@@ -118,29 +118,95 @@ class Grid(MutableSequence):
118118 py.plot([trace], filename='graph from grid')
119119 ```
120120 """
121- def __init__ (self , iterable_of_columns ):
121+ def __init__ (self , columns_or_json , fid = None ):
122122 """
123- Initialize a grid with an iterable of
124- `plotly.grid_objs.Column objects
123+ Initialize a grid with an iterable of `plotly.grid_objs.Column`
124+ objects or a json/dict describing a grid. See second usage example
125+ below for the necessary structure of the dict.
125126
126- Usage example:
127+ :param (str|bool) fid: should not be accessible to users. Default
128+ is 'None' but if a grid is retrieved via `py.get_grid()` then the
129+ retrieved grid response will contain the fid which will be
130+ necessary to set `self.id` and `self._columns.id` below.
131+
132+ Example from iterable of columns:
127133 ```
128134 column_1 = Column([1, 2, 3], 'time')
129135 column_2 = Column([4, 2, 5], 'voltage')
130136 grid = Grid([column_1, column_2])
131137 ```
138+ Example from json grid
139+ ```
140+ grid_json = {
141+ 'cols': {
142+ 'time': {'data': [1, 2, 3], 'order': 0, 'uid': '4cd7fc'},
143+ 'voltage': {'data': [4, 2, 5], 'order': 1, 'uid': u'2744be'}
144+ }
145+ }
146+ grid = Grid(grid_json)
147+ ```
132148 """
133-
134149 # TODO: verify that columns are actually columns
150+ if isinstance (columns_or_json , dict ):
151+ # check that fid is entered
152+ if fid is None :
153+ raise exceptions .PlotlyError (
154+ "If you are manually converting a raw json/dict grid "
155+ "into a Grid instance, you must ensure that 'fid' is "
156+ "set to your file ID. This looks like 'username:187'."
157+ )
158+
159+ self .id = fid
160+
161+ # check if 'cols' is a root key
162+ if 'cols' not in columns_or_json :
163+ raise exceptions .PlotlyError (
164+ "'cols' must be a root key in your json grid."
165+ )
166+
167+ # check if 'data', 'order' and 'uid' are not in columns
168+ grid_col_keys = ['data' , 'order' , 'uid' ]
169+
170+ for column_name in columns_or_json ['cols' ]:
171+ for key in grid_col_keys :
172+ if key not in columns_or_json ['cols' ][column_name ]:
173+ raise exceptions .PlotlyError (
174+ "Each column name of your dictionary must have "
175+ "'data', 'order' and 'uid' as keys."
176+ )
177+ # collect and sort all orders in case orders do not start
178+ # at zero or there are jump discontinuities between them
179+ all_orders = []
180+ for column_name in columns_or_json ['cols' ].keys ():
181+ all_orders .append (columns_or_json ['cols' ][column_name ]['order' ])
182+ all_orders .sort ()
183+
184+ # put columns in order in a list
185+ ordered_columns = []
186+ for order in all_orders :
187+ for column_name in columns_or_json ['cols' ].keys ():
188+ if columns_or_json ['cols' ][column_name ]['order' ] == order :
189+ break
190+
191+ ordered_columns .append (Column (
192+ columns_or_json ['cols' ][column_name ]['data' ],
193+ column_name )
194+ )
195+ self ._columns = ordered_columns
196+
197+ # fill in column_ids
198+ for column in self :
199+ column .id = self .id + ':' + columns_or_json ['cols' ][column .name ]['uid' ]
135200
136- column_names = [column .name for column in iterable_of_columns ]
137- duplicate_name = utils .get_first_duplicate (column_names )
138- if duplicate_name :
139- err = exceptions .NON_UNIQUE_COLUMN_MESSAGE .format (duplicate_name )
140- raise exceptions .InputError (err )
201+ else :
202+ column_names = [column .name for column in columns_or_json ]
203+ duplicate_name = utils .get_first_duplicate (column_names )
204+ if duplicate_name :
205+ err = exceptions .NON_UNIQUE_COLUMN_MESSAGE .format (duplicate_name )
206+ raise exceptions .InputError (err )
141207
142- self ._columns = list (iterable_of_columns )
143- self .id = ''
208+ self ._columns = list (columns_or_json )
209+ self .id = ''
144210
145211 def __repr__ (self ):
146212 return self ._columns .__repr__ ()
@@ -187,3 +253,26 @@ def get_column(self, column_name):
187253 for column in self ._columns :
188254 if column .name == column_name :
189255 return column
256+
257+ def get_column_reference (self , column_name ):
258+ """
259+ Returns the column reference of given column in the grid by its name.
260+
261+ Raises an error if the column name is not in the grid. Otherwise,
262+ returns the fid:uid pair, which may be the empty string.
263+ """
264+ column_id = None
265+ for column in self ._columns :
266+ if column .name == column_name :
267+ column_id = column .id
268+ break
269+
270+ if column_id is None :
271+ col_names = []
272+ for column in self ._columns :
273+ col_names .append (column .name )
274+ raise exceptions .PlotlyError (
275+ "Whoops, that column name doesn't match any of the column "
276+ "names in your grid. You must pick from {cols}" .format (cols = col_names )
277+ )
278+ return column_id
0 commit comments