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

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 (45) hide show
  1. package/dist/orbcharts-core.es.js +1751 -1662
  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/defaults.ts +5 -3
  23. package/src/multiValue/computeMultiValueData.ts +7 -2
  24. package/src/relationship/computeRelationshipData.ts +3 -0
  25. package/src/series/createSeriesContextObserver.ts +1 -1
  26. package/src/series/seriesObservables.ts +8 -7
  27. package/src/tree/computeTreeData.ts +31 -9
  28. package/src/tree/createTreeContextObserver.ts +44 -0
  29. package/src/tree/treeObservables.ts +95 -0
  30. package/src/types/ChartParams.ts +1 -1
  31. package/src/types/ComputedData.ts +18 -1
  32. package/src/types/ComputedDataGrid.ts +5 -5
  33. package/src/types/ComputedDataMultiValue.ts +2 -3
  34. package/src/types/ComputedDataRelationship.ts +2 -2
  35. package/src/types/ComputedDataTree.ts +2 -2
  36. package/src/types/ContextObserverTree.ts +6 -1
  37. package/src/types/DataFormatterMultiGrid.ts +2 -2
  38. package/src/types/DataFormatterMultiValue.ts +1 -1
  39. package/src/types/DataFormatterSeries.ts +2 -2
  40. package/src/types/DataFormatterTree.ts +1 -0
  41. package/src/types/DataMultiValue.ts +1 -0
  42. package/src/types/DataRelationship.ts +1 -0
  43. package/src/types/DataTree.ts +2 -0
  44. package/src/types/Event.ts +9 -1
  45. 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.36",
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",
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
 
@@ -1,11 +1,11 @@
1
- import type { ComputedDatumBase } from './ComputedData'
1
+ import type { ComputedDatumBase, ComputedDatumCategoryValue } from './ComputedData'
2
2
 
3
3
  export type ComputedDataRelationship = {
4
4
  nodes: ComputedNode[]
5
5
  edges: ComputedEdge[]
6
6
  }
7
7
 
8
- export interface ComputedNode extends ComputedDatumBase {
8
+ export interface ComputedNode extends ComputedDatumBase, ComputedDatumCategoryValue {
9
9
  startNodes: ComputedNode[]
10
10
  startNodeIds: string[]
11
11
  endNodes: ComputedNode[]