@windborne/grapher 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +85 -0
- package/.idea/codeStyles/Project.xml +19 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/grapher.iml +12 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/0.bundle.js +2 -0
- package/0.bundle.js.map +1 -0
- package/1767282193a714f63082.module.wasm +0 -0
- package/537.bundle.js +2 -0
- package/537.bundle.js.map +1 -0
- package/831.bundle.js +2 -0
- package/831.bundle.js.map +1 -0
- package/bundle.js +2 -0
- package/bundle.js.map +1 -0
- package/package.json +75 -0
- package/readme.md +129 -0
- package/src/components/annotations.js +62 -0
- package/src/components/context_menu.js +73 -0
- package/src/components/draggable_points.js +114 -0
- package/src/components/graph_body.js +292 -0
- package/src/components/graph_title.js +16 -0
- package/src/components/options.js +111 -0
- package/src/components/percentile_button.js +72 -0
- package/src/components/range_graph.js +352 -0
- package/src/components/range_selection.js +175 -0
- package/src/components/range_selection_button.js +26 -0
- package/src/components/range_selection_button_base.js +51 -0
- package/src/components/series_key.js +235 -0
- package/src/components/series_key_axis_container.js +70 -0
- package/src/components/series_key_item.js +52 -0
- package/src/components/sidebar.js +76 -0
- package/src/components/tooltip.js +244 -0
- package/src/components/vertical_lines.js +70 -0
- package/src/components/x_axis.js +124 -0
- package/src/components/y_axis.js +239 -0
- package/src/eventable.js +65 -0
- package/src/grapher.js +367 -0
- package/src/grapher.scss +914 -0
- package/src/helpers/axis_sizes.js +2 -0
- package/src/helpers/binary_search.js +67 -0
- package/src/helpers/color_to_vector.js +35 -0
- package/src/helpers/colors.js +27 -0
- package/src/helpers/custom_prop_types.js +159 -0
- package/src/helpers/flatten_simple_data.js +81 -0
- package/src/helpers/format.js +233 -0
- package/src/helpers/generator_params_equal.js +10 -0
- package/src/helpers/name_for_series.js +16 -0
- package/src/helpers/place_grid.js +257 -0
- package/src/helpers/pyodide_ready.js +13 -0
- package/src/multigrapher.js +105 -0
- package/src/renderer/background.frag +7 -0
- package/src/renderer/background.vert +7 -0
- package/src/renderer/background_program.js +48 -0
- package/src/renderer/circle.frag +26 -0
- package/src/renderer/circle.vert +12 -0
- package/src/renderer/create_gl_program.js +36 -0
- package/src/renderer/draw_area.js +159 -0
- package/src/renderer/draw_background.js +15 -0
- package/src/renderer/draw_bars.js +80 -0
- package/src/renderer/draw_line.js +69 -0
- package/src/renderer/draw_zero_line.js +24 -0
- package/src/renderer/extract_vertices.js +137 -0
- package/src/renderer/graph_body_renderer.js +293 -0
- package/src/renderer/line.frag +51 -0
- package/src/renderer/line.vert +32 -0
- package/src/renderer/line_program.js +125 -0
- package/src/renderer/paths_from.js +72 -0
- package/src/renderer/scale_bounds.js +28 -0
- package/src/renderer/size_canvas.js +59 -0
- package/src/rust/Cargo.lock +233 -0
- package/src/rust/Cargo.toml +35 -0
- package/src/rust/pkg/grapher_rs.d.ts +42 -0
- package/src/rust/pkg/grapher_rs.js +351 -0
- package/src/rust/pkg/grapher_rs_bg.d.ts +11 -0
- package/src/rust/pkg/grapher_rs_bg.wasm +0 -0
- package/src/rust/pkg/index.js +342 -0
- package/src/rust/pkg/index_bg.wasm +0 -0
- package/src/rust/pkg/package.json +14 -0
- package/src/rust/src/extract_vertices.rs +83 -0
- package/src/rust/src/get_point_number.rs +50 -0
- package/src/rust/src/lib.rs +15 -0
- package/src/rust/src/selected_space_to_render_space.rs +131 -0
- package/src/state/average_loop_times.js +15 -0
- package/src/state/bound_calculator_from_selection.js +36 -0
- package/src/state/bound_calculators.js +41 -0
- package/src/state/calculate_annotations_state.js +59 -0
- package/src/state/calculate_data_bounds.js +104 -0
- package/src/state/calculate_tooltip_state.js +241 -0
- package/src/state/data_types.js +13 -0
- package/src/state/expand_bounds.js +58 -0
- package/src/state/find_matching_axis.js +31 -0
- package/src/state/get_default_bounds_calculator.js +15 -0
- package/src/state/hooks.js +164 -0
- package/src/state/infer_type.js +74 -0
- package/src/state/merge_bounds.js +64 -0
- package/src/state/multigraph_state_controller.js +334 -0
- package/src/state/selection_from_global_bounds.js +25 -0
- package/src/state/space_conversions/condense_data_space.js +115 -0
- package/src/state/space_conversions/data_space_to_selected_space.js +328 -0
- package/src/state/space_conversions/selected_space_to_background_space.js +144 -0
- package/src/state/space_conversions/selected_space_to_render_space.js +161 -0
- package/src/state/space_conversions/simple_series_to_data_space.js +229 -0
- package/src/state/state_controller.js +1770 -0
- package/src/state/sync_pool.js +101 -0
- package/test/setup.js +15 -0
- package/test/space_conversions/data_space_to_selected_space.test.js +434 -0
- package/webpack.dev.config.js +109 -0
- package/webpack.prod.config.js +60 -0
- package/webpack.test.config.js +59 -0
@@ -0,0 +1,229 @@
|
|
1
|
+
import inferType from '../infer_type';
|
2
|
+
import { SIMPLE_DATA_TYPES } from '../data_types';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Given a series of a simple type (ie, not a function or an observable), converts it into data space
|
6
|
+
*
|
7
|
+
* @param {*} singleSeries
|
8
|
+
* @param {Object} options
|
9
|
+
* @return {*}
|
10
|
+
*/
|
11
|
+
export default function simpleSeriesToDataSpace(singleSeries, options={}) {
|
12
|
+
const type = inferType(singleSeries, { useSimpleData: true, data: options.data });
|
13
|
+
if (!SIMPLE_DATA_TYPES.includes(type)) {
|
14
|
+
throw new Error(`Cannot normalize ${type} (expected a simple type)`);
|
15
|
+
}
|
16
|
+
|
17
|
+
const inDataSpace = {
|
18
|
+
tuples: tuplesToDataSpace,
|
19
|
+
values: valuesToDataSpace,
|
20
|
+
objects: objectsToDataSpace
|
21
|
+
}[type](options.data || singleSeries.simpleData || singleSeries.data, singleSeries, options);
|
22
|
+
|
23
|
+
if (singleSeries.square) {
|
24
|
+
const square = [];
|
25
|
+
let prevY = options.prevY;
|
26
|
+
for (let tuple of inDataSpace) {
|
27
|
+
if (prevY !== undefined) {
|
28
|
+
square.push([tuple[0], prevY]);
|
29
|
+
}
|
30
|
+
square.push(tuple);
|
31
|
+
prevY = tuple[1];
|
32
|
+
}
|
33
|
+
|
34
|
+
return square;
|
35
|
+
}
|
36
|
+
|
37
|
+
if (singleSeries.shiftXBy) {
|
38
|
+
for (let tuple of inDataSpace) {
|
39
|
+
if (typeof tuple[0] === 'string') {
|
40
|
+
const originalXValue = tuple[0];
|
41
|
+
tuple[0] = new Date(new Date(tuple[0]).valueOf() + singleSeries.shiftXBy);
|
42
|
+
if (isNaN(tuple[0])) {
|
43
|
+
tuple[0] = options.stateController.enumToNumber(originalXValue, singleSeries);
|
44
|
+
}
|
45
|
+
} else if (tuple[0] instanceof Date) {
|
46
|
+
tuple[0] = new Date(tuple[0].valueOf() + singleSeries.shiftXBy);
|
47
|
+
} else if (typeof tuple[0] === 'number') {
|
48
|
+
tuple[0] += singleSeries.shiftXBy;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
if (singleSeries.xUnixDates) {
|
54
|
+
for (let tuple of inDataSpace) {
|
55
|
+
if (typeof tuple[0] === 'number') {
|
56
|
+
tuple[0] = new Date(tuple[0]*1000);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
return inDataSpace;
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Converts a values array to data space
|
66
|
+
*
|
67
|
+
* @param {Array<Number|String>} data
|
68
|
+
* @param {Object} singleSeries
|
69
|
+
* @param {Object} options
|
70
|
+
* @param {Number} [options.valueXStart]
|
71
|
+
* @param {StateController} options.stateController
|
72
|
+
* @return {Array<Array<Number|Date|null>>}
|
73
|
+
*/
|
74
|
+
function valuesToDataSpace(data, singleSeries, options) {
|
75
|
+
const inDataSpace = [];
|
76
|
+
|
77
|
+
for (let i = 0; i < data.length; i++) {
|
78
|
+
let yValue = data[i];
|
79
|
+
|
80
|
+
if (typeof yValue === 'string') {
|
81
|
+
yValue = options.stateController.enumToNumber(yValue, singleSeries);
|
82
|
+
}
|
83
|
+
|
84
|
+
if (typeof yValue === 'boolean') {
|
85
|
+
yValue = +yValue;
|
86
|
+
}
|
87
|
+
|
88
|
+
inDataSpace.push([i + (options.valueXStart || 0), yValue]);
|
89
|
+
}
|
90
|
+
|
91
|
+
return inDataSpace;
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Converts a tuples array to data space
|
96
|
+
*
|
97
|
+
* @param {Array<Array<Number|Date|null>>} data
|
98
|
+
* @param {Object} singleSeries
|
99
|
+
* @param {Object} options
|
100
|
+
* @param {StateController} options.stateController
|
101
|
+
* @return {Array<Array<Number|Date|null>>}
|
102
|
+
*/
|
103
|
+
function tuplesToDataSpace(data, singleSeries, options) {
|
104
|
+
return [...data.map(([ xValue, yValue]) => {
|
105
|
+
if (yValue === undefined) {
|
106
|
+
yValue = null;
|
107
|
+
}
|
108
|
+
|
109
|
+
if (typeof xValue === 'string') {
|
110
|
+
const originalXValue = xValue;
|
111
|
+
xValue = new Date(xValue);
|
112
|
+
|
113
|
+
if (isNaN(xValue)) {
|
114
|
+
xValue = options.stateController.enumToNumber(originalXValue, singleSeries, true);
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
if (typeof yValue === 'string') {
|
119
|
+
yValue = options.stateController.enumToNumber(yValue, singleSeries);
|
120
|
+
}
|
121
|
+
|
122
|
+
if (typeof yValue === 'boolean') {
|
123
|
+
yValue = +yValue;
|
124
|
+
}
|
125
|
+
|
126
|
+
return [xValue, yValue];
|
127
|
+
})];
|
128
|
+
}
|
129
|
+
|
130
|
+
function readBinaryFormatValue(view, offset, index) {
|
131
|
+
const localOffset = view.getUint32(offset + 2 + Uint32Array.BYTES_PER_ELEMENT*index, true);
|
132
|
+
|
133
|
+
if (localOffset === 0) {
|
134
|
+
return null;
|
135
|
+
}
|
136
|
+
|
137
|
+
const type = view.getUint8(localOffset);
|
138
|
+
|
139
|
+
if (type === 0) {
|
140
|
+
return view.getFloat64(offset + localOffset + 1, true);
|
141
|
+
} else if (type === 1 || type === 6) {
|
142
|
+
return null;
|
143
|
+
} else if (type === 3) {
|
144
|
+
return new Date(view.getFloat64(offset + localOffset + 1, true));
|
145
|
+
} else {
|
146
|
+
throw new Error(`Binary format type ${type} not supported`);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
/**
|
151
|
+
* Converts an objects array to data space
|
152
|
+
*
|
153
|
+
* @param {Array<Object>} data
|
154
|
+
* @param {Object} series
|
155
|
+
* @param {Object} options
|
156
|
+
* @param {StateController} options.stateController
|
157
|
+
* @return {Array<Array<Number|Date|null>>}
|
158
|
+
*/
|
159
|
+
function objectsToDataSpace(data, series, options) {
|
160
|
+
if (!series.xKey || typeof series.xKey !== 'string') {
|
161
|
+
throw new Error('xKey must be provided in the series');
|
162
|
+
}
|
163
|
+
|
164
|
+
if (!series.yKey || typeof series.yKey !== 'string') {
|
165
|
+
throw new Error('yKey must be provided in the series');
|
166
|
+
}
|
167
|
+
|
168
|
+
const inDataSpace = [];
|
169
|
+
|
170
|
+
for (let point of data) {
|
171
|
+
if (point.buffer instanceof ArrayBuffer) {
|
172
|
+
const view = new DataView(point.buffer);
|
173
|
+
const xIndex = point.channels[series.xKey];
|
174
|
+
const yIndex = point.channels[series.yKey];
|
175
|
+
|
176
|
+
for (let offset of point.offsets) {
|
177
|
+
inDataSpace.push([readBinaryFormatValue(view, offset, xIndex), readBinaryFormatValue(view, offset, yIndex)]);
|
178
|
+
}
|
179
|
+
} else if (Array.isArray(point[series.yKey])) {
|
180
|
+
if (point[series.yKey].length && !Array.isArray(point[series.yKey][0]) && typeof point[series.yKey][0] === 'object') {
|
181
|
+
for (let subpoint of point[series.yKey]) {
|
182
|
+
let yValue = subpoint[series.yKey];
|
183
|
+
if (yValue === undefined) {
|
184
|
+
yValue = null;
|
185
|
+
}
|
186
|
+
|
187
|
+
if (typeof yValue === 'string') {
|
188
|
+
yValue = options.stateController.enumToNumber(yValue, series);
|
189
|
+
}
|
190
|
+
|
191
|
+
if (typeof yValue === 'boolean') {
|
192
|
+
yValue = +yValue;
|
193
|
+
}
|
194
|
+
|
195
|
+
let xValue = subpoint[series.xKey];
|
196
|
+
if (typeof xValue === 'string') {
|
197
|
+
xValue = new Date(xValue);
|
198
|
+
}
|
199
|
+
|
200
|
+
inDataSpace.push([xValue, yValue]);
|
201
|
+
}
|
202
|
+
} else {
|
203
|
+
inDataSpace.push(...point[series.yKey]);
|
204
|
+
}
|
205
|
+
} else {
|
206
|
+
let yValue = point[series.yKey];
|
207
|
+
if (yValue === undefined) {
|
208
|
+
yValue = null;
|
209
|
+
}
|
210
|
+
|
211
|
+
let xValue = point[series.xKey];
|
212
|
+
if (typeof xValue === 'string') {
|
213
|
+
xValue = new Date(xValue);
|
214
|
+
}
|
215
|
+
|
216
|
+
if (typeof yValue === 'string') {
|
217
|
+
yValue = options.stateController.enumToNumber(yValue, series);
|
218
|
+
}
|
219
|
+
|
220
|
+
if (typeof yValue === 'boolean') {
|
221
|
+
yValue = +yValue;
|
222
|
+
}
|
223
|
+
|
224
|
+
inDataSpace.push([xValue, yValue]);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
return inDataSpace;
|
229
|
+
}
|