@kanaries/graphic-walker 0.2.11 → 0.2.13

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 (69) 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/components/dataTable/index.d.ts +10 -0
  7. package/dist/components/dataTable/pagination.d.ts +10 -0
  8. package/dist/components/tabs/defaultTab.d.ts +14 -0
  9. package/dist/components/tabs/{pureTab.d.ts → editableTab.d.ts} +2 -2
  10. package/dist/dataSource/datasetConfig/index.d.ts +3 -0
  11. package/dist/dataSource/utils.d.ts +1 -1
  12. package/dist/graphic-walker.es.js +17347 -18050
  13. package/dist/graphic-walker.es.js.map +1 -1
  14. package/dist/graphic-walker.umd.js +140 -138
  15. package/dist/graphic-walker.umd.js.map +1 -1
  16. package/dist/index.d.ts +2 -2
  17. package/dist/interfaces.d.ts +12 -0
  18. package/dist/lib/inferMeta.d.ts +20 -0
  19. package/dist/segments/segmentNav.d.ts +3 -0
  20. package/dist/store/commonStore.d.ts +8 -2
  21. package/dist/store/index.d.ts +0 -1
  22. package/dist/store/visualSpecStore.d.ts +5 -5
  23. package/dist/utils/dataPrep.d.ts +6 -0
  24. package/dist/utils/index.d.ts +2 -2
  25. package/dist/utils/normalization.d.ts +1 -1
  26. package/dist/utils/save.d.ts +3 -3
  27. package/dist/utils/throttle.d.ts +1 -1
  28. package/dist/vis/temporalFormat.d.ts +10 -0
  29. package/package.json +1 -1
  30. package/src/App.tsx +93 -51
  31. package/src/components/button/base.ts +7 -0
  32. package/src/components/button/default.tsx +17 -0
  33. package/src/components/button/primary.tsx +17 -0
  34. package/src/components/dataTable/index.tsx +187 -0
  35. package/src/components/dataTable/pagination.tsx +44 -0
  36. package/src/components/tabs/defaultTab.tsx +43 -0
  37. package/src/components/tabs/{pureTab.tsx → editableTab.tsx} +3 -3
  38. package/src/dataSource/dataSelection/csvData.tsx +8 -10
  39. package/src/dataSource/dataSelection/index.tsx +1 -1
  40. package/src/dataSource/dataSelection/publicData.tsx +4 -4
  41. package/src/dataSource/datasetConfig/index.tsx +21 -0
  42. package/src/dataSource/index.tsx +10 -12
  43. package/src/dataSource/table.tsx +11 -142
  44. package/src/dataSource/utils.ts +30 -35
  45. package/src/fields/datasetFields/dimFields.tsx +1 -5
  46. package/src/fields/datasetFields/meaFields.tsx +1 -5
  47. package/src/fields/obComponents/obFContainer.tsx +1 -5
  48. package/src/index.tsx +3 -4
  49. package/src/interfaces.ts +14 -0
  50. package/src/lib/inferMeta.ts +88 -0
  51. package/src/locales/en-US.json +14 -0
  52. package/src/locales/zh-CN.json +14 -0
  53. package/src/main.tsx +1 -1
  54. package/src/renderer/index.tsx +1 -0
  55. package/src/segments/segmentNav.tsx +58 -0
  56. package/src/segments/visNav.tsx +2 -2
  57. package/src/store/commonStore.ts +36 -5
  58. package/src/store/index.tsx +0 -2
  59. package/src/store/visualSpecStore.ts +245 -183
  60. package/src/utils/autoMark.ts +14 -14
  61. package/src/utils/dataPrep.ts +44 -0
  62. package/src/utils/index.ts +140 -128
  63. package/src/utils/normalization.ts +59 -51
  64. package/src/utils/save.ts +22 -21
  65. package/src/utils/throttle.ts +5 -1
  66. package/src/vis/react-vega.tsx +6 -10
  67. package/src/vis/temporalFormat.ts +66 -0
  68. package/dist/pitch/dnd-offset.d.ts +0 -2
  69. package/src/pitch/dnd-offset.ts +0 -64
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ interface PaginationProps {
4
+ from: number;
5
+ to: number;
6
+ total: number;
7
+ onPrev: () => void;
8
+ onNext: () => void;
9
+ }
10
+ export default function Pagination(props: PaginationProps) {
11
+ const { from , to, total, onNext, onPrev } = props;
12
+ const { t } = useTranslation();
13
+ return (
14
+ <nav
15
+ className="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6"
16
+ aria-label="Pagination"
17
+ >
18
+ <div className="hidden sm:block">
19
+ <p className="text-sm text-gray-700">
20
+ Showing <span className="font-medium">{from}</span> to <span className="font-medium">{to}</span> of{" "}
21
+ <span className="font-medium">{total}</span> results
22
+ </p>
23
+ </div>
24
+ <div className="flex flex-1 justify-between sm:justify-end">
25
+ <button
26
+ onClick={() => {
27
+ onPrev();
28
+ }}
29
+ className="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
30
+ >
31
+ {t('actions.prev')}
32
+ </button>
33
+ <button
34
+ onClick={() => {
35
+ onNext()
36
+ }}
37
+ className="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
38
+ >
39
+ {t('actions.next')}
40
+ </button>
41
+ </div>
42
+ </nav>
43
+ );
44
+ }
@@ -0,0 +1,43 @@
1
+ import React, { ReactElement } from "react";
2
+
3
+ function classNames(...classes: string[]) {
4
+ return classes.filter(Boolean).join(' ')
5
+ }
6
+
7
+ export interface ITabOption {
8
+ label: string | ReactElement;
9
+ key: string;
10
+ }
11
+ interface DefaultProps {
12
+ tabs: ITabOption[];
13
+ selectedKey: string;
14
+ onSelected: (selectedKey: string, index: number) => void;
15
+ allowEdit?: boolean;
16
+ onEditLabel?: (label: string, index: number) => void;
17
+ }
18
+ export default function Default(props: DefaultProps) {
19
+ const { tabs, selectedKey, onSelected } = props;
20
+
21
+ return (
22
+ <div className="border-b border-gray-200 mb-2" >
23
+ <nav className="-mb-px flex space-x-8" role="tablist" aria-label="Tabs">
24
+ {tabs.map((tab, tabIndex) => (
25
+ <span
26
+ role="tab"
27
+ tabIndex={0}
28
+ onClick={() => {
29
+ onSelected(tab.key, tabIndex)
30
+ }}
31
+ key={tab.key}
32
+ className={classNames(
33
+ tab.key === selectedKey
34
+ ? 'border-indigo-500 text-indigo-600'
35
+ : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300',
36
+ 'whitespace-nowrap py-2 px-1 border-b-2 font-medium text-sm'
37
+ )}
38
+ >{tab.label}</span>
39
+ ))}
40
+ </nav>
41
+ </div>
42
+ );
43
+ }
@@ -11,14 +11,14 @@ export interface ITabOption {
11
11
  key: string;
12
12
  options?: Record<string, any>;
13
13
  }
