@orbcharts/core 3.0.0-alpha.35 → 3.0.0-alpha.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. package/dist/orbcharts-core.es.js +1754 -1666
  2. package/dist/orbcharts-core.umd.js +2 -2
  3. package/dist/src/series/seriesObservables.d.ts +1 -8
  4. package/dist/src/tree/treeObservables.d.ts +13 -0
  5. package/dist/src/types/ChartParams.d.ts +1 -1
  6. package/dist/src/types/ComputedData.d.ts +13 -0
  7. package/dist/src/types/ComputedDataGrid.d.ts +2 -5
  8. package/dist/src/types/ComputedDataMultiValue.d.ts +2 -2
  9. package/dist/src/types/ComputedDataRelationship.d.ts +2 -2
  10. package/dist/src/types/ComputedDataTree.d.ts +2 -2
  11. package/dist/src/types/ContextObserverTree.d.ts +6 -0
  12. package/dist/src/types/DataFormatterMultiGrid.d.ts +1 -3
  13. package/dist/src/types/DataFormatterMultiValue.d.ts +0 -1
  14. package/dist/src/types/DataFormatterSeries.d.ts +0 -2
  15. package/dist/src/types/DataFormatterTree.d.ts +1 -0
  16. package/dist/src/types/DataMultiValue.d.ts +1 -0
  17. package/dist/src/types/DataRelationship.d.ts +1 -0
  18. package/dist/src/types/DataTree.d.ts +2 -0
  19. package/dist/src/types/Event.d.ts +9 -1
  20. package/dist/src/utils/observables.d.ts +7 -4
  21. package/package.json +1 -1
  22. package/src/base/createBaseChart.ts +0 -1
  23. package/src/defaults.ts +5 -3
  24. package/src/multiValue/computeMultiValueData.ts +7 -2
  25. package/src/relationship/computeRelationshipData.ts +3 -0
  26. package/src/series/createSeriesContextObserver.ts +1 -1
  27. package/src/series/seriesObservables.ts +8 -7
  28. package/src/tree/computeTreeData.ts +31 -9
  29. package/src/tree/createTreeContextObserver.ts +44 -0
  30. package/src/tree/treeObservables.ts +95 -0
  31. package/src/types/ChartParams.ts +1 -1
  32. package/src/types/ComputedData.ts +18 -1
  33. package/src/types/ComputedDataGrid.ts +5 -5
  34. package/src/types/ComputedDataMultiValue.ts +2 -3
  35. package/src/types/ComputedDataRelationship.ts +2 -2
  36. package/src/types/ComputedDataTree.ts +2 -2
  37. package/src/types/ContextObserverTree.ts +6 -1
  38. package/src/types/DataFormatterMultiGrid.ts +2 -2
  39. package/src/types/DataFormatterMultiValue.ts +1 -1
  40. package/src/types/DataFormatterSeries.ts +2 -2
  41. package/src/types/DataFormatterTree.ts +1 -0
  42. package/src/types/DataMultiValue.ts +1 -0
  43. package/src/types/DataRelationship.ts +1 -0
  44. package/src/types/DataTree.ts +2 -0
  45. package/src/types/Event.ts +9 -1
  46. package/src/utils/d3Utils.ts +16 -13
  47. package/src/utils/observables.ts +60 -77
@@ -24,5 +24,18 @@ export interface ComputedDatumSeriesValue {
24
24
  seriesIndex: number;
25
25
  seriesLabel: string;
26
26
  }
27
+ export interface ComputedDatumGridValue {
28
+ gridIndex: number;
29
+ color: string;
30
+ seriesIndex: number;
31
+ seriesLabel: string;
32
+ groupIndex: number;
33
+ groupLabel: string;
34
+ }
35
+ export interface ComputedDatumCategoryValue {
36
+ color: string;
37
+ categoryIndex: number;
38
+ categoryLabel: string | null;
39
+ }
27
40
  export type ComputedDataTypeMap<T extends ChartType> = T extends 'series' ? ComputedDataSeries : T extends 'grid' ? ComputedDataGrid : T extends 'multiGrid' ? ComputedDataMultiGrid : T extends 'multiValue' ? ComputedDataMultiValue : T extends 'relationship' ? ComputedDataRelationship : T extends 'tree' ? ComputedDataTree : ComputedDatumBase;
