@@ -5,33 +5,17 @@ import {
5
5
CompActionTypes ,
6
6
wrapChildAction ,
7
7
} from "openblocks-core" ;
8
- import {
9
- AxisFormatterComp ,
10
- calcXYConfig ,
11
- EchartsAxisType ,
12
- } from "./chartConfigs/cartesianAxisConfig" ;
13
- import { getPieRadiusAndCenter } from "./chartConfigs/pieChartConfig" ;
14
- import {
15
- CharOptionCompType ,
16
- chartChildrenMap ,
17
- ChartCompPropsType ,
18
- ChartSize ,
19
- getDataKeys ,
20
- noDataAxisConfig ,
21
- noDataPieChartConfig ,
22
- } from "./chartConstants" ;
8
+ import { AxisFormatterComp , EchartsAxisType } from "./chartConfigs/cartesianAxisConfig" ;
9
+ import { chartChildrenMap , ChartSize , getDataKeys } from "./chartConstants" ;
23
10
import { chartPropertyView } from "./chartPropertyView" ;
24
- import { EChartsOption } from "echarts" ;
25
11
import _ from "lodash" ;
26
12
import { useEffect , useMemo , useRef , useState } from "react" ;
27
13
import ReactResizeDetector from "react-resize-detector" ;
28
14
import ReactECharts from "./reactEcharts" ;
29
15
import {
30
- chartColorPalette ,
31
16
childrenToProps ,
32
17
depsConfig ,
33
18
genRandomKey ,
34
- isNumeric ,
35
19
JSONObject ,
36
20
JSONValue ,
37
21
NameConfig ,
@@ -42,230 +26,12 @@ import {
42
26
withViewFn ,
43
27
} from "openblocks-sdk" ;
44
28
import { getEchartsLocale , trans } from "i18n/comps" ;
45
-
46
- function transformData ( originData : JSONObject [ ] , xAxis : string , seriesColumnNames : string [ ] ) {
47
- // aggregate data by x-axis
48
- const transformedData : JSONObject [ ] = [ ] ;
49
- originData . reduce ( ( prev , cur ) => {
50
- if ( cur === null || cur === undefined ) {
51
- return prev ;
52
- }
53
- const groupValue = cur [ xAxis ] as string ;
54
- if ( ! prev [ groupValue ] ) {
55
- // init as 0
56
- const initValue : any = { } ;
57
- seriesColumnNames . forEach ( ( name ) => {
58
- initValue [ name ] = 0 ;
59
- } ) ;
60
- prev [ groupValue ] = initValue ;
61
- transformedData . push ( prev [ groupValue ] ) ;
62
- }
63
- // remain the x-axis data
64
- prev [ groupValue ] [ xAxis ] = groupValue ;
65
- seriesColumnNames . forEach ( ( key ) => {
66
- if ( key === xAxis ) {
67
- return ;
68
- } else if ( isNumeric ( cur [ key ] ) ) {
69
- prev [ groupValue ] [ key ] += Number ( cur [ key ] ) ;
70
- } else {
71
- prev [ groupValue ] [ key ] += 1 ;
72
- }
73
- } ) ;
74
- return prev ;
75
- } , { } as any ) ;
76
- return transformedData ;
77
- }
78
-
79
- const notAxisChartSet : Set < CharOptionCompType > = new Set ( [ "pie" ] as const ) ;
80
- const echartsConfigOmitChildren = [ "hidden" , "selectedPoints" , "onEvent" ] as const ;
81
- type EchartsConfigProps = Omit < ChartCompPropsType , typeof echartsConfigOmitChildren [ number ] > ;
82
-
83
- function isAxisChart ( type : CharOptionCompType ) {
84
- return ! notAxisChartSet . has ( type ) ;
85
- }
86
-
87
- function getSeriesConfig ( props : EchartsConfigProps ) {
88
- const visibleSeries = props . series . filter ( ( s ) => ! s . getView ( ) . hide ) ;
89
- const seriesLength = visibleSeries . length ;
90
- return visibleSeries . map ( ( s , index ) => {
91
- if ( isAxisChart ( props . chartConfig . type ) ) {
92
- let encodeX : string , encodeY : string ;
93
- const horizontalX = props . xAxisDirection === "horizontal" ;
94
- let itemStyle = props . chartConfig . itemStyle ;
95
- // FIXME: need refactor... chartConfig returns a function with paramters
96
- if ( props . chartConfig . type === "bar" ) {
97
- // barChart's border radius, depend on x-axis direction and stack state
98
- const borderRadius = horizontalX ? [ 2 , 2 , 0 , 0 ] : [ 0 , 2 , 2 , 0 ] ;
99
- if ( props . chartConfig . stack && index === visibleSeries . length - 1 ) {
100
- itemStyle = { ...itemStyle , borderRadius : borderRadius } ;
101
- } else if ( ! props . chartConfig . stack ) {
102
- itemStyle = { ...itemStyle , borderRadius : borderRadius } ;
103
- }
104
- }
105
- if ( horizontalX ) {
106
- encodeX = props . xAxisKey ;
107
- encodeY = s . getView ( ) . columnName ;
108
- } else {
109
- encodeX = s . getView ( ) . columnName ;
110
- encodeY = props . xAxisKey ;
111
- }
112
- return {
113
- name : s . getView ( ) . seriesName ,
114
- selectedMode : "single" ,
115
- select : {
116
- itemStyle : {
117
- borderColor : "#000" ,
118
- } ,
119
- } ,
120
- encode : {
121
- x : encodeX ,
122
- y : encodeY ,
123
- } ,
124
- // each type of chart's config
125
- ...props . chartConfig ,
126
- itemStyle : itemStyle ,
127
- label : {
128
- ...props . chartConfig . label ,
129
- ...( ! horizontalX && { position : "outside" } ) ,
130
- } ,
131
- } ;
132
- } else {
133
- // pie
134
- const radiusAndCenter = getPieRadiusAndCenter ( seriesLength , index , props . chartConfig ) ;
135
- return {
136
- ...props . chartConfig ,
137
- radius : radiusAndCenter . radius ,
138
- center : radiusAndCenter . center ,
139
- name : s . getView ( ) . seriesName ,
140
- selectedMode : "single" ,
141
- encode : {
142
- itemName : props . xAxisKey ,
143
- value : s . getView ( ) . columnName ,
144
- } ,
145
- } ;
146
- }
147
- } ) ;
148
- }
149
-
150
- // https://echarts.apache.org/en/option.html
151
- function getEchartsConfig ( props : EchartsConfigProps , chartSize ?: ChartSize ) : EChartsOption {
152
- if ( props . mode === "json" ) {
153
- return props . echartsOption ? props . echartsOption : { } ;
154
- }
155
- // axisChart
156
- const axisChart = isAxisChart ( props . chartConfig . type ) ;
157
- const gridPos = {
158
- left : 20 ,
159
- right : props . legendConfig . left === "right" ? "10%" : 20 ,
160
- top : 50 ,
161
- bottom : 35 ,
162
- } ;
163
- let config : EChartsOption = {
164
- color : chartColorPalette ,
165
- title : { text : props . title , left : "center" } ,
166
- backgroundColor : "#fff" ,
167
- tooltip : {
168
- confine : true ,
169
- trigger : axisChart ? "axis" : "item" ,
170
- } ,
171
- legend : props . legendConfig ,
172
- grid : {
173
- ...gridPos ,
174
- containLabel : true ,
175
- } ,
176
- } ;
177
- if ( props . data . length <= 0 ) {
178
- // no data
179
- return {
180
- ...config ,
181
- ...( axisChart ? noDataAxisConfig : noDataPieChartConfig ) ,
182
- } ;
183
- }
184
- const yAxisConfig = props . yConfig ( ) ;
185
- const seriesColumnNames = props . series
186
- . filter ( ( s ) => ! s . getView ( ) . hide )
187
- . map ( ( s ) => s . getView ( ) . columnName ) ;
188
- // y-axis is category and time, data doesn't need to aggregate
189
- const transformedData =
190
- yAxisConfig . type === "category" || yAxisConfig . type === "time"
191
- ? props . data
192
- : transformData ( props . data , props . xAxisKey , seriesColumnNames ) ;
193
- config = {
194
- ...config ,
195
- dataset : [
196
- {
197
- source : transformedData ,
198
- sourceHeader : false ,
199
- } ,
200
- ] ,
201
- series : getSeriesConfig ( props ) ,
202
- } ;
203
- if ( axisChart ) {
204
- // pure chart's size except the margin around
205
- let chartRealSize ;
206
- if ( chartSize ) {
207
- const rightSize =
208
- typeof gridPos . right === "number"
209
- ? gridPos . right
210
- : ( chartSize . w * parseFloat ( gridPos . right ) ) / 100.0 ;
211
- chartRealSize = {
212
- // actually it's self-adaptive with the x-axis label on the left, not that accurate but work
213
- w : chartSize . w - gridPos . left - rightSize ,
214
- // also self-adaptive on the bottom
215
- h : chartSize . h - gridPos . top - gridPos . bottom ,
216
- right : rightSize ,
217
- } ;
218
- }
219
- const finalXyConfig = calcXYConfig (
220
- props . xConfig ,
221
- yAxisConfig ,
222
- props . xAxisDirection ,
223
- transformedData . map ( ( d ) => d [ props . xAxisKey ] ) ,
224
- chartRealSize
225
- ) ;
226
- config = {
227
- ...config ,
228
- // @ts -ignore
229
- xAxis : finalXyConfig . xConfig ,
230
- // @ts -ignore
231
- yAxis : finalXyConfig . yConfig ,
232
- } ;
233
- }
234
- // log.log("Echarts transformedData and config", transformedData, config);
235
- return config ;
236
- }
237
-
238
- function getSelectedPoints ( param : any , option : any ) {
239
- const series = option . series ;
240
- const dataSource = _ . isArray ( option . dataset ) && option . dataset [ 0 ] ?. source ;
241
- if ( series && dataSource ) {
242
- return param . selected . flatMap ( ( selectInfo : any ) => {
243
- const seriesInfo = series [ selectInfo . seriesIndex ] ;
244
- if ( ! seriesInfo || ! seriesInfo . encode ) {
245
- return [ ] ;
246
- }
247
- return selectInfo . dataIndex . map ( ( index : any ) => {
248
- const commonResult = {
249
- seriesName : seriesInfo . name ,
250
- } ;
251
- if ( seriesInfo . encode . itemName && seriesInfo . encode . value ) {
252
- return {
253
- ...commonResult ,
254
- itemName : dataSource [ index ] [ seriesInfo . encode . itemName ] ,
255
- value : dataSource [ index ] [ seriesInfo . encode . value ] ,
256
- } ;
257
- } else {
258
- return {
259
- ...commonResult ,
260
- x : dataSource [ index ] [ seriesInfo . encode . x ] ,
261
- y : dataSource [ index ] [ seriesInfo . encode . y ] ,
262
- } ;
263
- }
264
- } ) ;
265
- } ) ;
266
- }
267
- return [ ] ;
268
- }
29
+ import { ItemColorComp } from "comps/chartComp/chartConfigs/lineChartConfig" ;
30
+ import {
31
+ echartsConfigOmitChildren ,
32
+ getEchartsConfig ,
33
+ getSelectedPoints ,
34
+ } from "comps/chartComp/chartUtils" ;
269
35
270
36
let ChartTmpComp = ( function ( ) {
271
37
return new UICompBuilder ( chartChildrenMap , ( ) => null )
@@ -353,6 +119,52 @@ function getYAxisFormatContextValue(
353
119
354
120
ChartTmpComp = class extends ChartTmpComp {
355
121
private lastYAxisFormatContextVal ?: JSONValue ;
122
+ private lastColorContext ?: JSONObject ;
123
+
124
+ updateContext ( comp : this) {
125
+ // the context value of axis format
126
+ let resultComp = comp ;
127
+ const data = comp . children . data . getView ( ) ;
128
+ const sampleSeries = comp . children . series . getView ( ) . find ( ( s ) => ! s . getView ( ) . hide ) ;
129
+ const yAxisContextValue = getYAxisFormatContextValue (
130
+ data ,
131
+ comp . children . yConfig . children . yAxisType . getView ( ) ,
132
+ sampleSeries ?. children . columnName . getView ( )
133
+ ) ;
134
+ if ( yAxisContextValue !== comp . lastYAxisFormatContextVal ) {
135
+ comp . lastYAxisFormatContextVal = yAxisContextValue ;
136
+ resultComp = comp . setChild (
137
+ "yConfig" ,
138
+ comp . children . yConfig . reduce (
139
+ wrapChildAction (
140
+ "formatter" ,
141
+ AxisFormatterComp . changeContextDataAction ( { value : yAxisContextValue } )
142
+ )
143
+ )
144
+ ) ;
145
+ }
146
+ // item color context
147
+ const colorContextVal = {
148
+ seriesName : sampleSeries ?. children . seriesName . getView ( ) ,
149
+ value : yAxisContextValue ,
150
+ } ;
151
+ if (
152
+ comp . children . chartConfig . children . comp . children . hasOwnProperty ( "itemColor" ) &&
153
+ ! _ . isEqual ( colorContextVal , comp . lastColorContext )
154
+ ) {
155
+ comp . lastColorContext = colorContextVal ;
156
+ resultComp = resultComp . setChild (
157
+ "chartConfig" ,
158
+ comp . children . chartConfig . reduce (
159
+ wrapChildAction (
160
+ "comp" ,
161
+ wrapChildAction ( "itemColor" , ItemColorComp . changeContextDataAction ( colorContextVal ) )
162
+ )
163
+ )
164
+ ) ;
165
+ }
166
+ return resultComp ;
167
+ }
356
168
357
169
override reduce ( action : CompAction ) : this {
358
170
const comp = super . reduce ( action ) ;
@@ -370,25 +182,7 @@ ChartTmpComp = class extends ChartTmpComp {
370
182
comp . children . series . dispatchDataChanged ( newData ) ;
371
183
} , 0 ) ;
372
184
}
373
- // the context value of axis format
374
- const sampleSeries = comp . children . series . getView ( ) . find ( ( s ) => ! s . getView ( ) . hide ) ;
375
- const contextValue = getYAxisFormatContextValue (
376
- newData ,
377
- comp . children . yConfig . children . yAxisType . getView ( ) ,
378
- sampleSeries ?. children . columnName . getView ( )
379
- ) ;
380
- if ( contextValue !== comp . lastYAxisFormatContextVal ) {
381
- comp . lastYAxisFormatContextVal = contextValue ;
382
- return comp . setChild (
383
- "yConfig" ,
384
- comp . children . yConfig . reduce (
385
- wrapChildAction (
386
- "formatter" ,
387
- AxisFormatterComp . changeContextDataAction ( { value : contextValue } )
388
- )
389
- )
390
- ) ;
391
- }
185
+ return this . updateContext ( comp ) ;
392
186
}
393
187
return comp ;
394
188
}
0 commit comments