@@ -139,7 +139,7 @@ def __init__(self, content=None):
139
139
content = {}
140
140
141
141
if not content :
142
- self ['layout' ] = _empty_box ()
142
+ self ['layout' ] = None
143
143
self ['version' ] = 2
144
144
self ['settings' ] = {}
145
145
else :
@@ -160,7 +160,7 @@ def _compute_box_ids(self):
160
160
max_id = max (box_ids_to_path .keys ())
161
161
except ValueError :
162
162
max_id = 0
163
- box_ids_to_path [max_id + 1 ] = list ( node [1 ])
163
+ box_ids_to_path [max_id + 1 ] = node [1 ] # list(... )
164
164
165
165
return box_ids_to_path
166
166
@@ -183,14 +183,23 @@ def _insert(self, box_or_container, path):
183
183
else :
184
184
self ['layout' ] = box_or_container
185
185
186
- def _set_container_sizes (self ):
186
+ def _make_all_nodes_and_paths (self ):
187
187
all_nodes = list (node_generator (self ['layout' ]))
188
188
189
+ # remove path 'second' as it's always an empty box
189
190
all_paths = []
190
191
for node in all_nodes :
191
- all_paths .append (list (node [1 ]))
192
- if ['second' ] in all_paths :
193
- all_paths .remove (['second' ])
192
+ all_paths .append (node [1 ])
193
+ path_second = ('second' ,)
194
+ if path_second in all_paths :
195
+ all_paths .remove (path_second )
196
+ return all_nodes , all_paths
197
+
198
+ def _set_container_sizes (self ):
199
+ if self ['layout' ] is None :
200
+ return
201
+
202
+ all_nodes , all_paths = self ._make_all_nodes_and_paths ()
194
203
195
204
# set dashboard_height proportional to max_path_len
196
205
max_path_len = max (len (path ) for path in all_paths )
@@ -229,13 +238,20 @@ def get_preview(self):
229
238
dict. Otherwise, returns an IPython.core.display.HTML display of the
230
239
dashboard.
231
240
232
- The algorithm - iteratively go through all paths of the dashboards
233
- moving from shorter to longer paths. Checking the box or container
234
- that sits at the end each path, if you find a container, draw a line
235
- to divide the current box into two, and record the top-left
236
- coordinates and box width and height resulting from the two boxes
237
- along with the corresponding path. When the path points to a box,
238
- draw the number associated with that box in the center of the box.
241
+ The algorithm used to build the HTML preview involves going through
242
+ the paths of the node generator of the dashboard. The paths of the
243
+ dashboard are sequenced through from shorter to longer and whether
244
+ it's a box or container that lies at the end of the path determines
245
+ the action.
246
+
247
+ If it's a container, draw a line in the figure to divide the current
248
+ box into two and store the specs of the resulting two boxes. If the
249
+ path points to a terminal box (often containing a plot), then draw
250
+ the box id in the center of the box.
251
+
252
+ It's important to note that these box ids are generated on-the-fly and
253
+ they do not necessarily stay assigned to the boxes they were once
254
+ assigned to.
239
255
"""
240
256
if IPython is None :
241
257
pprint .pprint (self )
@@ -259,18 +275,12 @@ def get_preview(self):
259
275
path_to_box_specs [('first' ,)] = first_box_specs
260
276
261
277
# generate all paths
262
- all_nodes = list (node_generator (self ['layout' ]))
263
-
264
- all_paths = []
265
- for node in all_nodes :
266
- all_paths .append (list (node [1 ]))
267
- if ['second' ] in all_paths :
268
- all_paths .remove (['second' ])
278
+ all_nodes , all_paths = self ._make_all_nodes_and_paths ()
269
279
270
280
max_path_len = max (len (path ) for path in all_paths )
271
281
for path_len in range (1 , max_path_len + 1 ):
272
282
for path in [path for path in all_paths if len (path ) == path_len ]:
273
- current_box_specs = path_to_box_specs [tuple ( path ) ]
283
+ current_box_specs = path_to_box_specs [path ]
274
284
275
285
if self ._path_to_box (path )['type' ] == 'split' :
276
286
html_figure = _draw_line_through_box (
@@ -316,8 +326,8 @@ def get_preview(self):
316
326
'box_h' : new_box_h
317
327
}
318
328
319
- path_to_box_specs [tuple ( path ) + ('first' ,)] = box_1_specs
320
- path_to_box_specs [tuple ( path ) + ('second' ,)] = box_2_specs
329
+ path_to_box_specs [path + ('first' ,)] = box_1_specs
330
+ path_to_box_specs [path + ('second' ,)] = box_2_specs
321
331
322
332
elif self ._path_to_box (path )['type' ] == 'box' :
323
333
for box_id in box_ids_to_path :
@@ -326,10 +336,10 @@ def get_preview(self):
326
336
327
337
html_figure = _add_html_text (
328
338
html_figure , number ,
329
- path_to_box_specs [tuple ( path ) ]['top_left_x' ],
330
- path_to_box_specs [tuple ( path ) ]['top_left_y' ],
331
- path_to_box_specs [tuple ( path ) ]['box_w' ],
332
- path_to_box_specs [tuple ( path ) ]['box_h' ],
339
+ path_to_box_specs [path ]['top_left_x' ],
340
+ path_to_box_specs [path ]['top_left_y' ],
341
+ path_to_box_specs [path ]['box_w' ],
342
+ path_to_box_specs [path ]['box_h' ],
333
343
)
334
344
335
345
# display HTML representation
@@ -347,22 +357,10 @@ def insert(self, box, side='above', box_id=None):
347
357
the insertion of the box.
348
358
"""
349
359
box_ids_to_path = self ._compute_box_ids ()
350
- init_box = {
351
- 'type' : 'box' ,
352
- 'boxType' : 'plot' ,
353
- 'fileId' : '' ,
354
- 'shareKey' : None ,
355
- 'title' : ''
356
- }
357
-
358
- # force box to have all valid box keys
359
- for key in init_box .keys ():
360
- if key not in box .keys ():
361
- box [key ] = init_box [key ]
362
360
363
361
# doesn't need box_id or side specified for first box
364
- if 'first' not in self ['layout' ]:
365
- self . _insert ( _container (box , _empty_box ()), [] )
362
+ if self ['layout' ] is None :
363
+ self [ 'layout' ] = _container (box , _empty_box ())
366
364
else :
367
365
if box_id is None :
368
366
raise exceptions .PlotlyError (
0 commit comments