1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
# ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
# ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
# ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
# ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
# ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
# ┃ Copyright (c) 2017, the Perspective Authors. ┃
# ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
# ┃ This file is part of the Perspective library, distributed under the terms ┃
# ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
# from .. import Server
# ─ │ ┌ ┬ ┐
# ┄ ┆ ├ ┼ ┤ ╲ ╱
# ┈ ┊ └ ┴ ┘
# ━ ┃ ┏ ┳ ┓ ┏ ┯ ┓ ┏ ┳ ┓ ┏ ┯ ┓
# ┅ ┇ ┣ ╋ ┫ ┣ ┿ ┫ ┠ ╂ ┨ ┠ ┼ ┨
# ┉ ┋ ┗ ┻ ┛ ┗ ┷ ┛ ┗ ┻ ┛ ┗ ┷ ┛
# global_server = PySyncServer()
"""PerspectiveViewer wraps the `perspective.Table` API and exposes an API
around creating views, loading data, and updating data.
"""
# Viewer attributes that should be saved in `save()` and restored using
# `restore()`. Symmetric to `PERSISTENT_ATTRIBUTES` in `perspective-viewer`.
=
"""Initialize an instance of `PerspectiveViewer` with the given viewer
configuration. Do not pass a `Table` or data into the constructor -
use the :func:`load()` method to provide the viewer with data.
Keyword Arguments:
columns (:obj:`list` of :obj:`str`): A list of column names to be
visible to the user.
group_by (:obj:`list` of :obj:`str`): A list of column names to
use as group by.
split_by (:obj:`list` of :obj:`str`): A list of column names
to use as split by.
aggregates (:obj:`dict` of :obj:`str` to :obj:`str`): A dictionary
of column names to aggregate types, which specify aggregates
for individual columns.
sort (:obj:`list` of :obj:`list` of :obj:`str`): A list of lists,
each list containing a column name and a sort direction
(``asc``, ``desc``, ``asc abs``, ``desc abs``, ``col asc``,
``col desc``, ``col asc abs``, ``col desc abs``).
filter (:obj:`list` of :obj:`list` of :obj:`str`): A list of lists,
each list containing a column name, a filter comparator, and a
value to filter by.
expressions (:obj:`list` of :obj:`str`): A list of string
expressions which are applied to the view.
plugin (:obj:`str`/:obj:`perspective.Plugin`): Which plugin to
select by default.
plugin_config (:obj:`dict`): A configuration for the plugin, i.e.
the datagrid plugin or a chart plugin.
settings(:obj:`bool`): Whether the perspective query settings
panel should be open.
theme (:obj:`str`): The color theme to use.
version (:obj:`str`): The version this configuration is restored from.
This should only be used when restoring a configuration,
and should not be set manually.
Examples:
>>> viewer = PerspectiveViewer(
... aggregates={"a": "avg"},
... group_by=["a"],
... sort=[["b", "desc"]],
... filter=[["a", ">", 1]],
... expressions=["\"a\" + 100"]
... )
"""
# The Table under management by this viewer and its
# attached PerspectiveManager
= None
= None
# Viewer configuration
= # validate_plugin(plugin)
= or # validate_columns(columns) or []
= or # validate_group_by(group_by) or []
= or # validate_split_by(split_by) or []
= or # validate_aggregates(aggregates) or {}
= or # validate_sort(sort) or []
= or # validate_filter(filter) or []
= or # validate_expressions(expressions) or {}
= # validate_plugin_config(plugin_config) or {}
=
=
=
return
"""Returns the ``perspective.Client`` or ``perspective.AsyncClient`` under management by the viewer."""
return
"""Returns the ``perspective.Table`` or ``perspective.AsyncTable`` under management by the viewer."""
return
"""Returns whether this widget has an async interface or synchronous"""
return
"""Given a ``perspective.Table``, a ``perspective.AsyncTable``,
or data that can be handled by ``perspective.Table``, pass it to the
viewer. Like `__init__`, load accepts a `perspective.Table`, a dataset,
or a schema.
``load()`` resets the state of the viewer: if a ``perspective.Table``
has already been loaded, ``**options`` is ignored as the options
already set on the ``Table`` take precedence.
If data is passed in, a ``perspective.Table`` is automatically created
by this method, and the options passed to ``**config`` are extended to
the new Table. If the widget already has a dataset, and the new data
has different columns to the old one, then the widget state (pivots,
sort, etc.) is cleared to prevent applying settings on columns that
don't exist.
When a ``perspective.AsyncTable`` is loaded, the widget's interface
becomes async. Methods which operate on the underlying Perspective
view, inclusive of the ``load()`` call itself, return coroutine values
which must be awaited.
Loading a ``perspective.Table`` or plain data will make the interface
synchronous again.
Args:
data (:obj:`Table`|:obj:`AsyncTable`|:obj:`dict`|:obj:`list`|:obj:`pandas.DataFrame`|:obj:`bytes`|:obj:`str`): a
`perspective.Table` instance, a `perspective.AsyncTable`
instance, or a dataset to be loaded in the viewer.
Keyword Arguments:
name (:obj:`str`): An optional name to reference the table by so it can
be accessed from the front-end. If not provided, a name will
be generated.
index (:obj:`str`): A column name to be used as the primary key.
Ignored if a ``Table`` or ``AsyncTable`` is supplied.
limit (:obj:`int`): A upper limit on the number of rows in the Table.
Cannot be set at the same time as `index`. Ignored if a
``Table`` or ``AsyncTable`` is supplied.
Returns:
coro (:obj:`coroutine`): when `AsyncTable` is passed, the `load()` call must be awaited
"""
=
# Reset the viewer when `load()` is called multiple times.
=
= await
=
# If the user does not set columns to show, synchronize viewer state
# with dataset.
= await
return
=
=
=
=
# If the user does not set columns to show, synchronize viewer state
# with dataset.
=
=
"""Update the table under management by the viewer with new data.
This function follows the semantics of `Table.update()`, and will be
affected by whether an index is set on the underlying table.
When this widget has loaded an ``AsyncTable``, returns a coroutine
which must be awaited.
Args:
data (:obj:`dict`|:obj:`list`|:obj:`pandas.DataFrame`): the
update data for the table.
Returns:
coro (:obj:`coroutine`): when async, must be awaited
"""
return
"""Clears the rows of this viewer's ``Table``."""
return
"""Replaces the rows of this viewer's `Table` with new data.
Args:
data (:obj:`dict`|:obj:`list`|:obj:`pandas.DataFrame`): new data
to set into the table - must conform to the table's schema.
Returns:
coro (:obj:`coroutine`): when async, must be awaited
"""
return
"""Get the viewer's attributes as a dictionary, symmetric with `restore`
so that a viewer's configuration can be reproduced."""
return
"""Restore a given set of attributes, passed as kwargs
(e.g. dictionary). Symmetric with `save` so that a given viewer's
configuration can be reproduced."""
"""Get the viewer's attributes as a list of kwargs, which can be passed to
the viewer constructor"""
=
=
=
=
return
"""Resets the viewer's attributes and state, but does not delete or
modify the underlying `Table`.
Example:
widget = PerspectiveWidget(data, group_by=["date"], plugin=Plugin.XBAR)
widget.reset()
widget.plugin #
"""
=
=
=
=
=
=
=
=
=
"""Delete the Viewer's data and clears its internal state. If
``delete_table`` is True, the underlying `perspective.Table` and the
internal `View` object will be deleted.
Args:
delete_table (:obj:`bool`) : whether the underlying `Table` will be
deleted. Defaults to True.
Returns:
coro (:obj:`coroutine`): when async and `delete_table` is `True`,
must be awaited
"""
= None
# Delete table
=
= None
= None
return