@kanaries/graphic-walker 0.3.4 → 0.3.5

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 (58) hide show
  1. package/dist/assets/viewQuery.worker-03404216.js.map +1 -0
  2. package/dist/components/pivotTable/index.d.ts +12 -0
  3. package/dist/components/pivotTable/inteface.d.ts +6 -0
  4. package/dist/components/pivotTable/leftTree.d.ts +10 -0
  5. package/dist/components/pivotTable/metricTable.d.ts +9 -0
  6. package/dist/components/pivotTable/store.d.ts +22 -0
  7. package/dist/components/pivotTable/topTree.d.ts +10 -0
  8. package/dist/components/pivotTable/utils.d.ts +6 -0
  9. package/dist/components/visualConfig/index.d.ts +3 -0
  10. package/dist/config.d.ts +2 -0
  11. package/dist/fields/aestheticFields.d.ts +2 -2
  12. package/dist/graphic-walker.es.js +23167 -22784
  13. package/dist/graphic-walker.es.js.map +1 -1
  14. package/dist/graphic-walker.umd.js +127 -127
  15. package/dist/graphic-walker.umd.js.map +1 -1
  16. package/dist/interfaces.d.ts +6 -0
  17. package/dist/lib/insights/utils.d.ts +0 -2
  18. package/dist/lib/interfaces.d.ts +5 -3
  19. package/dist/store/commonStore.d.ts +2 -0
  20. package/dist/store/visualSpecStore.d.ts +1 -0
  21. package/dist/utils/index.d.ts +1 -0
  22. package/dist/vis/react-vega.d.ts +3 -1
  23. package/dist/vis/spec/encode.d.ts +2 -0
  24. package/package.json +1 -1
  25. package/src/App.tsx +2 -0
  26. package/src/components/pivotTable/index.tsx +119 -0
  27. package/src/components/pivotTable/inteface.ts +8 -0
  28. package/src/components/pivotTable/leftTree.tsx +92 -0
  29. package/src/components/pivotTable/metricTable.tsx +107 -0
  30. package/src/components/pivotTable/store.tsx +66 -0
  31. package/src/components/pivotTable/topTree.tsx +77 -0
  32. package/src/components/pivotTable/utils.ts +141 -0
  33. package/src/components/visualConfig/index.tsx +76 -0
  34. package/src/config.ts +5 -1
  35. package/src/fields/aestheticFields.tsx +25 -4
  36. package/src/fields/components.tsx +2 -2
  37. package/src/fields/fieldsContext.tsx +2 -1
  38. package/src/interfaces.ts +6 -0
  39. package/src/lib/insights/explainByChildren.ts +11 -3
  40. package/src/lib/insights/explainBySelection.ts +14 -5
  41. package/src/lib/insights/explainValue.ts +10 -3
  42. package/src/lib/insights/utils.ts +0 -4
  43. package/src/lib/interfaces.ts +1 -3
  44. package/src/lib/op/aggregate.ts +9 -7
  45. package/src/locales/en-US.json +11 -2
  46. package/src/locales/ja-JP.json +187 -178
  47. package/src/locales/zh-CN.json +11 -2
  48. package/src/renderer/index.tsx +16 -2
  49. package/src/renderer/specRenderer.tsx +6 -2
  50. package/src/store/commonStore.ts +4 -0
  51. package/src/store/visualSpecStore.ts +12 -0
  52. package/src/utils/index.ts +7 -0
  53. package/src/vis/react-vega.tsx +31 -7
  54. package/src/vis/spec/aggregate.ts +3 -0
  55. package/src/vis/spec/encode.ts +5 -1
  56. package/src/vis/spec/view.ts +4 -2
  57. package/src/visualSettings/index.tsx +11 -0
  58. package/dist/assets/viewQuery.worker-ffefc111.js.map +0 -1
