@kanaries/graphic-walker 0.2.15 → 0.2.16

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 (97) hide show
  1. package/dist/App.d.ts +2 -0
  2. package/dist/assets/explainer.worker-8428eb12.js.map +1 -1
  3. package/dist/assets/transform.worker-5d54ff09.js.map +1 -0
  4. package/dist/assets/viewQuery.worker-ffefc111.js.map +1 -0
  5. package/dist/components/codeExport/index.d.ts +3 -0
  6. package/dist/components/loadingLayer.d.ts +2 -0
  7. package/dist/components/tabs/defaultTab.d.ts +1 -0
  8. package/dist/components/tabs/editableTab.d.ts +1 -2
  9. package/dist/dataSource/dataSelection/config.d.ts +1 -0
  10. package/dist/dataSource/dataSelection/utils.d.ts +2 -0
  11. package/dist/datasets/tmp/test.json +1 -0
  12. package/dist/graphic-walker.es.js +23081 -22577
  13. package/dist/graphic-walker.es.js.map +1 -1
  14. package/dist/graphic-walker.umd.js +130 -130
  15. package/dist/graphic-walker.umd.js.map +1 -1
  16. package/dist/index.d.ts +3 -3
  17. package/dist/interfaces.d.ts +21 -1
  18. package/dist/lib/execExp.d.ts +8 -0
  19. package/dist/lib/interfaces.d.ts +22 -0
  20. package/dist/lib/op/aggregate.d.ts +3 -0
  21. package/dist/lib/op/bin.d.ts +3 -0
  22. package/dist/lib/op/fold.d.ts +3 -0
  23. package/dist/lib/op/stat.d.ts +8 -0
  24. package/dist/lib/viewQuery.d.ts +5 -0
  25. package/dist/models/visSpecHistory.d.ts +2 -0
  26. package/dist/renderer/index.d.ts +8 -7
  27. package/dist/renderer/specRenderer.d.ts +13 -0
  28. package/dist/services.d.ts +4 -1
  29. package/dist/store/commonStore.d.ts +6 -0
  30. package/dist/store/index.d.ts +3 -2
  31. package/dist/store/visualSpecStore.d.ts +11 -4
  32. package/dist/utils/dataPrep.d.ts +2 -0
  33. package/dist/utils/index.d.ts +3 -5
  34. package/dist/utils/save.d.ts +1 -2
  35. package/dist/vis/react-vega.d.ts +1 -22
  36. package/dist/vis/spec/aggregate.d.ts +4 -0
  37. package/dist/vis/spec/encode.d.ts +19 -0
  38. package/dist/vis/spec/field.d.ts +2 -0
  39. package/dist/vis/spec/mark.d.ts +7 -0
  40. package/dist/vis/spec/stack.d.ts +4 -0
  41. package/dist/vis/spec/view.d.ts +67 -0
  42. package/dist/workers/transform.d.ts +2 -0
  43. package/package.json +4 -3
  44. package/src/App.tsx +5 -2
  45. package/src/components/codeExport/index.tsx +114 -0
  46. package/src/components/dataTable/index.tsx +10 -10
  47. package/src/components/loadingLayer.tsx +7 -0
  48. package/src/components/tabs/defaultTab.tsx +4 -2
  49. package/src/components/tabs/editableTab.tsx +74 -39
  50. package/src/dataSource/dataSelection/config.ts +11 -0
  51. package/src/dataSource/dataSelection/csvData.tsx +71 -39
  52. package/src/dataSource/dataSelection/gwFile.tsx +2 -2
  53. package/src/dataSource/dataSelection/utils.ts +28 -0
  54. package/src/dataSource/utils.ts +8 -3
  55. package/src/fields/datasetFields/meaFields.tsx +12 -4
  56. package/src/index.css +4 -4
  57. package/src/index.tsx +22 -22
  58. package/src/interfaces.ts +26 -2
  59. package/src/lib/execExp.ts +147 -0
  60. package/src/lib/interfaces.ts +39 -0
  61. package/src/lib/op/aggregate.ts +49 -0
  62. package/src/lib/op/bin.ts +25 -0
  63. package/src/lib/op/fold.ts +17 -0
  64. package/src/lib/op/stat.ts +46 -0
  65. package/src/lib/viewQuery.ts +23 -0
  66. package/src/locales/en-US.json +4 -2
  67. package/src/locales/i18n.ts +0 -1
  68. package/src/locales/ja-JP.json +4 -2
  69. package/src/locales/zh-CN.json +4 -2
  70. package/src/main.tsx +1 -1
  71. package/src/models/visSpecHistory.ts +14 -0
  72. package/src/renderer/index.tsx +58 -126
  73. package/src/renderer/specRenderer.tsx +119 -0
  74. package/src/segments/segmentNav.tsx +3 -16
  75. package/src/segments/visNav.tsx +17 -6
  76. package/src/services.ts +37 -1
  77. package/src/store/commonStore.ts +14 -9
  78. package/src/store/index.tsx +11 -4
  79. package/src/store/visualSpecStore.ts +89 -50
  80. package/src/utils/dataPrep.ts +24 -0
  81. package/src/utils/index.ts +16 -17
  82. package/src/utils/normalization.ts +3 -1
  83. package/src/utils/save.ts +1 -2
  84. package/src/vis/react-vega.tsx +4 -340
  85. package/src/vis/spec/aggregate.ts +13 -0
  86. package/src/vis/spec/encode.ts +69 -0
  87. package/src/vis/spec/field.ts +10 -0
  88. package/src/vis/spec/mark.ts +30 -0
  89. package/src/vis/spec/stack.ts +11 -0
  90. package/src/vis/spec/view.ts +138 -0
  91. package/src/vis/theme.ts +12 -0
  92. package/src/visualSettings/index.tsx +10 -1
  93. package/src/workers/transform.ts +12 -0
  94. package/src/workers/transform.worker.js +13 -0
  95. package/src/workers/viewQuery.worker.js +16 -0
  96. package/dist/dataSource/pannel.d.ts +0 -5
  97. package/src/dataSource/pannel.tsx +0 -71
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
- import { IGWProps } from './App';
3
- import './empty_sheet.css';
1
+ import React from "react";
2
+ import { IGWProps } from "./App";
3
+ import "./empty_sheet.css";
4
4
  export declare const ShadowDomContext: React.Context<{
5
5
  root: ShadowRoot | null;
6
6
  }>;