14
- interface PureTabsProps {
14
+ interface EditableTabsProps {
15
15
  tabs: ITabOption[];
16
16
  selectedKey: string;
17
17
  onSelected: (selectedKey: string, index: number) => void;
18
18
  allowEdit?: boolean;
19
19
  onEditLabel?: (label: string, index: number) => void;
20
20
  }
21
- export default function PureTabs(props: PureTabsProps) {
21
+ export default function EditableTabs(props: EditableTabsProps) {
22
22
  const { tabs, selectedKey, onSelected, allowEdit, onEditLabel } = props;
23
23
  const [editList, setEditList] = useState<boolean[]>([]);
24
24
  const { t } = useTranslation();
@@ -66,7 +66,7 @@ export default function PureTabs(props: PureTabsProps) {
66
66
  tab.key === selectedKey
67
67
  ? "text-black bg-gray-100"
68
68
  : "text-gray-500 hover:text-gray-700",
69
- "whitespace-nowrap border-gray-200 py-1 px-2 border-t border-r border-b pr-6 text-sm cursor-pointer"
69
+ "whitespace-nowrap border-gray-200 py-1 px-2 border-r border-t border-b pr-6 text-sm cursor-pointer"
70
70
  )}
71
71
  />
72
72
  ))}
@@ -6,6 +6,8 @@ import styled from "styled-components";
6
6
  import { useGlobalStore } from "../../store";
7
7
  import { observer } from "mobx-react-lite";
8
8
  import { useTranslation } from "react-i18next";
9
+ import DefaultButton from "../../components/button/default";
10
+ import PrimaryButton from "../../components/button/primary";
9
11
 