28
41
  export type ComputedDatumTypeMap<T extends ChartType> = T extends 'series' ? ComputedDatumSeries : T extends 'grid' ? ComputedDatumGrid : T extends 'multiGrid' ? ComputedDatumGrid : T extends 'multiValue' ? ComputedDatumMultiValue : T extends 'relationship' ? ComputedNode : T extends 'tree' ? ComputedDataTree : unknown;
@@ -1,9 +1,6 @@
1
- import { ComputedDatumBase, ComputedDatumSeriesValue } from './ComputedData';
1
+ import { ComputedDatumBase, ComputedDatumGridValue } from './ComputedData';
2
2
 
3
- export interface ComputedDatumGrid extends ComputedDatumBase, ComputedDatumSeriesValue {
4
- gridIndex: number;
5
- groupIndex: number;
6
- groupLabel: string;
3
+ export interface ComputedDatumGrid extends ComputedDatumBase, ComputedDatumGridValue {
7
4
  axisX: number;
8
5
  axisY: number;
9
6
  axisYFromZero: number;
@@ -1,6 +1,6 @@
1
- import { ComputedDatumBase } from './ComputedData';
1
+ import { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData';
2
2
 
3
3
  export type ComputedDataMultiValue = ComputedDatumMultiValue[][];
4
- export interface ComputedDatumMultiValue extends ComputedDatumBase {
4
+ export interface ComputedDatumMultiValue extends ComputedDatumBase, ComputedDatumCategoryValue {
5
5
  axis: number;
6
6
  }
@@ -1,10 +1,10 @@
1
- import { ComputedDatumBase } from './ComputedData';
1
+ import { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData';
2
2
 
3
3
  export type ComputedDataRelationship = {
4
4
  nodes: ComputedNode[];
5
5
  edges: ComputedEdge[];
6
6
  };
7
- export interface ComputedNode extends ComputedDatumBase {
7
+ export interface ComputedNode extends ComputedDatumBase, ComputedDatumCategoryValue {
8
8
  startNodes: ComputedNode[];
9
9
  startNodeIds: string[];
10
10
  endNodes: ComputedNode[];
@@ -1,6 +1,6 @@
1
- import { ComputedDatumBase } from './ComputedData';
1
+ import { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData';
2
2
 
3
- export interface ComputedDataTree extends ComputedDatumBase {
3
+ export interface ComputedDataTree extends ComputedDatumBase, ComputedDatumCategoryValue {
4
4
  level: number;
5
5
  seq: number;
6
6
  children?: ComputedDataTree[];
@@ -1,4 +1,10 @@
1
+ import { Observable } from 'rxjs';
1
2
  import { ContextObserverBase } from './ContextObserver';
3
+ import { ComputedDataTree } from './ComputedDataTree';
2
4
 
3
5
  export interface ContextObserverTree<PluginParams> extends ContextObserverBase<'tree', PluginParams> {
6
+ treeHighlight$: Observable<string[]>;
7
+ existCategoryLabels$: Observable<string[]>;
8
+ CategoryDataMap$: Observable<Map<string, ComputedDataTree[]>>;
9
+ visibleComputedData$: Observable<ComputedDataTree>;
4
10
  }
@@ -1,13 +1,11 @@
1
- import { VisibleFilter, DataFormatterBase, DataFormatterBasePartial } from './DataFormatter';
2
1
  import { DataFormatterGridGrid, DataFormatterGridGridPartial, DataFormatterGridContainer } from './DataFormatterGrid';
2
+ import { DataFormatterBase, DataFormatterBasePartial } from './DataFormatter';
3
3
 
4
4
  export interface DataFormatterMultiGrid extends DataFormatterBase<'multiGrid'> {
5
- visibleFilter: VisibleFilter<'multiGrid'>;
6
5
  gridList: Array<DataFormatterGridGrid>;
7
6
  container: DataFormatterMultiGridContainer;
8
7
  }
9
8
  export interface DataFormatterMultiGridPartial extends DataFormatterBasePartial<'multiGrid'> {
10
- visibleFilter?: VisibleFilter<'multiGrid'>;
11
9
  gridList?: Array<DataFormatterGridGridPartial>;
12
10
  container?: Partial<DataFormatterMultiGridContainer>;
13
11
  }
@@ -12,5 +12,4 @@ export interface DataFormatterMultiValuePartial extends DataFormatterBasePartial
12
12
  yAxis?: Partial<DataFormatterValueAxis>;
13
13
  }
14
14
  export interface DataFormatterMultiValueMultiValue {
15
- unitLabel: string;
16
15
  }
@@ -3,12 +3,10 @@ import { DataFormatterBase, DataFormatterBasePartial, VisibleFilter } from './Da
3
3
 
4
4
  export interface DataFormatterSeries extends DataFormatterBase<'series'> {
5
5
  visibleFilter: VisibleFilter<'series'>;
6
- unitLabel: string;
7
6
  seriesLabels: string[];
8
7
  sort: ((a: DataSeriesDatum | DataSeriesValue, b: DataSeriesDatum | number) => number) | null;
9
8
  }
10
9
  export interface DataFormatterSeriesPartial extends DataFormatterBasePartial<'series'> {
11
- unitLabel?: string;
12
10
  seriesLabels?: string[];
13
11
  sort?: ((a: DataSeriesDatum | DataSeriesValue, b: DataSeriesDatum | number) => number) | null;
14
12
  }
@@ -2,5 +2,6 @@ import { DataFormatterBase, VisibleFilter } from './DataFormatter';
2
2
 
3
3
  export interface DataFormatterTree extends DataFormatterBase<'tree'> {
4
4
  visibleFilter: VisibleFilter<'tree'>;
5
+ categoryLabels: string[];
5
6
  }
6
7
  export type DataFormatterTreePartial = Partial<DataFormatterTree>;
@@ -3,4 +3,5 @@ import { DatumBase, DatumValue } from './Data';
3
3
  export type DataMultiValue = (DataMultiValueDatum | DataMultiValueValue)[][];
4
4
  export type DataMultiValueValue = number;
5
5
  export interface DataMultiValueDatum extends DatumBase, DatumValue {
6
+ categoryLabel?: string;
6
7
  }
@@ -12,6 +12,7 @@ export type DataRelationshipList = [
12
12
  export interface Node extends DatumBase {
13
13
  id: string;
14
14
  value?: number;
15
+ categoryLabel?: string;
15
16
  }
16
17
  export interface Edge extends DatumBase {
17
18
  start: string;
@@ -5,9 +5,11 @@ export interface DataTreeObj extends DatumBase {
5
5
  id: string;
6
6
  value?: number;
7
7
  children?: DataTreeObj[];
8
+ categoryLabel?: string;
8
9
  }
9
10
  export interface DataTreeDatum extends DatumBase {
10
11
  id: string;
11
12
  value?: number;
12
13
  parent?: string;
14
+ categoryLabel?: string;
13
15
  }
@@ -4,7 +4,7 @@ import { ComputedDataSeries, ComputedDatumSeries } from './ComputedDataSeries';
4
4
  import { ComputedDataGrid, ComputedDatumGrid } from './ComputedDataGrid';
5
5
  import { ComputedDataMultiGrid } from './ComputedDataMultiGrid';
6
6
  import { ComputedDatumMultiValue } from './ComputedDataMultiValue';
7
- import { ComputedNode } from './ComputedDataRelationship';
7
+ import { ComputedDataRelationship, ComputedNode } from './ComputedDataRelationship';
8
8
  import { ComputedDataTree } from './ComputedDataTree';
9
9
  import { HighlightTarget } from './ChartParams';
10
10
 
@@ -56,9 +56,17 @@ export interface EventMultiValue extends EventBase {
56
56
  }
57
57
  export interface EventRelationship extends EventBase {
58
58
  type: 'relationship';
59
+ data: ComputedDataRelationship;
60
+ category: ComputedNode[];
61
+ categoryIndex: number;
62
+ categoryLabel: string;
59
63
  datum: ComputedNode | null;
60
64
  }
61
65
  export interface EventTree extends EventBase {
62
66
  type: 'tree';
67
+ data: ComputedDataTree;
68
+ category: ComputedDataTree[];
69
+ categoryIndex: number;
70
+ categoryLabel: string;
63
71
  datum: ComputedDataTree | null;
64
72
  }
@@ -1,14 +1,17 @@
1
1
  import { Subject, Observable } from 'rxjs';
2
- import { ChartType, ChartParams, ComputedDatumTypeMap } from '../types';
2
+ import { ChartParams, ComputedDatumTypeMap } from '../types';
3
3
 
4
4
  export declare const highlightObservable: ({ datumList$, fullChartParams$, event$ }: {
5
- datumList$: Observable<ComputedDatumTypeMap<"series" | "grid">[]>;
5
+ datumList$: Observable<ComputedDatumTypeMap<"series" | "grid" | "multiValue" | "relationship" | "tree">[]>;
6
6
  fullChartParams$: Observable<ChartParams>;
7
7
  event$: Subject<any>;
8
8
  }) => Observable<string[]>;
9
- export declare const seriesDataMapObservable: <DatumType extends ComputedDatumTypeMap<ChartType>>({ datumList$ }: {
9
+ export declare const seriesDataMapObservable: <DatumType extends ComputedDatumTypeMap<"series" | "grid">>({ datumList$ }: {
10
10
  datumList$: Observable<DatumType[]>;
11
11
  }) => Observable<Map<string, DatumType[]>>;
12
- export declare const groupDataMapObservable: <DatumType extends ComputedDatumTypeMap<ChartType>>({ datumList$ }: {
12
+ export declare const groupDataMapObservable: <DatumType extends ComputedDatumTypeMap<"grid">>({ datumList$ }: {
13
+ datumList$: Observable<DatumType[]>;
14
+ }) => Observable<Map<string, DatumType[]>>;
15
+ export declare const categoryDataMapObservable: <DatumType extends ComputedDatumTypeMap<"multiValue" | "relationship" | "tree">>({ datumList$ }: {
13
16
  datumList$: Observable<DatumType[]>;
14
17
  }) => Observable<Map<string, DatumType[]>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbcharts/core",
3
- "version": "3.0.0-alpha.35",
3
+ "version": "3.0.0-alpha.37",
4
4
  "description": "OrbCharts is an open source chart library based on d3.js and rx.js",
5
5
  "author": "Blue Planet Inc.",
6
6
  "license": "Apache-2.0",
@@ -94,7 +94,6 @@ function mergeDataFormatter <T>(dataFormatter: any, defaultDataFormatter: T, cha
94
94
  return mergeOptionsWithDefault(d, defaultGrid)
95
95
  })
96
96
  }
97
- console.log(mergedData)
98
97
  return mergedData
99
98
  }
100
99
 
package/src/defaults.ts CHANGED
@@ -58,7 +58,8 @@ export const CHART_PARAMS_DEFAULT: ChartParams = {
58
58
  colors: {
59
59
  light: {
60
60
  series: ['#67B7DC', '#6794DC', '#6771DC', '#8067DC', '#A367DC', '#C767DC', '#DC67CE', '#DC67AB', '#DC6788', '#DC6967', '#DC8C67', '#DCAF67'],
61
- primary: '#454545',
61
+ // primary: '#454545',
62
+ primary: '#1b1e23',
62
63
  secondary: '#e1e1e1',
63
64
  white: '#ffffff',
64
65
  background: '#ffffff'
@@ -139,7 +140,7 @@ export const DATA_FORMATTER_SERIES_DEFAULT: DataFormatterSeries = {
139
140
  // ...DATA_FORMATTER_WITH_VALUE,
140
141
  type: 'series',
141
142
  visibleFilter: (datum, rowIndex, columnIndex, context) => true,
142
- unitLabel: '',
143
+ // unitLabel: '',
143
144
  seriesLabels: [],
144
145
  // mapSeries: (datum, rowIndex, columnIndex, { data, dataFormatter }) => {
145
146
  // const seriesIndex = rowIndex >= dataFormatter.seriesLabels.length
@@ -200,7 +201,7 @@ export const DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT: DataFormatterMultiGridGrid
200
201
 
201
202
  export const DATA_FORMATTER_MULTI_GRID_DEFAULT: DataFormatterMultiGrid = {
202
203
  type: 'multiGrid',
203
- visibleFilter: (datum, rowIndex, columnIndex, context) => true,
204
+ // visibleFilter: (datum, rowIndex, columnIndex, context) => true,
204
205
  gridList: [
205
206
  {
206
207
  ...DATA_FORMATTER_MULTI_GRID_GRID_DEFAULT
@@ -226,6 +227,7 @@ export const DATA_FORMATTER_TREE_DEFAULT: DataFormatterTree = {
226
227
  type: 'tree',
227
228
  visibleFilter: (datum, rowIndex, columnIndex, context) => true,
228
229
  // labelFormat: (datum: any) => (datum && datum.label) ?? '',
230
+ categoryLabels: []
229
231
  }
230
232
 
231
233
  export const DATA_FORMATTER_RELATIONAL_DEFAULT: DataFormatterRelationship = {
@@ -24,6 +24,7 @@ export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) =>
24
24
  description: '',
25
25
  // tooltipContent: '',
26
26
  data: {},
27
+ categoryLabel: '',
27
28
  value: _d
28
29
  }
29
30
  : {
@@ -32,6 +33,7 @@ export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) =>
32
33
  description: _d.description ?? '',
33
34
  // tooltipContent: _d.tooltipContent ?? '',
34
35
  data: _d.data ?? {},
36
+ categoryLabel: _d.categoryLabel ??'',
35
37
  value: _d.value
36
38
  }
37
39
 
@@ -82,7 +84,7 @@ export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) =>
82
84
  dataFormatter.yAxis.scaleDomain[0] === 'auto' ? yMinValue : dataFormatter.yAxis.scaleDomain[0],
83
85
  dataFormatter.yAxis.scaleDomain[1] === 'auto' ? yMaxValue : dataFormatter.yAxis.scaleDomain[1]
84
86
  ]
85
- debugger
87
+
86
88
  // 篩選顯示狀態
87
89
  const visibleFilter = (datum: DataMultiValueDatum, rowIndex: number, columnIndex: number, context: DataFormatterContext<"multiValue">) => {
88
90
  // 如果不在scale的範圍內則為false,不再做visibleFilter的判斷
@@ -115,9 +117,12 @@ export const computeMultiValueData: ComputedDataFn<'multiValue'> = (context) =>
115
117
  // tooltipContent: _d.tooltipContent ? _d.tooltipContent : dataFormatter.tooltipContentFormat(_d, i, _i, context),
116
118
  data: _d.data,
117
119
  value: _d.value,
120
+ categoryIndex: 0, // @Q@ 未完成
121
+ categoryLabel: '', // @Q@ 未完成
118
122
  // valueLabel: formatValueToLabel(_d.value, dataFormatter.multiValue[_i].valueFormat),
119
123
  axis: _i == 0 ? xScale(_d.value) : yScale(_d.value),
120
- visible
124
+ visible,
125
+ color: '' // @Q@ 未完成
121
126
  }
122
127
  return computedDatum
123
128
  })
@@ -36,6 +36,9 @@ export const computeRelationshipData: ComputedDataFn<'relationship'> = (context)
36
36
  // tooltipContent: node.tooltipContent ? node.tooltipContent : dataFormatter.tooltipContentFormat(node, 0, i, context), // 0代表node
37
37
  data: node.data ?? {},
38
38
  value: node.value ?? 0,
39
+ categoryIndex: 0, // @Q@ 未完成
40
+ categoryLabel: '', // @Q@ 未完成
41
+ color: '', // @Q@ 未完成
39
42
  startNodes: [], // 後面再取得資料
40
43
  startNodeIds: [], // 後面再取得資料
41
44
  endNodes: [], // 後面再取得資料
@@ -1,9 +1,9 @@
1
1
  import { shareReplay } from 'rxjs'
2
2
  import type { ContextObserverFn } from '../types'
3
3
  import {
4
- highlightObservable,
5
4
  seriesDataMapObservable,
6
5
  groupDataMapObservable } from '../utils/observables'
6
+ import { highlightObservable } from '../utils/observables'
7
7
 
8
8
  export const createSeriesContextObserver: ContextObserverFn<'series'> = ({ subject, observer }) => {
9
9
 
@@ -11,13 +11,14 @@ import {
11
11
  Observable } from 'rxjs'
12
12
  import type {
13
13
  ChartParams,
14
+ ComputedDatumSeries,
14
15
  ComputedDataTypeMap } from '../types'
15
16
  import { highlightObservable } from '../utils/observables'
16
17
 
17
- export const seriesHighlightObservable = ({ computedData$, fullChartParams$, event$ }: {
18
- computedData$: Observable<ComputedDataTypeMap<'series'>>
19
- fullChartParams$: Observable<ChartParams>
20
- event$: Subject<any>
21
- }): Observable<string[]> => {
22
- return highlightObservable ({ datumList$: computedData$, fullChartParams$, event$ })
23
- }
18
+ // export const seriesHighlightObservable = ({ computedData$, fullChartParams$, event$ }: {
19
+ // computedData$: Observable<ComputedDataTypeMap<'series'>>
20
+ // fullChartParams$: Observable<ChartParams>
21
+ // event$: Subject<any>
22
+ // }): Observable<string[]> => {
23
+ // return highlightObservable ({ datumList$: computedData$, fullChartParams$, event$ })
24
+ // }
@@ -2,15 +2,24 @@ import type { DataTree, DataTreeObj, DataTreeDatum } from '../types/DataTree'
2
2
  import type { ComputedDataFn } from '../types/ComputedData'
3
3
  import type { ComputedDataTree } from '../types/ComputedDataTree'
4
4
  import { isPlainObject } from '../utils/commonUtils'
5
+ import { seriesColorPredicate } from '../utils/orbchartsUtils'
5
6
 
6
7
  export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
7
8
  const { data = [], dataFormatter, chartParams } = context
8
9
 
10
+ // <categoryLabel, categoryIndex>
11
+ const CategoryIndexMap = new Map<string, number>(
12
+ dataFormatter.categoryLabels.map((label, index) => [label, index])
13
+ )
14
+
9
15
  let computedBranchData: ComputedDataTree = {
10
16
  id: '',
11
17
  index: 0,
12
18
  label: '',
13
19
  description: '',
20
+ categoryIndex: 0,
21
+ categoryLabel: '',
22
+ color: '',
14
23
  visible: true,
15
24
  // tooltipContent: '',
16
25
  data: {},
@@ -56,6 +65,7 @@ export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
56
65
  data: root.data,
57
66
  // tooltipContent: root.tooltipContent,
58
67
  value: root.value,
68
+ categoryLabel: root.categoryLabel,
59
69
  children: (ChildrenMap.get(root.id) ?? []).map(d => {
60
70
  // 遞迴
61
71
  return createBranchData(d)
@@ -73,23 +83,35 @@ export const computeTreeData: ComputedDataFn<'tree'> = (context) => {
73
83
 
74
84
  let index = 0
75
85
 
76
- const formatBranchData = (branchRoot: DataTreeObj, level: number, seq: number): ComputedDataTree => {
86
+ const formatBranchData = (branch: DataTreeObj, level: number, seq: number): ComputedDataTree => {
77
87
  const childLayer = level + 1
78
- const visible = dataFormatter.visibleFilter(branchRoot, level, seq, context)
88
+ const visible = dataFormatter.visibleFilter(branch, level, seq, context)
89
+ const categoryLabel: string | null = branch.categoryLabel ?? null
90
+ let categoryIndex = 0
91
+ if (categoryLabel != null) {
92
+ if (!CategoryIndexMap.has(categoryLabel)) {
93
+ CategoryIndexMap.set(categoryLabel, CategoryIndexMap.size)
94
+ }
95
+ categoryIndex = CategoryIndexMap.get(categoryLabel) ?? 0
96
+ }
97
+
79
98
  const currentIndex = index
80
99
  index++
81
100
  return {
82
- id: branchRoot.id,
101
+ id: branch.id,
83
102
  index: currentIndex,
84
103
  level,
85
104
  seq,
86
- label: branchRoot.label ?? '',
87
- description: branchRoot.description ?? '',
88
- data: branchRoot.data ?? {},
89
- // tooltipContent: branchRoot.tooltipContent ? branchRoot.tooltipContent : dataFormatter.tooltipContentFormat(branchRoot, level, seq, context),
90
- value: branchRoot.value,
105
+ label: branch.label ?? '',
106
+ description: branch.description ?? '',
107
+ categoryIndex,
108
+ categoryLabel,
109
+ color: seriesColorPredicate(categoryIndex, chartParams),
110
+ data: branch.data ?? {},
111
+ // tooltipContent: branch.tooltipContent ? branch.tooltipContent : dataFormatter.tooltipContentFormat(branch, level, seq, context),
112
+ value: branch.value,
91
113
  visible,
92
- children: (branchRoot.children ?? []).map((d, i) => {
114
+ children: (branch.children ?? []).map((d, i) => {
93
115
  // 遞迴
94
116
  return formatBranchData(d, childLayer, i)
95
117
  })
@@ -1,12 +1,56 @@
1
+ import { map, shareReplay } from 'rxjs'
1
2
  import type { ContextObserverFn } from '../types'
3
+ import { highlightObservable, categoryDataMapObservable } from '../utils/observables'
4
+ import {
5
+ nodeListObservable,
6
+ existCategoryLabelsObservable,
7
+ treeVisibleComputedDataObservable
8
+ } from './treeObservables'
2
9
 
3
10
  export const createTreeContextObserver: ContextObserverFn<'tree'> = ({ subject, observer }) => {
4
11
 
12
+ const nodeList$ = nodeListObservable({
13
+ computedData$: observer.computedData$
14
+ }).pipe(
15
+ shareReplay(1)
16
+ )
17
+
18
+ const treeHighlight$ = highlightObservable({
19
+ datumList$: nodeList$,
20
+ fullChartParams$: observer.fullChartParams$,
21
+ event$: subject.event$
22
+ }).pipe(
23
+ shareReplay(1)
24
+ )
25
+
26
+ const existCategoryLabels$ = existCategoryLabelsObservable({
27
+ nodeList$,
28
+ fullDataFormatter$: observer.fullDataFormatter$
29
+ }).pipe(
30
+ shareReplay(1)
31
+ )
32
+
33
+ const CategoryDataMap$ = categoryDataMapObservable({
34
+ datumList$: nodeList$
35
+ }).pipe(
36
+ shareReplay(1)
37
+ )
38
+
39
+ const visibleComputedData$ = treeVisibleComputedDataObservable({
40
+ computedData$: observer.computedData$
41
+ }).pipe(
42
+ shareReplay(1)
43
+ )
44
+
5
45
  return {
6
46
  fullParams$: observer.fullParams$,
7
47
  fullChartParams$: observer.fullChartParams$,
8
48
  fullDataFormatter$: observer.fullDataFormatter$,
9
49
  computedData$: observer.computedData$,
10
50
  layout$: observer.layout$,
51
+ treeHighlight$,
52
+ existCategoryLabels$,
53
+ CategoryDataMap$,
54
+ visibleComputedData$
11
55
  }
12
56
  }
@@ -0,0 +1,95 @@
1
+ import {
2
+ combineLatest,
3
+ distinctUntilChanged,
4
+ filter,
5
+ map,
6
+ merge,
7
+ takeUntil,
8
+ shareReplay,
9
+ switchMap,
10
+ Subject,
11
+ Observable } from 'rxjs'
12
+ import type {
13
+ ChartParams,
14
+ ComputedDataTree,
15
+ ComputedDataTypeMap,
16
+ DataFormatterTree } from '../types'
17
+
18
+
19
+ // 所有節點list結構
20
+ export const nodeListObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTree> }) => {
21
+ return computedData$.pipe(
22
+ map(data => {
23
+ function setNodeList (accNodeList: ComputedDataTree[], branch: ComputedDataTree) {
24
+ accNodeList.push(branch)
25
+ if (branch.children) {
26
+ branch.children.forEach(childBranch => {
27
+ accNodeList = setNodeList(accNodeList, childBranch) // 遞迴子節點
28
+ })
29
+ }
30
+ return accNodeList
31
+ }
32
+ return setNodeList([], data)
33
+ })
34
+ )
35
+ }
36
+
37
+ export const existCategoryLabelsObservable = ({ nodeList$, fullDataFormatter$ }: {
38
+ nodeList$: Observable<ComputedDataTree[]>
39
+ fullDataFormatter$: Observable<DataFormatterTree>
40
+ }) => {
41
+
42
+ const categoryLabels$ = fullDataFormatter$.pipe(
43
+ map(d => d.categoryLabels),
44
+ distinctUntilChanged((a, b) => {
45
+ return JSON.stringify(a).length === JSON.stringify(b).length
46
+ }),
47
+ )
48
+
49
+ return combineLatest({
50
+ nodeList: nodeList$,
51
+ categoryLabels: categoryLabels$
52
+ }).pipe(
53
+ switchMap(async d => d),
54
+ map(data => {
55
+ const CurrentLabelSet = new Set(data.categoryLabels)
56
+ const ExistLabelSet = new Set(
57
+ data.nodeList.filter(node => node.visible).map(node => node.categoryLabel)
58
+ )
59
+ // 加入已存在的label(data.nodeList有,但是dataFormatter.categoryLabels沒有)
60
+ Array.from(ExistLabelSet).forEach(label => {
61
+ if (!CurrentLabelSet.has(label)) {
62
+ CurrentLabelSet.add(label)
63
+ }
64
+ })
65
+ // 移除不存在的label(dataFormatter.categoryLabels有,但是data.nodeList沒有)
66
+ Array.from(CurrentLabelSet).forEach(label => {
67
+ if (!ExistLabelSet.has(label)) {
68
+ ExistLabelSet.delete(label)
69
+ }
70
+ })
71
+
72
+ return Array.from(CurrentLabelSet)
73
+ }),
74
+ distinctUntilChanged((a, b) => {
75
+ return JSON.stringify(a).length === JSON.stringify(b).length
76
+ }),
77
+ )
78
+ }
79
+
80
+ // 所有可見的節點
81
+ export const treeVisibleComputedDataObservable = ({ computedData$ }: { computedData$: Observable<ComputedDataTree> }) => {
82
+ return computedData$.pipe(
83
+ map(data => {
84
+ function filterChildren (accTree: ComputedDataTree) {
85
+ if (accTree.children) {
86
+ accTree.children = accTree.children
87
+ .filter(child => child.visible) // 篩選visible
88
+ .map(child => filterChildren(child)) // 遞迴子節點
89
+ }
90
+ return accTree
91
+ }
92
+ return filterChildren(data)
93
+ })
94
+ )
95
+ }
@@ -33,7 +33,7 @@ function test (): ChartParamsPartial {
33
33
  }
34
34
  }
35
35
 
36
- export type HighlightTarget = 'series' | 'group' | 'datum' | 'none'
36
+ export type HighlightTarget = 'series' | 'group' | 'category' | 'datum' | 'none'
37
37
 
38
38
  export interface Styles {
39
39
  textSize: number
@@ -40,13 +40,30 @@ export interface ComputedDatumBase {
40
40
  // axisY: number
41
41
  // }
42
42
 
43
- // datum - 序列顏色
43
+ // datum - 序列資料
44
44
  export interface ComputedDatumSeriesValue {
45
45
  color: string
46
46
  seriesIndex: number
47
47
  seriesLabel: string
48
48
  }
49
49
 
50
+ // datum - 矩陣資料
51
+ export interface ComputedDatumGridValue {
52
+ gridIndex: number
53
+ color: string
54
+ seriesIndex: number
55
+ seriesLabel: string
56
+ groupIndex: number
57
+ groupLabel: string
58
+ }
59
+
60
+ // datum - 類別資料
61
+ export interface ComputedDatumCategoryValue {
62
+ color: string
63
+ categoryIndex: number
64
+ categoryLabel: string | null
65
+ }
66
+
50
67
  // 透過類型選擇ComputedData
51
68
  export type ComputedDataTypeMap<T extends ChartType> = T extends 'series' ? ComputedDataSeries
52
69
  : T extends 'grid' ? ComputedDataGrid
@@ -1,11 +1,11 @@
1
- import { ComputedDatumBase, ComputedDatumSeriesValue } from './ComputedData'
1
+ import { ComputedDatumBase, ComputedDatumGridValue } from './ComputedData'
2
2
 
3
3
  export interface ComputedDatumGrid
4
- extends ComputedDatumBase, ComputedDatumSeriesValue {
4
+ extends ComputedDatumBase, ComputedDatumGridValue {
5
5
  // accSeriesIndex: number // 每一個grid累加的seriesIndex
6
- gridIndex: number
7
- groupIndex: number
8
- groupLabel: string
6
+ // gridIndex: number
7
+ // groupIndex: number
8
+ // groupLabel: string
9
9
  axisX: number
10
10
  axisY: number
11
11
  axisYFromZero: number
@@ -1,9 +1,8 @@
1
- import type { ComputedDatumBase } from './ComputedData'
1
+ import type { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData'
2
2
 
3
3
  export type ComputedDataMultiValue = ComputedDatumMultiValue[][]
4
4
 
5
- export interface ComputedDatumMultiValue
6
- extends ComputedDatumBase {
5
+ export interface ComputedDatumMultiValue extends ComputedDatumBase, ComputedDatumCategoryValue {
7
6
  axis: number
8
7
  }
9
8