@@ -30,6 +30,24 @@ export interface IUncertainMutField {
30
30
  semanticType: ISemanticType | '?';
31
31
  analyticType: IAnalyticType | '?';
32
32
  }
33
+ export type IExpParamter = {
34
+ type: 'field';
35
+ value: string;
36
+ } | {
37
+ type: 'value';
38
+ value: any;
39
+ } | {
40
+ type: 'expression';
41
+ value: IExpression;
42
+ } | {
43
+ type: 'constant';
44
+ value: any;
45
+ };
46
+ export interface IExpression {
47
+ op: 'bin' | 'log2' | 'log10' | 'one' | 'binCount';
48
+ params: IExpParamter[];
49
+ as: string;
50
+ }
33
51
  export interface IField {
34
52
  /**
35
53
  * fid: key in data record
@@ -46,6 +64,8 @@ export interface IField {
46
64
  semanticType: ISemanticType;
47
65
  analyticType: IAnalyticType;
48
66
  cmp?: (a: any, b: any) => number;
67
+ computed?: boolean;
68
+ expressoion?: IExpression;
49
69
  }
50
70
  export interface IViewField extends IField {
51
71
  dragId: string;
@@ -146,7 +166,7 @@ export interface IVisualConfig {
146
166
  }
147
167
  export interface IVisSpec {
148
168
  readonly visId: string;
149
- readonly name?: [string, Record<string, any>?];
169
+ readonly name?: string;
150
170
  readonly encodings: DeepReadonly<DraggableFieldState>;
151
171
  readonly config: DeepReadonly<IVisualConfig>;
152
172
  }
@@ -0,0 +1,8 @@
1
+ import { IExpression, IField, IRow } from "../interfaces";
2
+ interface IDataFrame {
3
+ [key: string]: any[];
4
+ }
5
+ export declare function execExpression(exp: IExpression, dataFrame: IDataFrame, columns: IField[]): IDataFrame;
6
+ export declare function dataset2DataFrame(dataset: IRow[], columns: IField[]): IDataFrame;
7
+ export declare function dataframe2Dataset(dataFrame: IDataFrame, columns: IField[]): IRow[];
8
+ export {};
@@ -0,0 +1,22 @@
1
+ export interface IAggQuery {
2
+ op: 'aggregate';
3
+ groupBy: string[];
4
+ agg: {
5
+ [field: string]: 'sum' | 'count' | 'max' | 'min' | 'mean' | 'median' | 'variance' | 'stdev';
6
+ };
7
+ }
8
+ export interface IFoldQuery {
9
+ op: 'fold';
10
+ foldBy: string[];
11
+ newFoldKeyCol: string;
12
+ newFoldValueCol: string;
13
+ }
14
+ export interface IBinQuery {
15
+ op: 'bin';
16
+ binBy: string;
17
+ newBinCol: string;
18
+ binSize: number;
19
+ }
20
+ export interface IRawQuery {
21
+ op: 'raw';
22
+ }
@@ -0,0 +1,3 @@
1
+ import { IRow } from "visual-insights";
2
+ import { IAggQuery } from "../interfaces";
3
+ export declare function aggregate(data: IRow[], query: IAggQuery): IRow[];
@@ -0,0 +1,3 @@
1
+ import { IRow } from "visual-insights";
2
+ import { IBinQuery } from "../interfaces";
3
+ export declare function bin(dataSource: IRow[], query: IBinQuery): IRow[];
@@ -0,0 +1,3 @@
1
+ import { IRow } from "visual-insights";
2
+ import { IFoldQuery } from "../interfaces";
3
+ export declare function fold(data: IRow[], query: IFoldQuery): IRow[];
@@ -0,0 +1,8 @@
1
+ export declare function mean(nums: number[]): number;
2
+ export declare function sum(nums: number[]): number;
3
+ export declare function median(nums: number[]): number;
4
+ export declare function variance(nums: number[]): number;
5
+ export declare function stdev(nums: number[]): number;
6
+ export declare function max(nums: number[]): number;
7
+ export declare function min(nums: number[]): number;
8
+ export declare function count(nums: number[]): number;
@@ -0,0 +1,5 @@
1
+ import { IRow } from "visual-insights";
2
+ import { IMutField } from "../interfaces";
3
+ import { IAggQuery, IBinQuery, IFoldQuery, IRawQuery } from "./interfaces";
4
+ export type IViewQuery = IAggQuery | IFoldQuery | IBinQuery | IRawQuery;
5
+ export declare function queryView(rawData: IRow[], metas: IMutField[], query: IViewQuery): IRow[];
@@ -6,6 +6,7 @@ export declare class VisSpecWithHistory {
6
6
  constructor(data: IVisSpec);
7
7
  private get frame();
8
8
  private batchFlag;
9
+ updateLatest(snapshot: Partial<Readonly<VisSpecWithHistory['snapshots'][0]>>): void;
9
10
  private commit;
10
11
  get canUndo(): boolean;
11
12
  undo(): boolean;
@@ -18,5 +19,6 @@ export declare class VisSpecWithHistory {
18
19
  set encodings(encodings: IVisSpec['encodings']);
19
20
  get config(): DeepReadonly<IVisualConfig>;
20
21
  set config(config: IVisSpec['config']);
22
+ clone(): VisSpecWithHistory;
21
23
  exportGW(): IVisSpec;
22
24
  }
@@ -1,8 +1,9 @@
1
- import React from "react";
2
- import { IReactVegaHandler } from "../vis/react-vega";
3
- import { IDarkMode, IThemeKey } from "../interfaces";
4
- declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Pick<{
5
- themeKey?: IThemeKey | undefined;
6
- dark?: IDarkMode | undefined;
7
- } & React.RefAttributes<IReactVegaHandler>, "dark" | "key" | "themeKey"> & React.RefAttributes<IReactVegaHandler>>>;
1
+ import React from 'react';
2
+ import { IDarkMode, IThemeKey } from '../interfaces';
3
+ import { IReactVegaHandler } from '../vis/react-vega';
4
+ interface RendererProps {
5
+ themeKey?: IThemeKey;
6
+ dark?: IDarkMode;
7
+ }
8
+ declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Pick<RendererProps & React.RefAttributes<IReactVegaHandler>, "key" | keyof RendererProps> & React.RefAttributes<IReactVegaHandler>>>;
8
9
  export default _default;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { IReactVegaHandler } from '../vis/react-vega';
3
+ import { DeepReadonly, DraggableFieldState, IDarkMode, IRow, IThemeKey, IVisualConfig } from '../interfaces';
4
+ interface SpecRendererProps {
5
+ themeKey?: IThemeKey;
6
+ dark?: IDarkMode;
7
+ data: IRow[];
8
+ loading: boolean;
9
+ draggableFieldState: DeepReadonly<DraggableFieldState>;
10
+ visualConfig: IVisualConfig;
11
+ }
12
+ declare const SpecRenderer: React.ForwardRefExoticComponent<SpecRendererProps & React.RefAttributes<IReactVegaHandler>>;
13
+ export default SpecRenderer;
@@ -1,6 +1,7 @@
1
1
  import { Specification } from 'visual-insights';
2
2
  import { IRow, Filters, SemanticType, IMeasure, IMutField, IFilterField } from './interfaces';
3
3
  import { IExplaination, IMeasureWithStat } from './insights';
4
+ import { IViewQuery } from './lib/viewQuery';
4
5
  interface ExplainParams {
5
6
  dimensions: string[];
6
7
  measures: string[];
@@ -31,5 +32,7 @@ interface PreAnalysisParams {
31
32
  }
32
33
  export declare function preAnalysis(props: PreAnalysisParams): Promise<void>;
33
34
  export declare function destroyWorker(): void;
34
- export declare const applyFilter: (data: readonly IRow[], filters: readonly IFilterField[]) => Promise<IRow[]>;
35
+ export declare const applyFilter: (data: IRow[], filters: readonly IFilterField[]) => Promise<IRow[]>;
36
+ export declare const transformDataService: (data: IRow[], columns: IMutField[]) => Promise<IRow[]>;
37
+ export declare const applyViewQuery: (data: IRow[], metas: IMutField[], query: IViewQuery) => Promise<IRow[]>;
35
38
  export {};
@@ -13,6 +13,7 @@ export declare class CommonStore {
13
13
  position: [number, number];
14
14
  };
15
15
  showDataConfig: boolean;
16
+ showCodeExportPanel: boolean;
16
17
  filters: Filters;
17
18
  segmentKey: ISegmentKey;
18
19
  constructor();
@@ -22,6 +23,7 @@ export declare class CommonStore {
22
23
  setShowDataConfig(show: boolean): void;
23
24
  setShowInsightBoard(show: boolean): void;
24
25
  showEmbededMenu(position: [number, number]): void;
26
+ setShowCodeExportPanel(show: boolean): void;
25
27
  closeEmbededMenu(): void;
26
28
  initTempDS(): void;
27
29
  updateTempFields(fields: IMutField[]): void;
@@ -31,6 +33,10 @@ export declare class CommonStore {
31
33
  updateTempFieldSemanticType(fieldKey: string, semanticType: IMutField['semanticType']): void;
32
34
  updateTempName(name: string): void;
33
35
  updateTempDS(rawData: IRow[]): void;
36
+ /**
37
+ * update temp dataset (standard) with dataset info
38
+ * @param dataset
39
+ */
34
40
  updateTempSTDDS(dataset: IDataSetInfo): void;
35
41
  commitTempDS(): void;
36
42
  startDSBuildingTask(): void;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { CommonStore } from './commonStore';
3
3
  import { VizSpecStore } from './visualSpecStore';
4
- interface GlobalStore {
4
+ export interface IGlobalStore {
5
5
  commonStore: CommonStore;
6
6
  vizStore: VizSpecStore;
7
7
  }
@@ -9,11 +9,12 @@ export declare function destroyGWStore(): void;
9
9
  export declare function rebootGWStore(): void;
10
10
  interface StoreWrapperProps {
11
11
  keepAlive?: boolean;
12
+ storeRef?: React.MutableRefObject<IGlobalStore | null>;
12
13
  }
13
14
  export declare class StoreWrapper extends React.Component<StoreWrapperProps> {
14
15
  constructor(props: StoreWrapperProps);
15
16
  componentWillUnmount(): void;
16
17
  render(): JSX.Element;
17
18
  }
18
- export declare function useGlobalStore(): GlobalStore;
19
+ export declare function useGlobalStore(): IGlobalStore;
19
20
  export {};
@@ -1,7 +1,10 @@
1
1
  import { Specification } from "visual-insights";
2
- import { DataSet, DraggableFieldState, IFilterRule, IViewField, IVisualConfig } from "../interfaces";
2
+ import { DataSet, DraggableFieldState, IFilterRule, IViewField, IVisSpec, IVisualConfig } from "../interfaces";
3
3
  import { VisSpecWithHistory } from "../models/visSpecHistory";
4
+ import { IStoInfo } from "../utils/save";
4
5
  import { CommonStore } from "./commonStore";
6
+ export declare function initEncoding(): DraggableFieldState;
7
+ export declare function initVisualConfig(): IVisualConfig;
5
8
  type DeepReadonly<T extends Record<keyof any, any>> = {
6
9
  readonly [K in keyof T]: T[K] extends Record<keyof any, any> ? DeepReadonly<T[K]> : T[K];
7
10
  };
@@ -76,7 +79,9 @@ export declare class VizSpecStore {
76
79
  * dimension fields in visualization
77
80
  */
78
81
  get viewMeasures(): IViewField[];
79
- addVisualization(): void;
82
+ get allFields(): IViewField[];
83
+ get viewFilters(): readonly DeepReadonly<import("../interfaces").IFilterField>[];
84
+ addVisualization(defaultName?: string): void;
80
85
  selectVisualization(visIndex: number): void;
81
86
  setVisName(visIndex: number, name: string): void;
82
87
  initState(): void;
@@ -99,8 +104,8 @@ export declare class VizSpecStore {
99
104
  setFilterEditing(index: number): void;
100
105
  closeFilterEditing(): void;
101
106
  transpose(): void;
102
- createBinField(stateKey: keyof DraggableFieldState, index: number): void;
103
- createLogField(stateKey: keyof DraggableFieldState, index: number): void;
107
+ createBinField(stateKey: keyof DraggableFieldState, index: number, binType: 'bin' | 'binCount'): void;
108
+ createLogField(stateKey: keyof DraggableFieldState, index: number, scaleType: 'log10' | 'log2'): void;
104
109
  setFieldAggregator(stateKey: keyof DraggableFieldState, index: number, aggName: string): void;
105
110
  get sortCondition(): boolean;
106
111
  setFieldSort(stateKey: keyof DraggableFieldState, index: number, sortType: "none" | "ascending" | "descending"): void;
@@ -109,6 +114,8 @@ export declare class VizSpecStore {
109
114
  renderSpec(spec: Specification): void;
110
115
  destroy(): void;
111
116
  exportAsRaw(): string;
117
+ exportViewSpec(): IVisSpec[];
118
+ importStoInfo(stoInfo: IStoInfo): void;
112
119
  importRaw(raw: string): void;
113
120
  }
114
121
  export {};
@@ -4,3 +4,5 @@ export declare function guardDataKeys(data: IRow[], metas: IMutField[]): {
4
4
  safeData: IRow[];
5
5
  safeMetas: IMutField[];
6
6
  };
7
+ export declare function flatNestKeys(object: any): string[];
8
+ export declare function getValueByKeyPath(object: any, keyPath: string): any;
@@ -1,4 +1,4 @@
1
- import { IRow, Filters, IMutField } from "../interfaces";
1
+ import { IRow, Filters, IViewField } from "../interfaces";
2
2
  export declare function checkMajorFactor(data: IRow[], childrenData: Map<any, IRow[]>, dimensions: string[], measures: string[]): {
3
3
  majorKey: string;
4
4
  majorSum: number;
@@ -16,9 +16,7 @@ export declare function getPredicates(selection: IRow[], dimensions: string[], m
16
16
  export declare function getPredicatesFromVegaSignals(signals: Filters, dimensions: string[], measures: string[]): IPredicate[];
17
17
  export declare function filterByPredicates(data: IRow[], predicates: IPredicate[]): IRow[];
18
18
  export declare function applyFilters(dataSource: IRow[], filters: Filters): IRow[];
19
- export declare function extendCountField(dataSource: IRow[], fields: IMutField[]): {
20
- dataSource: IRow[];
21
- fields: IMutField[];
22
- };
19
+ export declare function createCountField(): IViewField;
23
20
  export declare function getRange(nums: number[]): [number, number];
24
21
  export declare function makeNumbersBeautiful(nums: number[]): number[];
22
+ export declare function classNames(...classes: string[]): string;
@@ -2,7 +2,7 @@ import { IDataSet, IDataSource, IVisSpec } from "../interfaces";
2
2
  import { VisSpecWithHistory } from "../models/visSpecHistory";
3
3
  export declare function dumpsGWPureSpec(list: VisSpecWithHistory[]): IVisSpec[];
4
4
  export declare function parseGWPureSpec(list: IVisSpec[]): VisSpecWithHistory[];
5
- interface IStoInfo {
5
+ export interface IStoInfo {
6
6
  datasets: IDataSet[];
7
7
  specList: {
8
8
  [K in keyof IVisSpec]: K extends "config" ? Partial<IVisSpec[K]> : IVisSpec[K];
@@ -12,4 +12,3 @@ interface IStoInfo {
12
12
  export declare function stringifyGWContent(info: IStoInfo): string;
13
13
  export declare function parseGWContent(raw: string): IStoInfo;
14
14
  export declare function download(data: string, filename: string, type: string): void;
15
- export {};
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { IViewField, IRow, IStackMode, IDarkMode, IThemeKey } from '../interfaces';
3
+ import { SingleViewProps } from './spec/view';
3
4
  export interface IReactVegaHandler {
4
5
  getSVGData: () => Promise<string[]>;
5
6
  getCanvasData: () => Promise<string[]>;
@@ -31,27 +32,5 @@ interface ReactVegaProps {
31
32
  themeKey?: IThemeKey;
32
33
  dark?: IDarkMode;
33
34
  }
34
- interface SingleViewProps {
35
- x: IViewField;
36
- y: IViewField;
37
- color: IViewField;
38
- opacity: IViewField;
39
- size: IViewField;
40
- shape: IViewField;
41
- xOffset: IViewField;
42
- yOffset: IViewField;
43
- row: IViewField;
44
- column: IViewField;
45
- theta: IViewField;
46
- radius: IViewField;
47
- defaultAggregated: boolean;
48
- stack: IStackMode;
49
- geomType: string;
50
- enableCrossFilter: boolean;
51
- asCrossFilterTrigger: boolean;
52
- selectEncoding: 'default' | 'none';
53
- brushEncoding: 'x' | 'y' | 'default' | 'none';
54
- hideLegend?: boolean;
55
- }
56
35
  declare const ReactVega: React.ForwardRefExoticComponent<ReactVegaProps & React.RefAttributes<IReactVegaHandler>>;
57
36
  export default ReactVega;
@@ -0,0 +1,4 @@
1
+ import { IViewField } from '../../interfaces';
2
+ export declare function channelAggregate(encoding: {
3
+ [key: string]: any;
4
+ }, fields: IViewField[]): void;
@@ -0,0 +1,19 @@
1
+ import { IViewField } from '../../interfaces';
2
+ export interface IEncodeProps {
3
+ geomType: string;
4
+ x: IViewField;
5
+ y: IViewField;
6
+ color: IViewField;
7
+ opacity: IViewField;
8
+ size: IViewField;
9
+ shape: IViewField;
10
+ xOffset: IViewField;
11
+ yOffset: IViewField;
12
+ row: IViewField;
13
+ column: IViewField;
14
+ theta: IViewField;
15
+ radius: IViewField;
16
+ }
17
+ export declare function channelEncode(props: IEncodeProps): {
18
+ [key: string]: any;
19
+ };
@@ -0,0 +1,2 @@
1
+ import { IViewField } from "../../interfaces";
2
+ export declare const NULL_FIELD: IViewField;
@@ -0,0 +1,7 @@
1
+ import { ISemanticType } from "visual-insights";
2
+ /**
3
+ *
4
+ * @param semanticTypeList semanticTypeList.length <= 2,调用时,手动将columns 和 rows的最后一个元素组合传进来
5
+ * @returns geom(mark) type
6
+ */
7
+ export declare function autoMark(semanticTypeList: ISemanticType[]): string;
@@ -0,0 +1,4 @@
1
+ import { IStackMode } from "../../interfaces";
2
+ export declare function channelStack(encoding: {
3
+ [key: string]: any;
4
+ }, stackMode: IStackMode): void;
@@ -0,0 +1,67 @@
1
+ import { IStackMode } from '../../interfaces';
2
+ import { IEncodeProps } from './encode';
3
+ export interface SingleViewProps extends IEncodeProps {
4
+ defaultAggregated: boolean;
5
+ stack: IStackMode;
6
+ enableCrossFilter: boolean;
7
+ asCrossFilterTrigger: boolean;
8
+ selectEncoding: 'default' | 'none';
9
+ brushEncoding: 'x' | 'y' | 'default' | 'none';
10
+ hideLegend?: boolean;
11
+ }
12
+ export declare function getSingleView(props: SingleViewProps): {
13
+ config: any;
14
+ mark: {
15
+ type: string;
16
+ opacity: number;
17
+ tooltip: boolean;
18
+ };
19
+ encoding: {
20
+ [key: string]: any;
21
+ };
22
+ transform?: undefined;
23
+ params?: undefined;
24
+ } | {
25
+ config: any;
26
+ transform: {
27
+ filter: {
28
+ param: string;
29
+ };
30
+ }[];
31
+ params: {
32
+ name: string;
33
+ select: {
34
+ type: string;
35
+ encodings: ("x" | "y")[] | undefined;
36
+ };
37
+ }[];
38
+ mark: {
39
+ type: string;
40
+ opacity: number;
41
+ tooltip: boolean;
42
+ };
43
+ encoding: {
44
+ [key: string]: any;
45
+ };
46
+ } | {
47
+ config: any;
48
+ transform: {
49
+ filter: {
50
+ param: string;
51
+ };
52
+ }[];
53
+ params: {
54
+ name: string;
55
+ select: {
56
+ type: string;
57
+ };
58
+ }[];
59
+ mark: {
60
+ type: string;
61
+ opacity: number;
62
+ tooltip: boolean;
63
+ };
64
+ encoding: {
65
+ [key: string]: any;
66
+ };
67
+ };
@@ -0,0 +1,2 @@
1
+ import { IField, IRow } from "../interfaces";
2
+ export declare function transformData(data: IRow[], columns: IField[]): IRow[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanaries/graphic-walker",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "scripts": {
5
5
  "dev:front_end": "vite --host",
6
6
  "dev": "npm run dev:front_end",
@@ -28,14 +28,15 @@
28
28
  },
29
29
  "prettier": {
30
30
  "tabWidth": 4,
31
- "printWidth": 120
31
+ "printWidth": 120,
32
+ "singleQuote": true
32
33
  },
33
34
  "types": "./dist/index.d.ts",
34
35
  "dependencies": {
35
36
  "@headlessui/react": "^1.7.12",
36
37
  "@heroicons/react": "^2.0.8",
37
38
  "@kanaries/react-beautiful-dnd": "0.0.1",
38
- "@kanaries/web-data-loader": "0.1.5",
39
+ "@kanaries/web-data-loader": "^0.1.7",
39
40
  "autoprefixer": "^10.3.5",
40
41
  "i18next": "^21.9.1",
41
42
  "i18next-browser-languagedetector": "^6.1.5",
package/src/App.tsx CHANGED
@@ -14,7 +14,7 @@ import AestheticFields from "./fields/aestheticFields";
14
14
  import DatasetFields from "./fields/datasetFields/index";
15
15
  import ReactiveRenderer from "./renderer/index";
16
16
  import DataSourceSegment from "./dataSource/index";
17
- import { useGlobalStore } from "./store";
17
+ import { IGlobalStore, useGlobalStore } from "./store";
18
18
  import { preAnalysis, destroyWorker } from "./services";
19
19
  import VisNav from "./segments/visNav";
20
20
  import { mergeLocaleRes, setLocaleLanguage } from "./locales/i18n";
@@ -23,6 +23,7 @@ import { guardDataKeys } from "./utils/dataPrep";
23
23
  import SegmentNav from "./segments/segmentNav";
24
24
  import DatasetConfig from "./dataSource/datasetConfig";
25
25
  import { useCurrentMediaTheme } from "./utils/media";
26
+ import CodeExport from "./components/codeExport";
26
27
 
27
28
  export interface IGWProps {
28
29
  dataSource?: IRow[];
@@ -39,6 +40,7 @@ export interface IGWProps {
39
40
  /** @default "vega" */
40
41
  themeKey?: IThemeKey;
41
42
  dark?: IDarkMode;
43
+ storeRef?: React.MutableRefObject<IGlobalStore | null>;
42
44
  }
43
45
 
44
46
  const App = observer<IGWProps>(function App (props) {
@@ -51,7 +53,7 @@ const App = observer<IGWProps>(function App (props) {
51
53
  hideDataSourceConfig,
52
54
  fieldKeyGuard = true,
53
55
  themeKey = 'vega',
54
- dark = 'media',
56
+ dark = 'media'
55
57
  } = props;
56
58
  const { commonStore, vizStore } = useGlobalStore();
57
59
  const [insightReady, setInsightReady] = useState<boolean>(true);
@@ -139,6 +141,7 @@ const App = observer<IGWProps>(function App (props) {
139
141
  {segmentKey === ISegmentKey.vis && (
140
142
  <div style={{ marginTop: "0em", borderTop: "none" }} className="m-4 p-4 border border-gray-200 dark:border-gray-700">
141
143
  <VisualSettings rendererHandler={rendererRef} darkModePreference={dark} />
144
+ <CodeExport />
142
145
  <div className="md:grid md:grid-cols-12 xl:grid-cols-6">
143
146
  <div className="md:col-span-3 xl:col-span-1">
144
147
  <DatasetFields />
@@ -0,0 +1,114 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import Modal from "../modal";
3
+ import { observer } from "mobx-react-lite";
4
+ import { useGlobalStore } from "../../store";
5
+ import DefaultButton from "../button/default";
6
+ import PrimaryButton from "../button/primary";
7
+ import { useTranslation } from "react-i18next";
8
+ import DefaultTab, { ITabOption } from "../tabs/defaultTab";
9
+
10
+ const syntaxHighlight = (json: any) => {
11
+ if (typeof json != "string") {
12
+ json = JSON.stringify(json, undefined, 4);
13
+ }
14
+ json = json
15
+ .replace(/&/g, "&amp;")
16
+ .replace(/</g, "&lt;")
17
+ .replace(/>/g, "&gt;")
18
+ .replace(/\n/g, "<br>")
19
+ .replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;")
20
+ .replace(/\s/g, "&nbsp;&nbsp;");
21
+ return json.replace(
22
+ /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
23
+ function (match) {
24
+ var cls = "text-sky-500"; // number
25
+ if (/^"/.test(match)) {
26
+ if (/:$/.test(match)) {
27
+ cls = "text-purple-500"; // key
28
+ } else {
29
+ cls = "text-emerald-500"; // string
30
+ }
31
+ } else if (/true|false/.test(match)) {
32
+ cls = "text-blue-500";
33
+ } else if (/null/.test(match)) {
34
+ cls = "text-sky-500";
35
+ }
36
+ return '<span class="' + cls + '">' + match + "</span>";
37
+ }
38
+ );
39
+ };
40
+
41
+ const CodeExport: React.FC = observer((props) => {
42
+ const { commonStore, vizStore } = useGlobalStore();
43
+ const { showCodeExportPanel } = commonStore;
44
+ const { t } = useTranslation();
45
+ const [tabKey, setTabKey] = useState<string>("graphic-walker");
46
+ const [code, setCode] = useState<any>("");
47
+
48
+ const specTabs: ITabOption[] = [
49
+ {
50
+ key: "graphic-walker",
51
+ label: "Graphic-Walker",
52
+ },
53
+ {
54
+ key: "vega-lite",
55
+ label: "Vega-Lite",
56
+ disabled: true
57
+ },
58
+ ];
59
+
60
+ useEffect(() => {
61
+ if (showCodeExportPanel) {
62
+ if (tabKey === "graphic-walker") {
63
+ const res = vizStore.exportViewSpec();
64
+ setCode(res);
65
+ } else {
66
+ setCode("vega code");
67
+ }
68
+ }
69
+ }, [tabKey, showCodeExportPanel]);
70
+ return (
71
+ <Modal
72
+ show={showCodeExportPanel}
73
+ onClose={() => {
74
+ commonStore.setShowCodeExportPanel(false);
75
+ }}
76
+ >
77
+ <div>
78
+ <h1>Code Export</h1>
79
+ <DefaultTab
80
+ tabs={specTabs}
81
+ selectedKey={tabKey}
82
+ onSelected={(k) => {
83
+ setTabKey(k as string);
84
+ }}
85
+ />
86
+ {tabKey === "graphic-walker" && (
87
+ <div className="text-sm px-6 max-h-56 overflow-auto">
88
+ <div dangerouslySetInnerHTML={{ __html: syntaxHighlight(code) }} />
89
+ </div>
90
+ )}
91
+ <div className="mt-4 flex justify-start">
92
+ <PrimaryButton
93
+ // text={t("actions.confirm")}
94
+ className="mr-2 px-6"
95
+ text="Copy to Clipboard"
96
+ onClick={() => {
97
+ navigator.clipboard.writeText(JSON.stringify(code));
98
+ commonStore.setShowCodeExportPanel(false);
99
+ }}
100
+ />
101
+ <DefaultButton
102
+ text={t("actions.cancel")}
103
+ className="mr-2 px-6"
104
+ onClick={() => {
105
+ commonStore.setShowCodeExportPanel(false);
106
+ }}
107
+ />
108
+ </div>
109
+ </div>
110
+ </Modal>
111
+ );
112
+ });
113
+
114
+ export default CodeExport;