@@ -258,11 +258,12 @@ class VitessceConfigViewHConcat:
258258 A class to represent a horizontal concatenation of view instances.
259259 """
260260
261- def __init__ (self , views ):
261+ def __init__ (self , views , split = None ):
262262 """
263263 Not meant to be instantiated directly, but instead created and returned by the ``hconcat`` helper function.
264264 """
265265 self .views = views
266+ self .split = split
266267
267268 def __or__ (self , other ):
268269 return hconcat (self , other )
@@ -271,12 +272,14 @@ def __truediv__(self, other):
271272 return vconcat (self , other )
272273
273274
274- def hconcat (* views ):
275+ def hconcat (* views , split = None ):
275276 """
276277 A helper function to create a ``VitessceConfigViewHConcat`` instance.
277278
278279 :param \\ *views: A variable number of views to concatenate horizontally.
279280 :type \\ *views: VitessceConfigView or VitessceConfigViewVConcat or VitessceConfigViewHConcat
281+ :param split: Optional list of relative width fractions for each view.
282+ :type split: list of int
280283
281284 :returns: The concatenated view instance.
282285 :rtype: VitessceConfigViewHConcat
@@ -291,21 +294,24 @@ def hconcat(*views):
291294 v1 = vc.add_view(vt.SPATIAL, dataset=my_dataset)
292295 v2 = vc.add_view(vt.SPATIAL, dataset=my_dataset)
293296 v3 = vc.add_view(vt.SPATIAL, dataset=my_dataset)
294- vc.layout(hconcat(v1, vconcat(v2, v3)))
297+ vc.layout(hconcat(v1, vconcat(v2, v3), split = [1,2]))
298+ split = [1,2] would give v1 (1/3) width, and vconcat(v2, v3) 2/3 width
295299 """
296- return VitessceConfigViewHConcat (views )
300+
301+ return VitessceConfigViewHConcat (views , split = split )
297302
298303
299304class VitessceConfigViewVConcat :
300305 """
301306 A class to represent a vertical concatenation of view instances.
302307 """
303308
304- def __init__ (self , views ):
309+ def __init__ (self , views , split = None ):
305310 """
306311 Not meant to be instantiated directly, but instead created and returned by the ``vconcat`` helper function.
307312 """
308313 self .views = views
314+ self .split = split
309315
310316 def __or__ (self , other ):
311317 return hconcat (self , other )
@@ -314,12 +320,14 @@ def __truediv__(self, other):
314320 return vconcat (self , other )
315321
316322
317- def vconcat (* views ):
323+ def vconcat (* views , split = None ):
318324 """
319325 A helper function to create a ``VitessceConfigViewVConcat`` instance.
320326
321327 :param \\ *views: A variable number of views to concatenate vertically.
322328 :type \\ *views: VitessceConfigView or VitessceConfigViewVConcat or VitessceConfigViewHConcat
329+ :param split: Optional list of relative height fractions for each view.
330+ :type split: list of int
323331
324332 :returns: The concatenated view instance.
325333 :rtype: VitessceConfigViewVConcat
@@ -334,9 +342,10 @@ def vconcat(*views):
334342 v1 = vc.add_view(vt.SPATIAL, dataset=my_dataset)
335343 v2 = vc.add_view(vt.SPATIAL, dataset=my_dataset)
336344 v3 = vc.add_view(vt.SPATIAL, dataset=my_dataset)
337- vc.layout(hconcat(v1, vconcat(v2, v3)))
345+ vc.layout(hconcat(v1, vconcat(v2, v3, [1,2])))
346+ split = [1,2] would give v2 (1/3) height, and v3, 2/3 height
338347 """
339- return VitessceConfigViewVConcat (views )
348+ return VitessceConfigViewVConcat (views , split = split )
340349
341350
342351def _use_coordination_by_dict_helper (scopes , coordination_scopes , coordination_scopes_by ):
@@ -1450,28 +1459,25 @@ def _layout(obj, x_min, x_max, y_min, y_max):
14501459 h = y_max - y_min
14511460 if isinstance (obj , VitessceConfigView ):
14521461 obj .set_xywh (x_min , y_min , w , h )
1453- elif isinstance (obj , VitessceConfigViewHConcat ):
1454- views = obj .views
1455- num_views = len (views )
1456- for i in range (num_views ):
1457- _layout (
1458- views [i ],
1459- x_min + (w / num_views ) * i ,
1460- x_min + (w / num_views ) * (i + 1 ),
1461- y_min ,
1462- y_max
1463- )
1464- elif isinstance (obj , VitessceConfigViewVConcat ):
1462+ else :
14651463 views = obj .views
1466- num_views = len (views )
1467- for i in range (num_views ):
1468- _layout (
1469- views [i ],
1470- x_min ,
1471- x_max ,
1472- y_min + (h / num_views ) * i ,
1473- y_min + (h / num_views ) * (i + 1 ),
1474- )
1464+ # If the split parameter is provided, it must have the same length as the views.
1465+ assert obj .split is None or len (obj .split ) == len (views )
1466+ split = obj .split or [1 ] * len (views ) # Default to equal split if not provided
1467+ total = sum (split )
1468+
1469+ if isinstance (obj , VitessceConfigViewHConcat ):
1470+ widths = [int (s / total * w ) for s in split ]
1471+ x_pos = x_min
1472+ for view , width in zip (views , widths ):
1473+ _layout (view , x_pos , x_pos + width , y_min , y_max )
1474+ x_pos += width
1475+ if isinstance (obj , VitessceConfigViewVConcat ):
1476+ heights = [int (s / total * h ) for s in split ]
1477+ y_pos = y_min
1478+ for view , height in zip (views , heights ):
1479+ _layout (view , x_min , x_max , y_pos , y_pos + height )
1480+ y_pos += height
14751481
14761482 # Recursively set the values (x,y,w,h) for each view.
14771483 _layout (view_concat , 0 , 12 , 0 , 12 )
0 commit comments