@@ -1,197 +1,206 @@
1
1
  {
2
+ "config": {
3
+ "format": "形式",
4
+ "numberFormat": "数字の形式",
5
+ "timeFormat": "時間の形式",
6
+ "normalizedNumberFormat": "正規化された数字の形式"
7
+ },
2
8
  "constant": {
3
- "row_count": "行数",
4
- "analytic_type": {
5
- "dimension": "次元",
6
- "measure": "尺度"
7
- },
8
- "semantic_type": {
9
- "nominal": "名義尺度",
10
- "ordinal": "順序尺度",
11
- "temporal": "時間尺度",
12
- "quantitative": "数量尺度"
13
- },
14
- "mark_type": {
15
- "__enum__": "マークタイプ",
16
- "auto": "自動",
17
- "bar": "バー",
18
- "line": "ライン",
19
- "area": "エリア",
20
- "trail": "トレイル",
21
- "point": "散布図",
22
- "circle": "円",
23
- "tick": "棒線図",
24
- "rect": "長方形",
25
- "arc": "アーク",
26
- "boxplot": "ボックスプロット"
27
- },
28
- "stack_mode": {
29
- "__enum__": "スタックモード",
30
- "none": "なし",
31
- "stack": "スタック",
32
- "normalize": "正規化"
33
- },
34
- "layout_type": {
35
- "__enum__": "レイアウトタイプ",
36
- "auto": "自動",
37
- "fixed": "固定"
38
- },
39
- "exploration_mode": {
40
- "__enum__": "探索モード",
41
- "none": "オフ",
42
- "brush": "ブラシ",
43
- "point": "ポイント"
44
- },
45
- "brush_mode": {
46
- "__enum__": "ブラシの方向",
47
- "default": "両方",
48
- "x": "X軸のみ",
49
- "y": "Y軸のみ"
50
- },
51
- "draggable_key": {
52
- "fields": "フィールド",
53
- "columns": "X軸",
54
- "rows": "Y軸",
55
- "color": "",
56
- "opacity": "不透明度",
57
- "size": "大きさ",
58
- "shape": "形状",
59
- "theta": "角度",
60
- "radius": "半径",
61
- "filters": "フィルター"
62
- },
63
- "aggregator": {
64
- "sum": "合計",
65
- "mean": "平均",
66
- "count": "件数",
67
- "median": "中央値",
68
- "min": "最小値",
69
- "max": "最大値",
70
- "q1": "第一四分位数",
71
- "q3": "第三四分位数",
72
- "stdev": "標準偏差",
73
- "variance": "分散"
74
- },
75
- "filter_type": {
76
- "one_of": "1つ以上",
77
- "range": "範囲",
78
- "temporal_range": "日付範囲"
79
- }
9
+ "row_count": "行数",
10
+ "analytic_type": {
11
+ "dimension": "次元",
12
+ "measure": "尺度"
13
+ },
14
+ "semantic_type": {
15
+ "nominal": "名義尺度",
16
+ "ordinal": "順序尺度",
17
+ "temporal": "時間尺度",
18
+ "quantitative": "数量尺度"
19
+ },
20
+ "mark_type": {
21
+ "__enum__": "マークタイプ",
22
+ "auto": "自動",
23
+ "bar": "バー",
24
+ "line": "ライン",
25
+ "area": "エリア",
26
+ "trail": "トレイル",
27
+ "point": "散布図",
28
+ "circle": "円",
29
+ "tick": "棒線図",
30
+ "rect": "長方形",
31
+ "arc": "アーク",
32
+ "boxplot": "ボックスプロット",
33
+ "table": "表",
34
+ "text": "本文"
35
+ },
36
+ "stack_mode": {
37
+ "__enum__": "スタックモード",
38
+ "none": "なし",
39
+ "stack": "スタック",
40
+ "normalize": "正規化"
41
+ },
42
+ "layout_type": {
43
+ "__enum__": "レイアウトタイプ",
44
+ "auto": "自動",
45
+ "fixed": "固定"
46
+ },
47
+ "exploration_mode": {
48
+ "__enum__": "探索モード",
49
+ "none": "オフ",
50
+ "brush": "ブラシ",
51
+ "point": "ポイント"
52
+ },
53
+ "brush_mode": {
54
+ "__enum__": "ブラシの方向",
55
+ "default": "両方",
56
+ "x": "X軸のみ",
57
+ "y": "Y軸のみ"
58
+ },
59
+ "draggable_key": {
60
+ "fields": "フィールド",
61
+ "columns": "X軸",
62
+ "rows": "Y軸",
63
+ "color": "",
64
+ "opacity": "不透明度",
65
+ "size": "大きさ",
66
+ "shape": "形状",
67
+ "theta": "角度",
68
+ "radius": "半径",
69
+ "filters": "フィルター",
70
+ "text": "本文"
71
+ },
72
+ "aggregator": {
73
+ "sum": "合計",
74
+ "mean": "平均",
75
+ "count": "件数",
76
+ "median": "中央値",
77
+ "min": "最小値",
78
+ "max": "最大値",
79
+ "q1": "第一四分位数",
80
+ "q3": "第三四分位数",
81
+ "stdev": "標準偏差",
82
+ "variance": "分散"
83
+ },
84
+ "filter_type": {
85
+ "one_of": "1つ以上",
86
+ "range": "範囲",
87
+ "temporal_range": "日付範囲"
88
+ }
80
89
  },
81
90
  "App": {
82
- "labels": {
83
- "data_interpretation": "データ解釈"
84
- },
85
- "segments": {
86
- "vis": "可視化",
87
- "data": "データ"
88
- }
91
+ "labels": {
92
+ "data_interpretation": "データ解釈"
93
+ },
94
+ "segments": {
95
+ "vis": "可視化",
96
+ "data": "データ"
97
+ }
89
98
  },
90
99
  "DataSource": {
91
- "labels": {
92
- "cur_dataset": "現在のデータセット"
93
- },
94
- "buttons": {
95
- "create_dataset": "データセットを作成",
96
- "export_as_file": "ファイルとして保存",
97
- "import_file": "Graphic Walkerファイルをインポート"
98
- },
99
- "dialog": {
100
- "create_data_source": "新しいデータソース",
101
- "data_types": "データソースの種類",
102
- "text_file_data": "ローカルファイル",
103
- "public_data": "公開データセット",
104
- "data_source_type": "データソースの種類:{{sourceType}}",
105
- "file": {
106
- "open": "開く...",
107
- "submit": "提出する",
108
- "dataset_name": "データセット名",
109
- "choose_file": "データファイルを選択してください",
110
- "get_start_desc": "データセットの作成を始めましょう。"
100
+ "labels": {
101
+ "cur_dataset": "現在のデータセット"
102
+ },
103
+ "buttons": {
104
+ "create_dataset": "データセットを作成",
105
+ "export_as_file": "ファイルとして保存",
106
+ "import_file": "Graphic Walkerファイルをインポート"
111
107
  },
112
- "public": {
113
- "submit": "提出する"
108
+ "dialog": {
109
+ "create_data_source": "新しいデータソース",
110
+ "data_types": "データソースの種類",
111
+ "text_file_data": "ローカルファイル",
112
+ "public_data": "公開データセット",
113
+ "data_source_type": "データソースの種類:{{sourceType}}",
114
+ "file": {
115
+ "open": "開く...",
116
+ "submit": "提出する",
117
+ "dataset_name": "データセット名",
118
+ "choose_file": "データファイルを選択してください",
119
+ "get_start_desc": "データセットの作成を始めましょう。"
120
+ },
121
+ "public": {
122
+ "submit": "提出する"
123
+ }
114
124
  }
115
- }
116
125
  },
117
126
  "main": {
118
- "tablist": {
119
- "new": "+ 新規作成",
120
- "auto_title": "グラフ {{idx}}",
121
- "chart_name": "グラフ名"
122
- },
123
- "tabpanel": {
124
- "menubar": {
125
- "undo": "元に戻す",
126
- "redo": "やり直し"
127
- },
128
- "settings": {
129
- "toggle": {
130
- "aggregation": "集計",
131
- "stack": "スタック",
132
- "axes_resize": "軸のサイズ変更",
133
- "debug": "デバッグ"
134
- },
135
- "sort": "並べ替えの順序",
136
- "button": {
137
- "ascending": "昇順に並べ替える",
138
- "descending": "降順に並べ替える",
139
- "transpose": "転置",
140
- "export_chart": "エクスポート",
141
- "export_chart_as": "{{type}}としてエクスポート"
142
- },
143
- "size": "サイズ変更",
144
- "size_setting": {
145
- "width": "幅",
146
- "height": "高さ"
147
- }
127
+ "tablist": {
128
+ "new": "+ 新規作成",
129
+ "auto_title": "グラフ {{idx}}",
130
+ "chart_name": "グラフ名"
148
131
  },
149
- "DatasetFields": {
150
- "field_list": "フィールド一覧"
132
+ "tabpanel": {
133
+ "menubar": {
134
+ "undo": "元に戻す",
135
+ "redo": "やり直し"
136
+ },
137
+ "settings": {
138
+ "toggle": {
139
+ "aggregation": "集計",
140
+ "stack": "スタック",
141
+ "axes_resize": "軸のサイズ変更",
142
+ "debug": "デバッグ"
143
+ },
144
+ "sort": "並べ替えの順序",
145
+ "button": {
146
+ "ascending": "昇順に並べ替える",
147
+ "descending": "降順に並べ替える",
148
+ "transpose": "転置",
149
+ "export_chart": "エクスポート",
150
+ "export_chart_as": "{{type}}としてエクスポート"
151
+ },
152
+ "size": "サイズ変更",
153
+ "size_setting": {
154
+ "width": "幅",
155
+ "height": "高さ"
156
+ }
157
+ },
158
+ "DatasetFields": {
159
+ "field_list": "フィールド一覧"
160
+ }
151
161
  }
152
- }
153
162
  },
154
163
  "filters": {
155
- "to_edit": "このルールを編集",
156
- "empty_rule": "! (空のルール)",
157
- "editing": "ルールを編集",
158
- "form": {
159
- "name": "フィールド",
160
- "rule": "ルール"
161
- },
162
- "header": {
163
- "visibility": "表示",
164
- "value": "ラベル",
165
- "count": "件数"
166
- },
167
- "selected_keys": "{{ count }}件が選択されました",
168
- "btn": {
169
- "select_all": "すべて選択",
170
- "unselect_all": "すべての選択を解除",
171
- "reverse": "選択を反転する",
172
- "confirm": "確認",
173
- "cancel": "キャンセル"
174
- }
164
+ "to_edit": "このルールを編集",
165
+ "empty_rule": "! (空のルール)",
166
+ "editing": "ルールを編集",
167
+ "form": {
168
+ "name": "フィールド",
169
+ "rule": "ルール"
170
+ },
171
+ "header": {
172
+ "visibility": "表示",
173
+ "value": "ラベル",
174
+ "count": "件数"
175
+ },
176
+ "selected_keys": "{{ count }}件が選択されました",
177
+ "btn": {
178
+ "select_all": "すべて選択",
179
+ "unselect_all": "すべての選択を解除",
180
+ "reverse": "選択を反転する",
181
+ "confirm": "確認",
182
+ "cancel": "キャンセル"
183
+ }
175
184
  },
176
185
  "explain": {
177
- "lg_than": "より大きい",
178
- "sm_than": "より小さい",
179
- "expection": "期待値",
180
- "unrecognized": "未認識",
181
- "score": "スコア",
182
- "contains": "を含む",
183
- "reason": {
184
- "selection_dim_distribution": "次元のヒント",
185
- "selection_mea_distribution": "尺度のヒント",
186
- "children_major_factor": "主要要因",
187
- "children_outlier": "外れ値"
188
- }
186
+ "lg_than": "より大きい",
187
+ "sm_than": "より小さい",
188
+ "expection": "期待値",
189
+ "unrecognized": "未認識",
190
+ "score": "スコア",
191
+ "contains": "を含む",
192
+ "reason": {
193
+ "selection_dim_distribution": "次元のヒント",
194
+ "selection_mea_distribution": "尺度のヒント",
195
+ "children_major_factor": "主要要因",
196
+ "children_outlier": "外れ値"
197
+ }
189
198
  },
190
199
  "actions": {
191
- "prev": "前へ",
192
- "next": "次へ",
193
- "drop_field": "ここにフィールドをドロップ",
194
- "confirm": "確認",
195
- "cancel": "キャンセル"
200
+ "prev": "前へ",
201
+ "next": "次へ",
202
+ "drop_field": "ここにフィールドをドロップ",
203
+ "confirm": "確認",
204
+ "cancel": "キャンセル"
196
205
  }
197
- }
206
+ }
@@ -1,4 +1,10 @@
1
1
  {
2
+ "config": {
3
+ "format": "格式",
4
+ "numberFormat": "数字格式",
5
+ "timeFormat": "时间格式",
6
+ "normalizedNumberFormat": "标准化数字格式"
7
+ },
2
8
  "constant": {
3
9
  "row_count": "行数",
4
10
  "analytic_type": {
@@ -23,7 +29,9 @@
23
29
  "tick": "标记",
24
30
  "rect": "矩形",
25
31
  "arc": "弧形",
26
- "boxplot": "统计箱"
32
+ "boxplot": "统计箱",
33
+ "table": "表格",
34
+ "text": "文本"
27
35
  },
28
36
  "layout_type": {
29
37
  "__enum__": "尺寸模式",
@@ -59,7 +67,8 @@
59
67
  "theta": "角度",
60
68
  "radius": "半径",
61
69
  "filters": "筛选器",
62
- "details": "信息"
70
+ "details": "信息",
71
+ "text": "文本"
63
72
  },
64
73
  "aggregator": {
65
74
  "sum": "求和",
@@ -8,6 +8,8 @@ import { useGlobalStore } from '../store';
8
8
  import { IReactVegaHandler } from '../vis/react-vega';
9
9
  import { unstable_batchedUpdates } from 'react-dom';
10
10
  import { initEncoding, initVisualConfig } from '../store/visualSpecStore';
11
+ import PivotTable from '../components/pivotTable';
12
+ import { getMeaAggKey } from '../utils';
11
13
 
12
14
  interface RendererProps {
13
15
  themeKey?: IThemeKey;
@@ -24,7 +26,6 @@ const Renderer = forwardRef<IReactVegaHandler, RendererProps>(function (props, r
24
26
  const [encodings, setEncodings] = useState<DeepReadonly<DraggableFieldState>>(initEncoding);
25
27
 
26
28
  const [viewData, setViewData] = useState<IRow[]>([]);
27
-
28
29
  useEffect(() => {
29
30
  setWaiting(true);
30
31
  applyFilter(dataSource, viewFilters)
@@ -37,7 +38,7 @@ const Renderer = forwardRef<IReactVegaHandler, RendererProps>(function (props, r
37
38
  return applyViewQuery(d, dims.concat(meas), {
38
39
  op: config.defaultAggregated ? 'aggregate' : 'raw',
39
40
  groupBy: dims.map((f) => f.fid),
40
- agg: Object.fromEntries(meas.map((f) => [f.fid, f.aggName as any])),
41
+ measures: meas.map((f) => ({ field: f.fid, agg: f.aggName as any, asFieldKey: getMeaAggKey(f.fid, f.aggName!) })),
41
42
  });
42
43
  })
43
44
  .then((data) => {
@@ -54,6 +55,19 @@ const Renderer = forwardRef<IReactVegaHandler, RendererProps>(function (props, r
54
55
  });
55
56
  }, [dataSource, viewFilters, allFields, viewDimensions, viewMeasures]);
56
57
 
58
+ if (viewConfig.geoms.includes('table')) {
59
+ return (
60
+ <PivotTable
61
+ data={viewData}
62
+ draggableFieldState={encodings}
63
+ visualConfig={viewConfig}
64
+ loading={waiting}
65
+ themeKey={themeKey}
66
+ dark={dark}
67
+ />
68
+ );
69
+ }
70
+
57
71
  return (
58
72
  <SpecRenderer
59
73
  loading={waiting}
@@ -1,4 +1,4 @@
1
- import { runInAction } from 'mobx';
1
+ import { runInAction, toJS } from 'mobx';
2
2
  import { Resizable } from 're-resizable';
3
3
  import React, { useCallback, forwardRef, useMemo } from 'react';
4
4
 
@@ -21,7 +21,7 @@ const SpecRenderer = forwardRef<IReactVegaHandler, SpecRendererProps>(function (
21
21
  ) {
22
22
  const { vizStore, commonStore } = useGlobalStore();
23
23
  // const { draggableFieldState, visualConfig } = vizStore;
24
- const { geoms, interactiveScale, defaultAggregated, stack, showActions, size } = visualConfig;
24
+ const { geoms, interactiveScale, defaultAggregated, stack, showActions, size, format: _format } = visualConfig;
25
25
 
26
26
  const rows = draggableFieldState.rows;
27
27
  const columns = draggableFieldState.columns;
@@ -32,6 +32,8 @@ const SpecRenderer = forwardRef<IReactVegaHandler, SpecRendererProps>(function (
32
32
  const radius = draggableFieldState.radius;
33
33
  const sizeChannel = draggableFieldState.size;
34
34
  const details = draggableFieldState.details;
35
+ const text = draggableFieldState.text;
36
+ const format = toJS(_format)
35
37
 
36
38
  const rowLeftFacetFields = useMemo(() => rows.slice(0, -1).filter((f) => f.analyticType === 'dimension'), [rows]);
37
39
  const colLeftFacetFields = useMemo(
@@ -85,6 +87,7 @@ const SpecRenderer = forwardRef<IReactVegaHandler, SpecRendererProps>(function (
85
87
  >
86
88
  {loading && <LoadingLayer />}
87
89
  <ReactVega
90
+ format={format}
88
91
  layoutMode={size.mode}
89
92
  interactiveScale={interactiveScale}
90
93
  geomType={geoms[0]}
@@ -100,6 +103,7 @@ const SpecRenderer = forwardRef<IReactVegaHandler, SpecRendererProps>(function (
100
103
  opacity={opacity[0]}
101
104
  size={sizeChannel[0]}
102
105
  details={details}
106
+ text={text[0]}
103
107
  showActions={showActions}
104
108
  width={size.width - 12 * 4}
105
109
  height={size.height - 12 * 4}
@@ -14,6 +14,7 @@ export class CommonStore {
14
14
  public vizEmbededMenu: { show: boolean; position: [number, number] } = { show: false, position: [0, 0] };
15
15
  public showDataConfig: boolean = false;
16
16
  public showCodeExportPanel: boolean = false;
17
+ public showVisualConfigPanel: boolean = false;
17
18
  public filters: Filters = {};
18
19
  public segmentKey: ISegmentKey = ISegmentKey.vis;
19
20
  constructor () {
@@ -64,6 +65,9 @@ export class CommonStore {
64
65
  public setShowCodeExportPanel (show: boolean) {
65
66
  this.showCodeExportPanel = show;
66
67
  }
68
+ public setShowVisualConfigPanel (show: boolean) {
69
+ this.showVisualConfigPanel = show;
70
+ }
67
71
  public closeEmbededMenu () {
68
72
  this.vizEmbededMenu.show = false;
69
73
  }
@@ -58,6 +58,7 @@ export function initEncoding(): DraggableFieldState {
58
58
  theta: [],
59
59
  details: [],
60
60
  filters: [],
61
+ text: [],
61
62
  };
62
63
  }
63
64
 
@@ -74,6 +75,11 @@ export function initVisualConfig(): IVisualConfig {
74
75
  width: 320,
75
76
  height: 200,
76
77
  },
78
+ format: {
79
+ numberFormat: undefined,
80
+ timeFormat: undefined,
81
+ normalizedNumberFormat: undefined
82
+ }
77
83
  };
78
84
  }
79
85
 
@@ -368,6 +374,9 @@ export class VizSpecStore {
368
374
  case configKey === "stack": {
369
375
  return (config[configKey] = value);
370
376
  }
377
+ case configKey === 'format' && typeof value === "object": {
378
+ return config[configKey] = value
379
+ }
371
380
  default: {
372
381
  console.error("unknown key" + configKey);
373
382
  }
@@ -619,6 +628,9 @@ export class VizSpecStore {
619
628
  encodings[destinationKey].push(cloneField);
620
629
  });
621
630
  }
631
+ public setVizFormatConfig (formatKey: keyof IVisualConfig['format'], value?: string) {
632
+ this.visualConfig[formatKey] = value
633
+ }
622
634
  public renderSpec(spec: Specification) {
623
635
  const tab = this.visList[this.visIndex];
624
636
 
@@ -275,4 +275,11 @@ export function makeNumbersBeautiful (nums: number[]): number[] {
275
275
 
276
276
  export function classNames(...classes: string[]) {
277
277
  return classes.filter(Boolean).join(' ')
278
+ }
279
+
280
+ export function getMeaAggKey (meaKey: string, agg?: string | undefined) {
281
+ if (!agg) {
282
+ return meaKey;
283
+ }
284
+ return `${meaKey}_${agg}`;
278
285
  }