How to calculate sequoia view like boxes?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

How to calculate sequoia view like boxes?

Post by Michael Vogel »

SequoiaView was a tool to show the files in rectangles and their size are represented by different rectangle sizes. But how to get the dimensions for this boxes?

Let's say there are fifteen files (named 'document 1.txt' to 'document 15.txt') and the file sizes are equal (docnr+5)^2.

How should all boxes be displayed best in a certain rectangle area (e.g. 800 x 600) that all filenames could be placed inside the boxes?
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: How to calculate sequoia view like boxes?

Post by davido »

@Michael Vogel,

Might I suggest the following:
1. Sort all the files in descending order by size
2. Find the sum of all the file-sizes
3. Use the ratio of the largest file to the total size. Calculate the width of the first box from the 800px width of the box
4. Use this width to make a vertical rectangle on the left-hand side.
5. Repeat for the other 14 moving from left to right.

I must admit that I did look at their website before writing this?!

Another way would be to set the first rectangle as above but then alternate between vertical and horizontal boxes. This would seem more complicated, though.

Hope this helps.
DE AA EB
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: How to calculate sequoia view like boxes?

Post by Michael Vogel »

Thanks, did a first step now, but some things need to be optimized:
· the coordinates are not calculated precisely, so there are some gaps here and there
· the boxes should get a wider proportion to allow drawing longer texts inside

Code: Select all

; Define

	; Sequoia like Treemap
	; Michael Vogel - V1.0

	Enumeration
		#X
		#Y
	EndEnumeration

	Macro CreateArray(name,vals,globaldim=)
		globaldim# Dim name(CountString(vals,",")+1)
		For i=1 To CountString(vals,",")+1
			name(i-1)=Val(StringField(vals,i,","))
		Next
	EndMacro

	Macro SetXY(name,x,y)
		name(0)=x
		name(1)=y
	EndMacro
	
	
	CreateArray(mydata,"361,324,289,256,225,196,169,144,121,100,81,64,49,36,25",Global)

	EnableExplicit
	Global Dim dat(0)
	Global Dim out(#Y)
	Global Dim off(#Y)
	Global Dim rest.f(#Y)
	Global Dim temp.f(#Y)
	Global Dim color(#Y)

	SetXY(out,640,320)
	SetXY(off,150,80)
	SetXY(rest,out(#X),out(#Y))
	SetXY(color,$74DCB1,$F3D1AD)

	Global datcount
	Global area.f
	Global fact.f

; EndDefine
Procedure boxs(text.s,x,y,w,h,color)

	DrawingMode(#PB_2DDrawing_Default)
	Box(x+off(#X),y+off(#Y),w,h,color)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(x+off(#X),y+off(#Y),w,h,#Black)
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	DrawText(x+off(#X)+2,y+off(#Y)+2,text,$FF000000,#Null);

EndProcedure

Procedure calc(mode)

	Protected i,k,var,w,h
	Protected boxarea.f
	Protected Dim boxlen.f(datcount)
	Protected Dim boxprop.f(datcount)

	; Calculate areas for boxes...
	For i=0 To datcount
		boxarea=0
		For k=0 To i-1
			boxarea+dat(k)
		Next k

		; Calculate boxlen (width or height)
		boxlen(i)=boxarea*fact/rest(mode);

		; Calculate proportion
		For k=0 To i-1
			boxprop(i)+boxlen(i)/(dat(k)*fact/boxlen(i));
		Next k
		boxprop(i)=(Abs(1-boxprop(i)/(i+1)));
	Next i

	; Choose best variant...
	For i=0 To datcount
		If i>0 And boxprop(i)<boxprop(i-1)
			var=i;
		EndIf
	Next i

	; Draw column/row...
	SetXY(temp,0,0)
	i=0
	While i<var
		w=dat(i)*fact/boxlen(var)
		h=boxlen(var)
		If mode
			Swap w,h
		EndIf
		boxs("Box Size "+Str(dat(i)),out(#X)-rest(#X)-temp(#X),out(#Y)-rest(#Y)-temp(#Y),w,h,color(mode))
		temp(mode)-dat(i)*fact/boxlen(var)
		i+1
	Wend


	mode!1
	rest(mode)-boxlen(var);

	k=0
	For i=var To datcount
		dat(k)=dat(i)
		k+1
	Next i
	datcount-var


EndProcedure
Procedure treemap()

	Protected i,l

	For i=0 To ArraySize(dat())
		area+dat(i)
	Next i

	fact=out(#X)*out(#Y)/area;

	StartDrawing(CanvasOutput(0))
	Box(0,0,OutputWidth(),OutputHeight(),#White)
	While datcount
		l+1
		calc(l&1)
	Wend
	StopDrawing()

EndProcedure
Procedure restart()

	CopyArray(mydata(),dat())
	datcount=ArraySize(mydata())

	rest(#X)=out(#X);
	rest(#Y)=out(#Y);
	area=0
	fact=0

	treemap()

EndProcedure

OpenWindow(0,0,0,out(#X)+off(#X)<<1,out(#Y)+off(#Y)<<1,"")
CanvasGadget(0,0,0,out(#X)+off(#X)<<1,out(#Y)+off(#Y)<<1)

restart()

Repeat
	Select WaitWindowEvent()
	Case #PB_Event_CloseWindow
		End
	Case #WM_CHAR
		Select EventwParam()
		Case 'x','X','y','Y'
			Out(EventwParam()&1)+((GetKeyState_(#VK_SHIFT)&128)>>6-1)*10
			restart()
		Case #ESC
			End
		EndSelect
	EndSelect
ForEver
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: How to calculate sequoia view like boxes?

Post by Little John »

Hi,

maybe this Fast Optimizing Rectangle Packing Algorithm is interesting for you.
User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: How to calculate sequoia view like boxes?

Post by idle »

Little John wrote:Hi,

maybe this Fast Optimizing Rectangle Packing Algorithm is interesting for you.
I think there's one on the forum already from around ~2008
Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply