@kanaries/graphic-walker 0.2.11 → 0.2.12

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.
Files changed (54) hide show
  1. package/dist/App.d.ts +6 -3
  2. package/dist/assets/explainer.worker-8428eb12.js.map +1 -1
  3. package/dist/components/button/base.d.ts +6 -0
  4. package/dist/components/button/default.d.ts +4 -0
  5. package/dist/components/button/primary.d.ts +4 -0
  6. package/dist/dataSource/utils.d.ts +1 -1
  7. package/dist/graphic-walker.es.js +17671 -18577
  8. package/dist/graphic-walker.es.js.map +1 -1
  9. package/dist/graphic-walker.umd.js +134 -134
  10. package/dist/graphic-walker.umd.js.map +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/interfaces.d.ts +8 -0
  13. package/dist/lib/inferMeta.d.ts +20 -0
  14. package/dist/store/commonStore.d.ts +1 -1
  15. package/dist/store/index.d.ts +0 -1
  16. package/dist/store/visualSpecStore.d.ts +5 -5
  17. package/dist/utils/dataPrep.d.ts +6 -0
  18. package/dist/utils/index.d.ts +2 -2
  19. package/dist/utils/normalization.d.ts +1 -1
  20. package/dist/utils/save.d.ts +3 -3
  21. package/dist/utils/throttle.d.ts +1 -1
  22. package/dist/vis/temporalFormat.d.ts +10 -0
  23. package/package.json +1 -1
  24. package/src/App.tsx +27 -10
  25. package/src/components/button/base.ts +7 -0
  26. package/src/components/button/default.tsx +17 -0
  27. package/src/components/button/primary.tsx +17 -0
  28. package/src/dataSource/dataSelection/csvData.tsx +8 -10
  29. package/src/dataSource/dataSelection/publicData.tsx +4 -4
  30. package/src/dataSource/index.tsx +10 -12
  31. package/src/dataSource/table.tsx +33 -20
  32. package/src/dataSource/utils.ts +30 -35
  33. package/src/fields/datasetFields/dimFields.tsx +1 -5
  34. package/src/fields/datasetFields/meaFields.tsx +1 -5
  35. package/src/fields/obComponents/obFContainer.tsx +1 -5
  36. package/src/index.tsx +3 -4
  37. package/src/interfaces.ts +9 -0
  38. package/src/lib/inferMeta.ts +88 -0
  39. package/src/locales/en-US.json +6 -0
  40. package/src/locales/zh-CN.json +6 -0
  41. package/src/main.tsx +1 -1
  42. package/src/store/commonStore.ts +8 -3
  43. package/src/store/index.tsx +0 -2
  44. package/src/store/visualSpecStore.ts +245 -183
  45. package/src/utils/autoMark.ts +14 -14
  46. package/src/utils/dataPrep.ts +44 -0
  47. package/src/utils/index.ts +140 -128
  48. package/src/utils/normalization.ts +59 -51
  49. package/src/utils/save.ts +22 -21
  50. package/src/utils/throttle.ts +5 -1
  51. package/src/vis/react-vega.tsx +6 -10
  52. package/src/vis/temporalFormat.ts +66 -0
  53. package/dist/pitch/dnd-offset.d.ts +0 -2
  54. package/src/pitch/dnd-offset.ts +0 -64
@@ -1,6 +1,6 @@
1
1
  import { IReactionDisposer, makeAutoObservable, observable, reaction, toJS } from "mobx";
2
- import produce from 'immer';
3
- import { v4 as uuidv4 } from 'uuid';
2
+ import produce from "immer";
3
+ import { v4 as uuidv4 } from "uuid";
4
4
  import { Specification } from "visual-insights";
5
5
  import { DataSet, DraggableFieldState, IFilterRule, IViewField, IVisSpec, IVisualConfig } from "../interfaces";
6
6
  import { CHANNEL_LIMIT, GEMO_TYPES, MetaFieldKeys } from "../config";
@@ -9,34 +9,34 @@ import { VisSpecWithHistory } from "../models/visSpecHistory";
9
9
  import { dumpsGWPureSpec, parseGWContent, parseGWPureSpec, stringifyGWContent } from "../utils/save";
10
10
  import { CommonStore } from "./commonStore";
11
11
 
12
- function getChannelSizeLimit (channel: string): number {
13
- if (typeof CHANNEL_LIMIT[channel] === 'undefined') return Infinity;
12
+ function getChannelSizeLimit(channel: string): number {
13
+ if (typeof CHANNEL_LIMIT[channel] === "undefined") return Infinity;
14
14
  return CHANNEL_LIMIT[channel];
15
15
  }
16
16
 
17
- function geomAdapter (geom: string) {
17
+ function geomAdapter(geom: string) {
18
18
  switch (geom) {
19
- case 'interval':
20
- return 'bar';
21
- case 'line':
22
- return 'line';
23
- case 'boxplot':
24
- return 'boxplot';
25
- case 'area':
26
- return 'area';
27
- case 'point':
28
- return 'point';
29
- case 'arc':
30
- return 'arc';
31
- case 'circle':
32
- return 'circle';
33
- case 'heatmap':
34
- return 'circle'
35
- case 'rect':
36
- return 'rect'
37
- case 'tick':
19
+ case "interval":
20
+ return "bar";
21
+ case "line":
22
+ return "line";
23
+ case "boxplot":
24
+ return "boxplot";
25
+ case "area":
26
+ return "area";
27
+ case "point":
28
+ return "point";
29
+ case "arc":
30
+ return "arc";
31
+ case "circle":
32
+ return "circle";
33
+ case "heatmap":
34
+ return "circle";
35
+ case "rect":
36
+ return "rect";
37
+ case "tick":
38
38
  default:
39
- return 'tick'
39
+ return "tick";
40
40
  }
41
41
  }
42
42
 
@@ -57,32 +57,32 @@ function initEncoding(): DraggableFieldState {
57
57
  };
58
58
  }
59
59
 
60
- function initVisualConfig (): IVisualConfig {
60
+ function initVisualConfig(): IVisualConfig {
61
61
  return {
62
62
  defaultAggregated: true,
63
63
  geoms: [GEMO_TYPES[0]!],
64
- stack: 'stack',
64
+ stack: "stack",
65
65
  showActions: false,
66
66
  interactiveScale: false,
67
- sorted: 'none',
67
+ sorted: "none",
68
68
  size: {
69
- mode: 'auto',
69
+ mode: "auto",
70
70
  width: 320,
71
- height: 200
71
+ height: 200,
72
72
  },
73
73
  exploration: {
74
- mode: 'none',
75
- brushDirection: 'default',
74
+ mode: "none",
75
+ brushDirection: "default",
76
76
  },
77
- }
77
+ };
78
78
  }
79
79
 
80
80
  type DeepReadonly<T extends Record<keyof any, any>> = {
81
81
  readonly [K in keyof T]: T[K] extends Record<keyof any, any> ? DeepReadonly<T[K]> : T[K];
82
82
  };
83
83
 
84
- const forwardVisualConfigs = (backwards: ReturnType<typeof parseGWContent>['specList']): IVisSpec[] => {
85
- return backwards.map(content => ({
84
+ const forwardVisualConfigs = (backwards: ReturnType<typeof parseGWContent>["specList"]): IVisSpec[] => {
85
+ return backwards.map((content) => ({
86
86
  ...content,
87
87
  config: {
88
88
  ...initVisualConfig(),
@@ -91,7 +91,6 @@ const forwardVisualConfigs = (backwards: ReturnType<typeof parseGWContent>['spec
91
91
  }));
92
92
  };
93
93
 
94
-
95
94
  export class VizSpecStore {
96
95
  // public fields: IViewField[] = [];
97
96
  private commonStore: CommonStore;
@@ -105,13 +104,13 @@ export class VizSpecStore {
105
104
  * Assignment or mutable operations applied to ANY members of this segment
106
105
  * is strictly FORBIDDEN.
107
106
  * Members of it can only be got as READONLY objects.
108
- *
107
+ *
109
108
  * If you're trying to change the value of it and let mobx catch the action to trigger an update,
110
109
  * please use `this.useMutable()` to access to a writable reference
111
110
  * (an `immer` draft) of `this.visList[this.visIndex]`.
112
111
  */
113
112
  public readonly draggableFieldState: DeepReadonly<DraggableFieldState>;
114
- private reactions: IReactionDisposer[] = []
113
+ private reactions: IReactionDisposer[] = [];
115
114
  /**
116
115
  * This segment will always refers to the state of the active tab -
117
116
  * `this.visList[this.visIndex].config`.
@@ -122,7 +121,7 @@ export class VizSpecStore {
122
121
  * Assignment or mutable operations applied to ANY members of this segment
123
122
  * is strictly FORBIDDEN.
124
123
  * Members of it can only be got as READONLY objects.
125
- *
124
+ *
126
125
  * If you're trying to change the value of it and let mobx catch the action to trigger an update,
127
126
  * please use `this.useMutable()` to access to a writable reference
128
127
  * (an `immer` draft) of `this.visList[this.visIndex]`.
@@ -133,34 +132,42 @@ export class VizSpecStore {
133
132
  public canUndo = false;
134
133
  public canRedo = false;
135
134
  public editingFilterIdx: number | null = null;
136
- constructor (commonStore: CommonStore) {
135
+ constructor(commonStore: CommonStore) {
137
136
  this.commonStore = commonStore;
138
137
  this.draggableFieldState = initEncoding();
139
138
  this.visualConfig = initVisualConfig();
140
- this.visList.push(new VisSpecWithHistory({
141
- name: ['main.tablist.autoTitle', { idx: 1 }],
142
- visId: uuidv4(),
143
- config: this.visualConfig,
144
- encodings: this.draggableFieldState,
145
- }));
139
+ this.visList.push(
140
+ new VisSpecWithHistory({
141
+ name: ["main.tablist.autoTitle", { idx: 1 }],
142
+ visId: uuidv4(),
143
+ config: this.visualConfig,
144
+ encodings: this.draggableFieldState,
145
+ })
146
+ );
146
147
  makeAutoObservable(this, {
147
148
  visList: observable.shallow,
148
149
  // @ts-expect-error private fields are not supported
149
- reactions: false
150
+ reactions: false,
150
151
  });
151
152
  this.reactions.push(
152
- reaction(() => commonStore.currentDataset, (dataset) => {
153
- // this.initState();
154
- this.initMetaState(dataset);
155
- }),
156
- reaction(() => this.visList[this.visIndex], frame => {
157
- // @ts-ignore Allow assignment here to trigger watch
158
- this.draggableFieldState = frame.encodings;
159
- // @ts-ignore Allow assignment here to trigger watch
160
- this.visualConfig = frame.config;
161
- this.canUndo = frame.canUndo;
162
- this.canRedo = frame.canRedo;
163
- }),
153
+ reaction(
154
+ () => commonStore.currentDataset,
155
+ (dataset) => {
156
+ // this.initState();
157
+ this.initMetaState(dataset);
158
+ }
159
+ ),
160
+ reaction(
161
+ () => this.visList[this.visIndex],
162
+ (frame) => {
163
+ // @ts-ignore Allow assignment here to trigger watch
164
+ this.draggableFieldState = frame.encodings;
165
+ // @ts-ignore Allow assignment here to trigger watch
166
+ this.visualConfig = frame.config;
167
+ this.canUndo = frame.canUndo;
168
+ this.canRedo = frame.canRedo;
169
+ }
170
+ )
164
171
  );
165
172
  }
166
173
  private __dangerous_is_inside_useMutable__ = false;
@@ -169,38 +176,38 @@ export class VizSpecStore {
169
176
  * because the state will be overwritten by the root `useMutable()` call,
170
177
  * update caused by recursive `useMutable()` call will be reverted or lead to unexpected behaviors.
171
178
  * Inline your invoking or just use block with IF statement to avoid this in your cases.
172
- *
179
+ *
173
180
  * Allow to change any deep member of `encodings` or `config`
174
181
  * in the active tab `this.visList[this.visIndex]`.
175
- *
182
+ *
176
183
  * - `tab.encodings`
177
- *
184
+ *
178
185
  * A mutable reference of `this.draggableFieldState`
179
- *
186
+ *
180
187
  * - `tab.config`
181
- *
188
+ *
182
189
  * A mutable reference of `this.visualConfig`
183
190
  */
184
- private useMutable(
185
- cb: (tab: {
186
- encodings: DraggableFieldState;
187
- config: IVisualConfig;
188
- }) => void,
189
- ) {
191
+ private useMutable(cb: (tab: { encodings: DraggableFieldState; config: IVisualConfig }) => void) {
190
192
  if (this.__dangerous_is_inside_useMutable__) {
191
193
  throw new Error(
192
- 'A recursive call of useMutable() is detected, '
193
- + 'this is prevented because update will be overwritten by parent execution context.'
194
+ "A recursive call of useMutable() is detected, " +
195
+ "this is prevented because update will be overwritten by parent execution context."
194
196
  );
195
197
  }
196
198
 
197
199
  this.__dangerous_is_inside_useMutable__ = true;
198
200
 
199
- const { encodings, config } = produce({
200
- encodings: this.visList[this.visIndex].encodings,
201
- config: this.visList[this.visIndex].config,
202
- }, draft => { cb(draft) }); // notice that cb() may unexpectedly returns a non-nullable value
203
-
201
+ const { encodings, config } = produce(
202
+ {
203
+ encodings: this.visList[this.visIndex].encodings,
204
+ config: this.visList[this.visIndex].config,
205
+ },
206
+ (draft) => {
207
+ cb(draft);
208
+ }
209
+ ); // notice that cb() may unexpectedly returns a non-nullable value
210
+
204
211
  this.visList[this.visIndex].encodings = encodings;
205
212
  this.visList[this.visIndex].config = config;
206
213
 
@@ -242,96 +249,98 @@ export class VizSpecStore {
242
249
  /**
243
250
  * dimension fields in visualization
244
251
  */
245
- public get viewDimensions (): IViewField[] {
252
+ public get viewDimensions(): IViewField[] {
246
253
  const { draggableFieldState } = this;
247
254
  const state = toJS(draggableFieldState);
248
255
  const fields: IViewField[] = [];
249
256
  (Object.keys(state) as (keyof DraggableFieldState)[])
250
- .filter(dkey => !MetaFieldKeys.includes(dkey))
251
- .forEach(dkey => {
252
- fields.push(...state[dkey].filter(f => f.analyticType === 'dimension'))
253
- })
257
+ .filter((dkey) => !MetaFieldKeys.includes(dkey))
258
+ .forEach((dkey) => {
259
+ fields.push(...state[dkey].filter((f) => f.analyticType === "dimension"));
260
+ });
254
261
  return fields;
255
262
  }
256
263
  /**
257
264
  * dimension fields in visualization
258
265
  */
259
- public get viewMeasures (): IViewField[] {
266
+ public get viewMeasures(): IViewField[] {
260
267
  const { draggableFieldState } = this;
261
268
  const state = toJS(draggableFieldState);
262
269
  const fields: IViewField[] = [];
263
270
  (Object.keys(state) as (keyof DraggableFieldState)[])
264
- .filter(dkey => !MetaFieldKeys.includes(dkey))
265
- .forEach(dkey => {
266
- fields.push(...state[dkey].filter(f => f.analyticType === 'measure'))
267
- })
271
+ .filter((dkey) => !MetaFieldKeys.includes(dkey))
272
+ .forEach((dkey) => {
273
+ fields.push(...state[dkey].filter((f) => f.analyticType === "measure"));
274
+ });
268
275
  return fields;
269
276
  }
270
- public addVisualization () {
271
- this.visList.push(new VisSpecWithHistory({
272
- name: ['main.tablist.autoTitle', { idx: this.visList.length + 1 }],
273
- visId: uuidv4(),
274
- config: initVisualConfig(),
275
- encodings: initEncoding()
276
- }));
277
+ public addVisualization() {
278
+ this.visList.push(
279
+ new VisSpecWithHistory({
280
+ name: ["main.tablist.autoTitle", { idx: this.visList.length + 1 }],
281
+ visId: uuidv4(),
282
+ config: initVisualConfig(),
283
+ encodings: initEncoding(),
284
+ })
285
+ );
277
286
  this.visIndex = this.visList.length - 1;
278
287
  }
279
- public selectVisualization (visIndex: number) {
288
+ public selectVisualization(visIndex: number) {
280
289
  this.visIndex = visIndex;
281
290
  }
282
- public setVisName (visIndex: number, name: string) {
291
+ public setVisName(visIndex: number, name: string) {
283
292
  this.useMutable(() => {
284
293
  this.visList[visIndex].name = [name];
285
294
  });
286
295
  }
287
- public initState () {
288
- this.useMutable(tab => {
296
+ public initState() {
297
+ this.useMutable((tab) => {
289
298
  tab.encodings = initEncoding();
290
299
  this.freezeHistory();
291
300
  });
292
301
  }
293
- public initMetaState (dataset: DataSet) {
302
+ public initMetaState(dataset: DataSet) {
294
303
  this.useMutable(({ encodings }) => {
295
304
  encodings.fields = dataset.rawFields.map((f) => ({
296
305
  dragId: uuidv4(),
297
306
  fid: f.fid,
298
307
  name: f.name || f.fid,
299
- aggName: f.analyticType === 'measure' ? 'sum' : undefined,
308
+ aggName: f.analyticType === "measure" ? "sum" : undefined,
300
309
  analyticType: f.analyticType,
301
- semanticType: f.semanticType
310
+ semanticType: f.semanticType,
302
311
  }));
303
312
  encodings.dimensions = dataset.rawFields
304
- .filter(f => f.analyticType === 'dimension')
313
+ .filter((f) => f.analyticType === "dimension")
305
314
  .map((f) => ({
306
315
  dragId: uuidv4(),
307
316
  fid: f.fid,
308
317
  name: f.name || f.fid,
309
318
  semanticType: f.semanticType,
310
319
  analyticType: f.analyticType,
311
- }));
320
+ }));
312
321
  encodings.measures = dataset.rawFields
313
- .filter(f => f.analyticType === 'measure')
322
+ .filter((f) => f.analyticType === "measure")
314
323
  .map((f) => ({
315
324
  dragId: uuidv4(),
316
325
  fid: f.fid,
317
326
  name: f.name || f.fid,
318
327
  analyticType: f.analyticType,
319
328
  semanticType: f.semanticType,
320
- aggName: 'sum'
321
- }));
329
+ aggName: "sum",
330
+ }));
322
331
  });
323
332
 
324
333
  this.freezeHistory();
325
334
  // this.draggableFieldState.measures.push({
326
- // dragId: uuidv4(),
327
- // fid: COUNT_FIELD_ID,
328
- // name: '记录数',
329
- // analyticType: 'measure',
330
- // semanticType: 'quantitative',
331
- // aggName: 'count'
332
- // })
333
- }
334
- public clearState () {
335
+ // dragId: uuidv4(),
336
+ // fid: COUNT_FIELD_ID,
337
+ // name: '记录数',
338
+ // analyticType: 'measure',
339
+ // semanticType: 'quantitative',
340
+ // aggName: 'count'
341
+ // })
342
+ }
343
+ public clearState() {
335
344
  this.useMutable(({ encodings }) => {
336
345
  for (let key in encodings) {
337
346
  if (!MetaFieldKeys.includes(key as keyof DraggableFieldState)) {
@@ -343,41 +352,35 @@ export class VizSpecStore {
343
352
  public setVisualConfig<K extends keyof IVisualConfig>(configKey: K, value: IVisualConfig[K]) {
344
353
  this.useMutable(({ config }) => {
345
354
  switch (true) {
346
- case ['defaultAggregated', 'defaultStack', 'showActions', 'interactiveScale'].includes(configKey): {
347
- return (config as unknown as {[k: string]: boolean})[configKey] = Boolean(value);
355
+ case ["defaultAggregated", "defaultStack", "showActions", "interactiveScale"].includes(configKey): {
356
+ return ((config as unknown as { [k: string]: boolean })[configKey] = Boolean(value));
348
357
  }
349
- case configKey === 'geoms' && Array.isArray(value):
350
- case configKey === 'size' && typeof value === 'object':
351
- case configKey === 'sorted':
352
- case configKey === 'stack':
353
- {
354
- return config[configKey] = value;
358
+ case configKey === "geoms" && Array.isArray(value):
359
+ case configKey === "size" && typeof value === "object":
360
+ case configKey === "sorted":
361
+ case configKey === "stack": {
362
+ return (config[configKey] = value);
355
363
  }
356
364
  default: {
357
- console.error('unknown key' + configKey);
365
+ console.error("unknown key" + configKey);
358
366
  }
359
367
  }
360
368
  });
361
369
  }
362
- public transformCoord (coord: 'cartesian' | 'polar') {
363
- if (coord === 'polar') {
364
-
370
+ public transformCoord(coord: "cartesian" | "polar") {
371
+ if (coord === "polar") {
365
372
  }
366
373
  }
367
- public setChartLayout(props: {mode: IVisualConfig['size']['mode'], width?: number, height?: number }) {
374
+ public setChartLayout(props: { mode: IVisualConfig["size"]["mode"]; width?: number; height?: number }) {
368
375
  this.useMutable(({ config }) => {
369
- const {
370
- mode = config.size.mode,
371
- width = config.size.width,
372
- height = config.size.height
373
- } = props;
376
+ const { mode = config.size.mode, width = config.size.width, height = config.size.height } = props;
374
377
 
375
378
  config.size.mode = mode;
376
379
  config.size.width = width;
377
380
  config.size.height = height;
378
381
  });
379
382
  }
380
- public setExploration(value: Partial<IVisualConfig['exploration']>) {
383
+ public setExploration(value: Partial<IVisualConfig["exploration"]>) {
381
384
  this.useMutable(({ config }) => {
382
385
  if (value.mode) {
383
386
  config.exploration.mode = value.mode;
@@ -397,13 +400,18 @@ export class VizSpecStore {
397
400
  fields.splice(destinationIndex, 0, field);
398
401
  });
399
402
  }
400
- public moveField(sourceKey: keyof DraggableFieldState, sourceIndex: number, destinationKey: keyof DraggableFieldState, destinationIndex: number) {
401
- if (sourceKey === 'filters') {
403
+ public moveField(
404
+ sourceKey: keyof DraggableFieldState,
405
+ sourceIndex: number,
406
+ destinationKey: keyof DraggableFieldState,
407
+ destinationIndex: number
408
+ ) {
409
+ if (sourceKey === "filters") {
402
410
  return this.removeField(sourceKey, sourceIndex);
403
- } else if (destinationKey === 'filters') {
404
- return this.appendFilter(destinationIndex, this.draggableFieldState[sourceKey][sourceIndex])
411
+ } else if (destinationKey === "filters") {
412
+ return this.appendFilter(destinationIndex, this.draggableFieldState[sourceKey][sourceIndex]);
405
413
  }
406
-
414
+
407
415
  this.useMutable(({ encodings }) => {
408
416
  let movingField: IViewField;
409
417
  // 来源是不是metafield,是->clone;不是->直接删掉
@@ -418,9 +426,9 @@ export class VizSpecStore {
418
426
  }
419
427
  // 目的地是metafields的情况,只有在来源也是metafields时,会执行字段类型转化操作
420
428
  if (MetaFieldKeys.includes(destinationKey)) {
421
- if (!MetaFieldKeys.includes(sourceKey))return;
429
+ if (!MetaFieldKeys.includes(sourceKey)) return;
422
430
  encodings[sourceKey].splice(sourceIndex, 1);
423
- movingField.analyticType = destinationKey === 'dimensions' ? 'dimension' : 'measure';
431
+ movingField.analyticType = destinationKey === "dimensions" ? "dimension" : "measure";
424
432
  }
425
433
  const limitSize = getChannelSizeLimit(destinationKey);
426
434
  const fixedDestinationIndex = Math.min(destinationIndex, limitSize - 1);
@@ -429,7 +437,7 @@ export class VizSpecStore {
429
437
  });
430
438
  }
431
439
  public removeField(sourceKey: keyof DraggableFieldState, sourceIndex: number) {
432
- if (MetaFieldKeys.includes(sourceKey))return;
440
+ if (MetaFieldKeys.includes(sourceKey)) return;
433
441
 
434
442
  this.useMutable(({ encodings }) => {
435
443
  const fields = encodings[sourceKey];
@@ -462,25 +470,29 @@ export class VizSpecStore {
462
470
  const fieldsInCup = encodings.columns;
463
471
 
464
472
  encodings.columns = encodings.rows;
465
- encodings.rows = fieldsInCup as typeof encodings.rows; // assume this as writable
473
+ encodings.rows = fieldsInCup as typeof encodings.rows; // assume this as writable
466
474
  });
467
475
  }
468
476
  public createBinField(stateKey: keyof DraggableFieldState, index: number) {
469
477
  this.useMutable(({ encodings }) => {
470
- const originField = encodings[stateKey][index]
478
+ const originField = encodings[stateKey][index];
471
479
  const binField: IViewField = {
472
480
  fid: uuidv4(),
473
481
  dragId: uuidv4(),
474
482
  name: `bin(${originField.name})`,
475
- semanticType: 'ordinal',
476
- analyticType: 'dimension',
483
+ semanticType: "ordinal",
484
+ analyticType: "dimension",
477
485
  };
478
486
  encodings.dimensions.push(binField);
479
- this.commonStore.currentDataset.dataSource = makeBinField(this.commonStore.currentDataset.dataSource, originField.fid, binField.fid)
487
+ this.commonStore.currentDataset.dataSource = makeBinField(
488
+ this.commonStore.currentDataset.dataSource,
489
+ originField.fid,
490
+ binField.fid
491
+ );
480
492
  });
481
493
  }
482
494
  public createLogField(stateKey: keyof DraggableFieldState, index: number) {
483
- if (stateKey === 'filters') {
495
+ if (stateKey === "filters") {
484
496
  return;
485
497
  }
486
498
 
@@ -490,14 +502,18 @@ export class VizSpecStore {
490
502
  fid: uuidv4(),
491
503
  dragId: uuidv4(),
492
504
  name: `log10(${originField.name})`,
493
- semanticType: 'quantitative',
494
- analyticType: originField.analyticType
505
+ semanticType: "quantitative",
506
+ analyticType: originField.analyticType,
495
507
  };
496
508
  encodings[stateKey].push(logField);
497
- this.commonStore.currentDataset.dataSource = makeLogField(this.commonStore.currentDataset.dataSource, originField.fid, logField.fid)
509
+ this.commonStore.currentDataset.dataSource = makeLogField(
510
+ this.commonStore.currentDataset.dataSource,
511
+ originField.fid,
512
+ logField.fid
513
+ );
498
514
  });
499
515
  }
500
- public setFieldAggregator (stateKey: keyof DraggableFieldState, index: number, aggName: string) {
516
+ public setFieldAggregator(stateKey: keyof DraggableFieldState, index: number, aggName: string) {
501
517
  this.useMutable(({ encodings }) => {
502
518
  const fields = encodings[stateKey];
503
519
 
@@ -506,54 +522,77 @@ export class VizSpecStore {
506
522
  }
507
523
  });
508
524
  }
509
- public get sortCondition () {
525
+ public get sortCondition() {
510
526
  const { rows, columns } = this.draggableFieldState;
511
527
  const yField = rows.length > 0 ? rows[rows.length - 1] : null;
512
528
  const xField = columns.length > 0 ? columns[columns.length - 1] : null;
513
- if (xField !== null && xField.analyticType === 'dimension' && yField !== null && yField.analyticType === 'measure') {
514
- return true
529
+ if (
530
+ xField !== null &&
531
+ xField.analyticType === "dimension" &&
532
+ yField !== null &&
533
+ yField.analyticType === "measure"
534
+ ) {
535
+ return true;
515
536
  }
516
- if (xField !== null && xField.analyticType === 'measure' && yField !== null && yField.analyticType === 'dimension') {
517
- return true
537
+ if (
538
+ xField !== null &&
539
+ xField.analyticType === "measure" &&
540
+ yField !== null &&
541
+ yField.analyticType === "dimension"
542
+ ) {
543
+ return true;
518
544
  }
519
545
  return false;
520
546
  }
521
- public setFieldSort (stateKey: keyof DraggableFieldState, index: number, sortType: 'none' | 'ascending' | 'descending') {
547
+ public setFieldSort(
548
+ stateKey: keyof DraggableFieldState,
549
+ index: number,
550
+ sortType: "none" | "ascending" | "descending"
551
+ ) {
522
552
  this.useMutable(({ encodings }) => {
523
553
  encodings[stateKey][index].sort = sortType;
524
554
  });
525
555
  }
526
- public applyDefaultSort(sortType: 'none' | 'ascending' | 'descending' = 'ascending') {
556
+ public applyDefaultSort(sortType: "none" | "ascending" | "descending" = "ascending") {
527
557
  this.useMutable(({ encodings }) => {
528
558
  const { rows, columns } = encodings;
529
559
  const yField = rows.length > 0 ? rows[rows.length - 1] : null;
530
560
  const xField = columns.length > 0 ? columns[columns.length - 1] : null;
531
-
532
- if (xField !== null && xField.analyticType === 'dimension' && yField !== null && yField.analyticType === 'measure') {
561
+
562
+ if (
563
+ xField !== null &&
564
+ xField.analyticType === "dimension" &&
565
+ yField !== null &&
566
+ yField.analyticType === "measure"
567
+ ) {
533
568
  encodings.columns[columns.length - 1].sort = sortType;
534
569
  return;
535
570
  }
536
- if (xField !== null && xField.analyticType === 'measure' && yField !== null && yField.analyticType === 'dimension') {
571
+ if (
572
+ xField !== null &&
573
+ xField.analyticType === "measure" &&
574
+ yField !== null &&
575
+ yField.analyticType === "dimension"
576
+ ) {
537
577
  encodings.rows[rows.length - 1].sort = sortType;
538
578
  return;
539
579
  }
540
580
  });
541
581
  }
542
- public appendField (destinationKey: keyof DraggableFieldState, field: IViewField | undefined) {
582
+ public appendField(destinationKey: keyof DraggableFieldState, field: IViewField | undefined) {
543
583
  if (MetaFieldKeys.includes(destinationKey)) return;
544
- if (typeof field === 'undefined') return;
545
- if (destinationKey === 'filters') {
584
+ if (typeof field === "undefined") return;
585
+ if (destinationKey === "filters") {
546
586
  return;
547
587
  }
548
-
549
-
588
+
550
589
  this.useMutable(({ encodings }) => {
551
590
  const cloneField = { ...toJS(field) };
552
591
  cloneField.dragId = uuidv4();
553
592
  encodings[destinationKey].push(cloneField);
554
593
  });
555
594
  }
556
- public renderSpec (spec: Specification) {
595
+ public renderSpec(spec: Specification) {
557
596
  const tab = this.visList[this.visIndex];
558
597
 
559
598
  if (tab) {
@@ -562,44 +601,67 @@ export class VizSpecStore {
562
601
  // const [xField, yField, ] = spec.position;
563
602
  this.clearState();
564
603
  if ((spec.geomType?.length ?? 0) > 0) {
565
- this.setVisualConfig('geoms', spec.geomType!.map(g => geomAdapter(g)));
604
+ this.setVisualConfig(
605
+ "geoms",
606
+ spec.geomType!.map((g) => geomAdapter(g))
607
+ );
566
608
  }
567
609
  if ((spec.facets?.length ?? 0) > 0) {
568
610
  const facets = (spec.facets || []).concat(spec.highFacets || []);
569
611
  for (let facet of facets) {
570
- this.appendField('rows', fields.find(f => f.fid === facet));
612
+ this.appendField(
613
+ "rows",
614
+ fields.find((f) => f.fid === facet)
615
+ );
571
616
  }
572
617
  }
573
618
  if (spec.position) {
574
619
  const [cols, rows] = spec.position;
575
- if (cols) this.appendField('columns', fields.find(f => f.fid === cols));
576
- if (rows) this.appendField('rows', fields.find(f => f.fid === rows));
620
+ if (cols)
621
+ this.appendField(
622
+ "columns",
623
+ fields.find((f) => f.fid === cols)
624
+ );
625
+ if (rows)
626
+ this.appendField(
627
+ "rows",
628
+ fields.find((f) => f.fid === rows)
629
+ );
577
630
  }
578
631
  if ((spec.color?.length ?? 0) > 0) {
579
- this.appendField('color', fields.find(f => f.fid === spec.color![0]));
632
+ this.appendField(
633
+ "color",
634
+ fields.find((f) => f.fid === spec.color![0])
635
+ );
580
636
  }
581
637
  if ((spec.size?.length ?? 0) > 0) {
582
- this.appendField('size', fields.find(f => f.fid === spec.size![0]));
638
+ this.appendField(
639
+ "size",
640
+ fields.find((f) => f.fid === spec.size![0])
641
+ );
583
642
  }
584
643
  if ((spec.opacity?.length ?? 0) > 0) {
585
- this.appendField('opacity', fields.find(f => f.fid === spec.opacity![0]));
644
+ this.appendField(
645
+ "opacity",
646
+ fields.find((f) => f.fid === spec.opacity![0])
647
+ );
586
648
  }
587
649
  }
588
650
  }
589
- public destroy () {
590
- this.reactions.forEach(rec => {
651
+ public destroy() {
652
+ this.reactions.forEach((rec) => {
591
653
  rec();
592
- })
654
+ });
593
655
  }
594
- public exportAsRaw () {
656
+ public exportAsRaw() {
595
657
  const pureVisList = dumpsGWPureSpec(this.visList);
596
658
  return stringifyGWContent({
597
659
  datasets: toJS(this.commonStore.datasets),
598
660
  dataSources: this.commonStore.dataSources,
599
- specList: pureVisList
600
- })
661
+ specList: pureVisList,
662
+ });
601
663
  }
602
- public importRaw (raw: string) {
664
+ public importRaw(raw: string) {
603
665
  const content = parseGWContent(raw);
604
666
  this.commonStore.datasets = content.datasets;
605
667
  this.commonStore.dataSources = content.dataSources;
@@ -608,4 +670,4 @@ export class VizSpecStore {
608
670
  this.visList = parseGWPureSpec(forwardVisualConfigs(content.specList));
609
671
  this.visIndex = 0;
610
672
  }
611
- }
673
+ }