10
12
  const Container = styled.div`
11
13
  overflow-x: auto;
@@ -44,25 +46,21 @@ const CSVData: React.FC<ICSVData> = (props) => {
44
46
  }}
45
47
  />
46
48
  <div className="mt-1 mb-1">
47
- <button
48
- className="inline-block min-w-96 text-xs mr-2 pt-1 pb-1 pl-6 pr-6 border border-gray-500 rounded-sm cursor-pointer hover:bg-gray-200"
49
+ <DefaultButton
49
50
  onClick={() => {
50
51
  if (fileRef.current) {
51
52
  fileRef.current.click();
52
53
  }
53
54
  }}
54
- >
55
- {t("open")}
56
- </button>
57
- <button
58
- className="inline-block min-w-96 text-xs mr-2 pt-1 pb-1 pl-6 pr-6 bg-black rounded-sm hover:bg-gray-500 text-white font-bold disabled:bg-gray-300"
55
+ text={t("open")}
56
+ />
57
+ <PrimaryButton
58
+ text={t("submit")}
59
59
  disabled={tmpDataSource.length === 0}
60
60
  onClick={() => {
61
61
  onSubmitData();
62
62
  }}
63
- >
64
- {t("submit")}
65
- </button>
63
+ />
66
64
  </div>
67
65
  <div className="my-2">
68
66
  <label className="block text-xs text-gray-800 mb-1 font-bold">{t("dataset_name")}</label>
@@ -3,7 +3,7 @@ import { useState } from "react";
3
3
  import CSVData from "./csvData";
4
4
  import PublicData from "./publicData";
5
5
  import { useTranslation } from "react-i18next";
6
- import PureTabs from "../../components/tabs/pureTab";
6
+ import PureTabs from "../../components/tabs/editableTab";
7
7
 
8
8
  const DataSelection: React.FC = (props) => {
9
9
  const [sourceType, setSourceType] = useState<"file" | "public">("file");
@@ -4,6 +4,7 @@ import { DemoDataAssets, PUBLIC_DATA_LIST } from '../config'
4
4
  import { useGlobalStore } from '../../store';
5
5
  import { observer } from 'mobx-react-lite';
6
6
  import { useTranslation } from 'react-i18next';
7
+ import PrimaryButton from '../../components/button/primary';
7
8
 
8
9
 
9
10
  interface IPublicDataProps {
@@ -43,12 +44,11 @@ const PublicData: React.FC<IPublicDataProps> = props => {
43
44
  }
44
45
  </div>
45
46
  <hr className="m-1" />
46
- <button className="inline-block min-w-96 text-xs mr-2 pt-1 pb-1 pl-6 pr-6 bg-black rounded-sm hover:bg-gray-500 text-white font-bold disabled:bg-gray-300"
47
+ <PrimaryButton
47
48
  disabled={tmpDataSource.length === 0}
48
49
  onClick={() => { commonStore.commitTempDS() }}
49
- >
50
- {t('submit')}
51
- </button>
50
+ text={t('submit')}
51
+ />
52
52
  <hr className="m-1" />
53
53
  <Table />
54
54
  </div>
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import DatasetTable from "../../components/dataTable";
3
+ import { observer } from "mobx-react-lite";
4
+ import { useGlobalStore } from "../../store";
5
+
6
+ const DatasetConfig: React.FC = (props) => {
7
+ const { commonStore, vizStore } = useGlobalStore();
8
+ const { currentDataset } = commonStore;
9
+ const { dataSource, rawFields } = currentDataset;
10
+ return (
11
+ <div>
12
+ <DatasetTable size={100} data={dataSource} metas={rawFields}
13
+ onMetaChange={(fid, fIndex, diffMeta) => {
14
+ commonStore.updateCurrentDatasetMetas(fid, diffMeta)
15
+ }}
16
+ />
17
+ </div>
18
+ );
19
+ };
20
+
21
+ export default observer(DatasetConfig);
@@ -8,6 +8,7 @@ import { useGlobalStore } from '../store';
8
8
  import { download } from '../utils/save';
9
9
  import GwFile from './dataSelection/gwFile';
10
10
  import DataSelection from './dataSelection';
11
+ import DefaultButton from '../components/button/default';
11
12
 
12
13
  interface DSSegmentProps {
13
14
  preWorkDone: boolean;
@@ -39,28 +40,25 @@ const DataSourceSegment: React.FC<DSSegmentProps> = props => {
39
40
  ))}
40
41
  </select>
41
42
 
42
- <button className="inline-block min-w-96 text-xs ml-2 pt-1 pb-1 pl-6 pr-6 border border-gray-500 rounded-sm hover:bg-gray-200"
43
+ <DefaultButton
44
+ text={t('DataSource.buttons.create_dataset')}
43
45
  onClick={() => { commonStore.startDSBuildingTask() }}
44
- >
45
- {t('DataSource.buttons.create_dataset')}
46
- </button>
47
- <button className="inline-block min-w-96 text-xs ml-2 pt-1 pb-1 pl-6 pr-6 border border-gray-500 rounded-sm hover:bg-gray-200"
46
+ />
47
+ <DefaultButton
48
+ text={t('DataSource.buttons.export_as_file')}
48
49
  onClick={() => {
49
50
  const res = vizStore.exportAsRaw();
50
51
  download(res, 'graphic-walker-notebook.json', 'text/plain')
51
52
  }}
52
- >
53
- {t('DataSource.buttons.export_as_file')}
54
- </button>
55
- <button className="inline-block min-w-96 text-xs ml-2 pt-1 pb-1 pl-6 pr-6 border border-gray-500 rounded-sm hover:bg-gray-200"
53
+ />
54
+ <DefaultButton
55
+ text={t('DataSource.buttons.import_file')}
56
56
  onClick={() => {
57
57
  if (gwFileRef.current) {
58
58
  gwFileRef.current.click();
59
59
  }
60
60
  }}
61
- >
62
- {t('DataSource.buttons.import_file')}
63
- </button>
61
+ />
64
62
  {showDSPanel && (
65
63
  <Modal
66
64
  title={t('DataSource.dialog.create_data_source')}
@@ -1,158 +1,27 @@
1
- import React, { useMemo } from "react";
2
- import styled from "styled-components";
1
+ import React from "react";
3
2
  import { observer } from "mobx-react-lite";
4
- import { IMutField } from "../interfaces";
5
3
  import { useGlobalStore } from "../store";
6
- import { useTranslation } from "react-i18next";
4
+ import DataTable from "../components/dataTable";
5
+ import { toJS } from "mobx";
7
6
 
8
7
  interface TableProps {
9
8
  size?: number;
10
9
  }
11
- const Container = styled.div`
12
- overflow-x: auto;
13
- table {
14
- box-sizing: content-box;
15
- border-collapse: collapse;
16
- font-size: 12px;
17
- thead {
18
- th {
19
- }
20
- th.number {
21
- border-top: 3px solid #5cdbd3;
22
- }
23
- th.text {
24
- border-top: 3px solid #69c0ff;
25
- }
26
- }
27
- tbody {
28
- td {
29
- }
30
- td.number {
31
- text-align: right;
32
- }
33
- td.text {
34
- text-align: left;
35
- }
36
- }
37
- }
38
- `;
39
- const TYPE_LIST = [
40
- {
41
- value: "dimension",
42
- label: "维度",
43
- },
44
- {
45
- value: "measure",
46
- label: "度量",
47
- },
48
- ];
49
- // function getCellType(field: IMutField): 'number' | 'text' {
50
- // return field.dataType === 'number' || field.dataType === 'integer' ? 'number' : 'text';
51
- // }
52
- function getHeaderType(field: IMutField): "number" | "text" {
53
- return field.analyticType === "dimension" ? "text" : "number";
54
- }
55
-
56
- function getHeaderClassNames(field: IMutField) {
57
- return field.analyticType === "dimension" ? "border-t-4 border-blue-400" : "border-t-4 border-teal-400";
58
- }
59
-
60
- function getSemanticColors(field: IMutField): string {
61
- switch (field.semanticType) {
62
- case "nominal":
63
- return "bg-indigo-100 text-indigo-800";
64
- case "ordinal":
65
- return "bg-purple-100 text-purple-800"
66
- case "quantitative":
67
- return "bg-green-100 text-green-800"
68
- case "temporal":
69
- return "bg-yellow-100 text-yellow-800"
70
- default:
71
- return "bg-gray-400";
72
- }
73
- }
74
10
 
75
11
  const Table: React.FC<TableProps> = (props) => {
76
12
  const { size = 10 } = props;
77
13
  const { commonStore } = useGlobalStore();
78
14
  const { tmpDSRawFields, tmpDataSource } = commonStore;
79
- const { t } = useTranslation();
80
-
81
- const analyticTypeList = useMemo<{ value: string; label: string }[]>(() => {
82
- return TYPE_LIST.map((at) => ({
83
- value: at.value,
84
- label: t(`constant.analytic_type.${at.value}`),
85
- }));
86
- }, []);
87
15
 
88
16
  return (
89
- <Container className="rounded border-gray-200 border">
90
- <table className="min-w-full divide-y divide-gray-30">
91
- <thead className="bg-gray-50">
92
- <tr className="divide-x divide-gray-200">
93
- {tmpDSRawFields.map((field, fIndex) => (
94
- <th key={field.fid} className={""}>
95
- <div
96
- className={
97
- getHeaderClassNames(field) +
98
- " whitespace-nowrap py-3.5 px-6 text-left text-xs font-semibold text-gray-900 sm:pl-6"
99
- }
100
- >
101
- <b>{field.name || field.fid}</b>
102
- <div>
103
- <select
104
- className={
105
- "px-2 py font-normal mt-2 rounded-full text-xs text-white " +
106
- (field.analyticType === "dimension" ? "bg-blue-500" : "bg-teal-500")
107
- }
108
- // className="border-b border-gray-200 bg-gray-50 pl-0 mt-2 font-light"
109
- value={field.analyticType}
110
- onChange={(e) => {
111
- commonStore.updateTempFieldAnalyticType(
112
- field.fid,
113
- e.target.value as IMutField["analyticType"]
114
- );
115
- }}
116
- >
117
- {analyticTypeList.map((type) => (
118
- <option key={type.value} value={type.value}>
119
- {type.label}
120
- </option>
121
- ))}
122
- </select>
123
- </div>
124
- <div
125
- className={
126
- "inline-block px-2.5 py-0.5 text-xs font-medium mt-1 rounded-full text-xs text-white " +
127
- getSemanticColors(field)
128
- }
129
- >
130
- {field.semanticType}
131
- </div>
132
- </div>
133
- </th>
134
- ))}
135
- </tr>
136
- </thead>
137
- <tbody className="divide-y divide-gray-200 bg-white">
138
- {tmpDataSource.slice(0, size).map((record, index) => (
139
- <tr className={"divide-x divide-gray-200 " + (index % 2 ? "bg-gray-50" : "")} key={index}>
140
- {tmpDSRawFields.map((field) => (
141
- <td
142
- key={field.fid + index}
143
- className={
144
- getHeaderType(field) +
145
- " whitespace-nowrap py-2 pl-4 pr-3 text-xs text-gray-500 sm:pl-6"
146
- }
147
- >
148
- {record[field.fid]}
149
- </td>
150
- ))}
151
- </tr>
152
- ))}
153
- </tbody>
154
- </table>
155
- </Container>
17
+ <DataTable
18
+ size={size}
19
+ metas={toJS(tmpDSRawFields)}
20
+ data={tmpDataSource}
21
+ onMetaChange={(fid, fIndex, diffMeta) => {
22
+ commonStore.updateTempDatasetMetas(fid, diffMeta);
23
+ }}
24
+ />
156
25
  );
157
26
  };
158
27
 
@@ -1,47 +1,42 @@
1
- import { IRow, IMutField } from '../interfaces';
2
- import { Insight } from 'visual-insights';
1
+ import { IRow, IMutField } from "../interfaces";
2
+ import { inferMeta } from "../lib/inferMeta";
3
+ import { guardDataKeys } from "../utils/dataPrep";
3
4
 
4
5
  export function transData(dataSource: IRow[]): {
5
6
  dataSource: IRow[];
6
- fields: IMutField[]
7
+ fields: IMutField[];
7
8
  } {
8
- if (dataSource.length === 0) return {
9
- dataSource: [],
10
- fields: []
11
- };
12
- let ans: IRow[] = [];
9
+ if (dataSource.length === 0) {
10
+ return {
11
+ dataSource: [],
12
+ fields: [],
13
+ };
14
+ }
13
15
  const keys = Object.keys(dataSource[0]);
14
- // TODO: 冗余设计,单变量统计被进行了多次重复计算。另外对于这种不完整的分析任务,不建议使用VIEngine。
15
- const vie = new Insight.VIEngine();
16
- vie.setData(dataSource)
17
- .setFields(keys.map(k => ({
16
+ const metas = inferMeta({
17
+ dataSource,
18
+ fields: keys.map((k) => ({
19
+ fid: k,
18
20
  key: k,
19
- analyticType: '?',
20
- dataType: '?',
21
- semanticType: '?'
22
- })))
23
- // TODO: 结合上面的TODO,讨论,VIEngine是否要提供不需要进行univarSelection就提供summary的接口。
24
- // 这里我们使用了一种非原API设计时期待的用法,即强制指定单变量选择时要全选字段。但我们无法阻止对变量的转换。
25
- vie.univarSelection('percent', 1);
26
- const fields = vie.fields;
27
- for (let record of dataSource) {
21
+ analyticType: "?",
22
+ semanticType: "?",
23
+ })),
24
+ });
25
+ const { safeData, safeMetas } = guardDataKeys(dataSource, metas);
26
+ const finalData: IRow[] = [];
27
+ for (let record of safeData) {
28
28
  const newRecord: IRow = {};
29
- for (let field of fields) {
30
- if (field.dataType === 'number' || field.dataType === 'integer') {
31
- newRecord[field.key] = Number(record[field.key])
29
+ for (let field of safeMetas) {
30
+ if (field.semanticType === "quantitative") {
31
+ newRecord[field.fid] = Number(record[field.fid]);
32
32
  } else {
33
- newRecord[field.key] = record[field.key]
33
+ newRecord[field.fid] = record[field.fid];
34
34
  }
35
35
  }
36
- ans.push(newRecord);
36
+ finalData.push(newRecord);
37
37
  }
38
38
  return {
39
- dataSource: ans,
40
- fields: fields.map(f => ({
41
- fid: f.key,
42
- analyticType: f.analyticType,
43
- dataType: f.dataType,
44
- semanticType: f.semanticType
45
- }))
46
- }
47
- }
39
+ dataSource: finalData,
40
+ fields: safeMetas
41
+ };
42
+ }
@@ -4,22 +4,18 @@ import { observer } from 'mobx-react-lite';
4
4
  import { useGlobalStore } from '../../store';
5
5
  import DataTypeIcon from '../../components/dataTypeIcon';
6
6
  import { FieldPill } from './fieldPill';
7
- import { fixDraggableOffset } from '../../pitch/dnd-offset';
8
7
 
9
8
  interface Props {
10
9
  provided: DroppableProvided;
11
10
  }
12
11
  const DimFields: React.FC<Props> = props => {
13
12
  const { provided } = props;
14
- const { vizStore, commonStore } = useGlobalStore();
13
+ const { vizStore } = useGlobalStore();
15
14
  const dimensions = vizStore.draggableFieldState.dimensions;
16
15
  return <div {...provided.droppableProps} ref={provided.innerRef}>
17
16
  {dimensions.map((f, index) => (
18
17
  <Draggable key={f.dragId} draggableId={f.dragId} index={index}>
19
18
  {(provided, snapshot) => {
20
- if (snapshot.isDragging && provided.draggableProps.style) {
21
- fixDraggableOffset(provided, commonStore.rootContainer)
22
- }
23
19
 
24
20
  return (
25
21
  <>
@@ -4,22 +4,18 @@ import { observer } from 'mobx-react-lite';
4
4
  import { useGlobalStore } from '../../store';
5
5
  import DataTypeIcon from '../../components/dataTypeIcon';
6
6
  import { FieldPill } from './fieldPill';
7
- import { fixDraggableOffset } from '../../pitch/dnd-offset';
8
7
 
9
8
  interface Props {
10
9
  provided: DroppableProvided;
11
10
  }
12
11
  const MeaFields: React.FC<Props> = props => {
13
12
  const { provided } = props;
14
- const { vizStore, commonStore } = useGlobalStore();
13
+ const { vizStore } = useGlobalStore();
15
14
  const measures = vizStore.draggableFieldState.measures;
16
15
  return <div {...provided.droppableProps} ref={provided.innerRef}>
17
16
  {measures.map((f, index) => (
18
17
  <Draggable key={f.dragId} draggableId={f.dragId} index={index}>
19
18
  {(provided, snapshot) => {
20
- if (snapshot.isDragging && provided.draggableProps.style) {
21
- fixDraggableOffset(provided, commonStore.rootContainer)
22
- }
23
19
  return (
24
20
  <>
25
21
  <FieldPill
@@ -8,7 +8,6 @@ import {
8
8
  } from "@kanaries/react-beautiful-dnd";
9
9
  import { IDraggableStateKey } from '../../interfaces';
10
10
  import OBPill from './obPill';
11
- import { fixDraggableOffset } from '../../pitch/dnd-offset';
12
11
 
13
12
  interface FieldContainerProps {
14
13
  provided: DroppableProvided
@@ -19,7 +18,7 @@ interface FieldContainerProps {
19
18
  }
20
19
  const OBFieldContainer: React.FC<FieldContainerProps> = props => {
21
20
  const { provided, dkey } = props;
22
- const { vizStore, commonStore } = useGlobalStore();
21
+ const { vizStore} = useGlobalStore();
23
22
  const { draggableFieldState } = vizStore;
24
23
  return <FieldsContainer
25
24
  {...provided.droppableProps}
@@ -29,9 +28,6 @@ const OBFieldContainer: React.FC<FieldContainerProps> = props => {
29
28
  {draggableFieldState[dkey.id].map((f, index) => (
30
29
  <Draggable key={f.dragId} draggableId={f.dragId} index={index}>
31
30
  {(provided, snapshot) => {
32
- if (snapshot.isDragging && provided.draggableProps.style) {
33
- fixDraggableOffset(provided, commonStore.rootContainer)
34
- }
35
31
  return (
36
32
  <OBPill dkey={dkey} fIndex={index} provided={provided} />
37
33
  );
package/src/index.tsx CHANGED
@@ -3,7 +3,7 @@ import { StyleSheetManager } from 'styled-components';
3
3
  import root from 'react-shadow';
4
4
  import { DOM } from '@kanaries/react-beautiful-dnd';
5
5
  import { observer } from 'mobx-react-lite';
6
- import App, { EditorProps } from './App';
6
+ import App, { IGWProps } from './App';
7
7
  import { StoreWrapper } from './store/index';
8
8
  import { FieldsContextWrapper } from './fields/fieldsContext';
9
9
 
@@ -14,10 +14,9 @@ import style from './index.css?inline';
14
14
 
15
15
  export const ShadowDomContext = createContext<{ root: ShadowRoot | null }>({ root: null });
16
16
 
17
- export const GraphicWalker: React.FC<EditorProps> = observer(props => {
17
+ export const GraphicWalker: React.FC<IGWProps> = observer(props => {
18
18
  const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);
19
19
  const rootRef = useRef<HTMLDivElement>(null);
20
- const fixContainer = props.fixContainer ?? false;
21
20
 
22
21
  useEffect(() => {
23
22
  if (rootRef.current) {
@@ -38,7 +37,7 @@ export const GraphicWalker: React.FC<EditorProps> = observer(props => {
38
37
  <style>{style}</style>
39
38
  {shadowRoot && (
40
39
  <StyleSheetManager target={shadowRoot}>
41
- <StoreWrapper keepAlive={props.keepAlive} rootContainer={fixContainer ? rootRef.current : null}>
40
+ <StoreWrapper keepAlive={props.keepAlive}>
42
41
  <FieldsContextWrapper>
43
42
  <ShadowDomContext.Provider value={{ root: shadowRoot }}>
44
43
  <App {...props} />
package/src/interfaces.ts CHANGED
@@ -27,6 +27,15 @@ export interface IMutField {
27
27
  analyticType: IAnalyticType;
28
28
  };
29
29
 
30
+ export interface IUncertainMutField {
31
+ fid: string;
32
+ key?: string;
33
+ name?: string;
34
+ disable?: boolean;
35
+ semanticType: ISemanticType | '?';
36
+ analyticType: IAnalyticType | '?';
37
+ }
38
+
30
39
  export interface IField {
31
40
  /**
32
41
  * fid: key in data record
@@ -169,4 +178,9 @@ export interface IVisSpec {
169
178
  readonly name?: [string, Record<string, any>?];
170
179
  readonly encodings: DeepReadonly<DraggableFieldState>;
171
180
  readonly config: DeepReadonly<IVisualConfig>;
181
+ }
182
+
183
+ export enum ISegmentKey {
184
+ vis = 'vis',
185
+ data = 'data'
172
186
  }