sea-chart 1.1.62 → 1.1.63-alpha.0
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.
- package/dist/services/map-json.js +3 -1
- package/dist/utils/chart-utils/base-utils.js +4 -0
- package/dist/view/index.css +6 -2
- package/dist/view/wrapper/area.js +84 -121
- package/dist/view/wrapper/bar-custom.js +138 -89
- package/dist/view/wrapper/bar-group.js +66 -78
- package/dist/view/wrapper/bar.js +47 -54
- package/dist/view/wrapper/chart-component.js +276 -45
- package/dist/view/wrapper/combination.js +168 -299
- package/dist/view/wrapper/compare.js +97 -190
- package/dist/view/wrapper/completeness.js +147 -71
- package/dist/view/wrapper/dashboard.js +102 -137
- package/dist/view/wrapper/funnel.js +49 -84
- package/dist/view/wrapper/heat-map.js +165 -257
- package/dist/view/wrapper/horizontal-bar-group.js +55 -72
- package/dist/view/wrapper/horizontal-bar.js +34 -69
- package/dist/view/wrapper/horizontal-component.js +6 -6
- package/dist/view/wrapper/line-group.js +32 -87
- package/dist/view/wrapper/line.js +32 -85
- package/dist/view/wrapper/map.js +318 -240
- package/dist/view/wrapper/mirror.js +214 -109
- package/dist/view/wrapper/pie.js +99 -121
- package/dist/view/wrapper/ring.js +130 -200
- package/dist/view/wrapper/scatter.js +140 -47
- package/dist/view/wrapper/treemap.js +56 -74
- package/dist/view/wrapper/world-map.js +340 -272
- package/package.json +7 -5
- package/dist/utils/custom-g2.js +0 -655
|
@@ -69,7 +69,8 @@ function getMapJsonQueryUrl(mapLevel, mapLocation) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
function handleLoadedMapJson(url, mapJson) {
|
|
72
|
-
|
|
72
|
+
// geo json and topology json
|
|
73
|
+
const isValid = mapJson && mapJson.features || mapJson && mapJson.type === 'Topology';
|
|
73
74
|
if (isValid) {
|
|
74
75
|
setMapJson(url, mapJson);
|
|
75
76
|
return mapJson;
|
|
@@ -89,6 +90,7 @@ export default async function fetchMapJson(mapLevel, mapLocation, mediaUrl) {
|
|
|
89
90
|
let mapJson;
|
|
90
91
|
try {
|
|
91
92
|
const res = await fetch("".concat(mediaUrl, "dtable-statistic/geolocation/").concat(url, ".json"));
|
|
93
|
+
// const res = await fetch('https://geojson.cn/api/china/china.topo.json');
|
|
92
94
|
mapJson = await res.json();
|
|
93
95
|
} catch (error) {
|
|
94
96
|
console.error('on fetchMapJson: fetch error', error);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var _BaseUtils;
|
|
2
2
|
import shallowEqual from 'shallowequal';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
|
+
import slugid from 'slugid';
|
|
4
5
|
import { CellType, COLLABORATOR_COLUMN_TYPES, FORMULA_COLUMN_TYPES_MAP, FORMULA_RESULT_TYPE, getDateDisplayString, getNumberDisplayString, getOption, getPrecisionNumber, getTableById, getTableColumnByKey, isNumber, isNumericColumn, isDateColumn, sortText, sortNumber, sortDate, sortSingleSelect, sortFormula, getColumnOptions, DateUtils, getGeolocationDisplayString, getFormulaDisplayString, isArchiveView, getViewById, MULTIPLE_CELL_VALUE_COLUMN_TYPE_MAP } from 'dtable-utils';
|
|
5
6
|
import { PIE_CHART_COLORS, CHART_SUMMARY_TYPE, CHART_SUPPORT_SORT_COLUMNS, CHART_TYPE, CHART_STYLE_SETTING_KEYS, DEFAULT_LABEL_FONT_SIZE, DEFAULT_NUMBER_FORMAT_OBJECT, X_AXIS_IS_GROUPBY_COLUMN_KEY_CHART_TYPES, STYLE_COLORS, CHART_DATA_SORT_TYPE, CHART_Y_GROUP_TYPE, HORIZONTAL_BAR_CHART_TYPES, COMPLTETELESS_CHART_TYPES, CHART_STYLE_CONFIG_SETTING_KEYS } from '../../constants';
|
|
6
7
|
import { getClientFormulaDisplayString } from '../cell-format-utils';
|
|
@@ -543,6 +544,9 @@ BaseUtils.formatEmptyName = (dataList, column_groupby_column_key, emptyName) =>
|
|
|
543
544
|
if (!item.name) {
|
|
544
545
|
item.name = emptyName;
|
|
545
546
|
}
|
|
547
|
+
if (!item.slugid) {
|
|
548
|
+
item.slugId = slugid.nice();
|
|
549
|
+
}
|
|
546
550
|
if (column_groupby_column_key && !item.group_name) {
|
|
547
551
|
item.group_name = emptyName;
|
|
548
552
|
}
|
package/dist/view/index.css
CHANGED
|
@@ -49,10 +49,14 @@
|
|
|
49
49
|
.sea-chart-formatter .sea-chart-container {
|
|
50
50
|
font-size: 12px;
|
|
51
51
|
position: absolute;
|
|
52
|
-
left:
|
|
52
|
+
left: 0;
|
|
53
|
+
top: 0;
|
|
54
|
+
/* left: 2%;
|
|
53
55
|
right: 2%;
|
|
54
56
|
top: 2%;
|
|
55
|
-
bottom: 8%;
|
|
57
|
+
bottom: 8%; */
|
|
58
|
+
width: 100%;
|
|
59
|
+
height: 100%;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
.sea-chart-formatter .sea-chart-container.plugin-number-card,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import classNames from 'classnames';
|
|
4
3
|
import { CellType } from 'dtable-ui-component/lib/constants';
|
|
5
|
-
import { CHART_LINE_TYPES, CHART_STYLE_COLORS, CHART_THEME_COLOR,
|
|
4
|
+
import { CHART_LINE_TYPES, CHART_STYLE_COLORS, CHART_THEME_COLOR, TYPE_COLOR_USING, TITLE_AMOUNT } from '../../constants';
|
|
6
5
|
import intl from '../../intl';
|
|
7
6
|
import { BaseUtils, isFunction } from '../../utils';
|
|
8
7
|
import { SUPPORT_SINGLE_SELECT_THEMES_OPTIONS } from '../../constants/color-rules';
|
|
@@ -28,7 +27,13 @@ class Area extends ChartComponent {
|
|
|
28
27
|
const {
|
|
29
28
|
y_axis_show_value
|
|
30
29
|
} = chart.config;
|
|
31
|
-
const appendPadding =
|
|
30
|
+
const appendPadding = {
|
|
31
|
+
insetRight: 50,
|
|
32
|
+
insetLeft: 50
|
|
33
|
+
};
|
|
34
|
+
if (y_axis_show_value) {
|
|
35
|
+
appendPadding['paddingTop'] = 17;
|
|
36
|
+
}
|
|
32
37
|
this.initChart(this.container, {
|
|
33
38
|
appendPadding
|
|
34
39
|
});
|
|
@@ -37,7 +42,6 @@ class Area extends ChartComponent {
|
|
|
37
42
|
});
|
|
38
43
|
};
|
|
39
44
|
this.clearChart = () => {
|
|
40
|
-
this.chart.annotation().clear(true);
|
|
41
45
|
this.chart.clear(true);
|
|
42
46
|
};
|
|
43
47
|
this.drawChart = () => {
|
|
@@ -47,16 +51,12 @@ class Area extends ChartComponent {
|
|
|
47
51
|
} = this.props;
|
|
48
52
|
data = BaseUtils.formatEmptyName(data, '', intl.get('Empty'));
|
|
49
53
|
if (!Array.isArray(data)) return;
|
|
50
|
-
if (this.isGroupChart) {
|
|
51
|
-
this.chart.scale(this.groupName, {
|
|
52
|
-
type: 'cat'
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
54
|
this.loadData(data);
|
|
56
55
|
this.draw(data);
|
|
57
56
|
isFunction(customRender) && customRender(this.chart);
|
|
58
57
|
requestAnimationFrame(() => {
|
|
59
58
|
this.chart.render();
|
|
59
|
+
this.renderAxisLabel(this.props.chart, this.props.tables);
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
62
|
this.draw = data => {
|
|
@@ -65,20 +65,18 @@ class Area extends ChartComponent {
|
|
|
65
65
|
summaryColumn,
|
|
66
66
|
columnGroupbyColumn,
|
|
67
67
|
globalTheme,
|
|
68
|
-
customRender,
|
|
69
68
|
chartColorTheme
|
|
70
69
|
} = this.props;
|
|
71
70
|
const theme = CHART_THEME_COLOR[globalTheme];
|
|
72
71
|
const {
|
|
73
|
-
y_axis_summary_type,
|
|
74
72
|
y_axis_summary_method,
|
|
75
73
|
y_axis_label_color,
|
|
76
74
|
line_type,
|
|
77
75
|
y_axis_show_value,
|
|
78
76
|
label_font_size,
|
|
79
|
-
summary_columns = [],
|
|
80
77
|
color_option,
|
|
81
|
-
color_theme
|
|
78
|
+
color_theme,
|
|
79
|
+
column_groupby_multiple_numeric_column
|
|
82
80
|
} = chart.config;
|
|
83
81
|
const {
|
|
84
82
|
display_goal_line,
|
|
@@ -87,20 +85,11 @@ class Area extends ChartComponent {
|
|
|
87
85
|
} = chart.style_config || {};
|
|
88
86
|
const chartWidth = this.chart.width - 6 - 10; // 10 is y-axis number width and 6 is gap between number and y axis line
|
|
89
87
|
|
|
90
|
-
const newData = this.getChartGroupData(data);
|
|
91
88
|
const isSmooth = line_type === CHART_LINE_TYPES[1];
|
|
92
|
-
const isMultipleSummary = summary_columns && summary_columns.length;
|
|
93
|
-
const isAreaGroup = chart.config.type === CHART_TYPE.AREA_GROUP;
|
|
94
89
|
const useSingleSelectColumnColor = (columnGroupbyColumn === null || columnGroupbyColumn === void 0 ? void 0 : columnGroupbyColumn.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
|
|
95
90
|
let chartBarColor;
|
|
96
|
-
let colorCallBack = null;
|
|
97
91
|
if (this.isGroupChart) {
|
|
98
92
|
useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme);
|
|
99
|
-
chartBarColor = this.groupName;
|
|
100
|
-
colorCallBack = group_name => {
|
|
101
|
-
return this.colorMap[group_name];
|
|
102
|
-
};
|
|
103
|
-
this.drawLabels(newData);
|
|
104
93
|
} else {
|
|
105
94
|
// default color
|
|
106
95
|
chartBarColor = CHART_STYLE_COLORS[0];
|
|
@@ -112,114 +101,96 @@ class Area extends ChartComponent {
|
|
|
112
101
|
if (color_option === TYPE_COLOR_USING.USE_SPECIFIC_COLORS && y_axis_label_color) {
|
|
113
102
|
chartBarColor = y_axis_label_color;
|
|
114
103
|
}
|
|
115
|
-
this.drawLabels(newData);
|
|
116
|
-
}
|
|
117
|
-
const title = this.getTitle(this.props.tables, chart.config.table_id, y_axis_summary_type, chart.config.y_axis_column_key || chart.config.y_axis_summary_column_key);
|
|
118
|
-
|
|
119
|
-
// set Coord type
|
|
120
|
-
this.chart.coordinate('rect');
|
|
121
|
-
this.autoAdjustDataOptions(chart, data, summaryColumn);
|
|
122
|
-
|
|
123
|
-
// if area group
|
|
124
|
-
if (this.isGroupChart) {
|
|
125
|
-
this.chart.scale({
|
|
126
|
-
group_name: {
|
|
127
|
-
type: 'cat'
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
104
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
105
|
+
const scaleOptions = this.getYaxisAutoAdjustScaleOptions(chart, data, summaryColumn);
|
|
106
|
+
const line = this.chart.line().encode('x', 'name').encode('y', 'value').style('shape', isSmooth ? 'smooth' : 'line').style('lineWidth', 2).animate('enter', {
|
|
107
|
+
type: 'fadeIn',
|
|
108
|
+
duration: 1000,
|
|
109
|
+
easing: 'linear'
|
|
110
|
+
}).label({
|
|
111
|
+
text: y_axis_show_value ? 'value' : '',
|
|
134
112
|
style: {
|
|
135
113
|
fontSize: BaseUtils.getLabelFontSize(label_font_size),
|
|
136
114
|
fill: theme.labelColor,
|
|
115
|
+
dy: -15,
|
|
137
116
|
...this.labelStroke
|
|
138
117
|
}
|
|
139
|
-
}).
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
118
|
+
}).tooltip(false);
|
|
119
|
+
const area = this.chart.area().encode('x', 'name').encode('y', 'value').axis('x', {
|
|
120
|
+
...this.getAxisStyle(theme, 'x'),
|
|
121
|
+
labelAutoRotate: false
|
|
122
|
+
}).axis('y', this.getAxisStyle(theme, 'y')).scale('y', {
|
|
123
|
+
type: 'linear',
|
|
124
|
+
...scaleOptions
|
|
125
|
+
}).style('shape', isSmooth ? 'smooth' : 'area').style('opacity', 0.3).animate('enter', {
|
|
126
|
+
type: 'fadeIn',
|
|
127
|
+
duration: 1000,
|
|
128
|
+
easing: 'linear'
|
|
129
|
+
}).tooltip(data => {
|
|
130
|
+
const {
|
|
131
|
+
name,
|
|
132
|
+
value,
|
|
133
|
+
group_name
|
|
134
|
+
} = data;
|
|
156
135
|
return {
|
|
157
|
-
title: isAreaGroup && isMultipleSummary ? !name && typeof name !== 'number' ? intl.get('Empty') : name : title,
|
|
158
136
|
value: BaseUtils.getSummaryValueDisplayString(summaryColumn, value, y_axis_summary_method),
|
|
159
|
-
|
|
137
|
+
xName: column_groupby_multiple_numeric_column ? group_name : name
|
|
160
138
|
};
|
|
161
|
-
}).
|
|
162
|
-
|
|
139
|
+
}).interaction('tooltip', {
|
|
140
|
+
css: this.getToolTipCss(),
|
|
141
|
+
render: (event, tooltipData) => {
|
|
142
|
+
tooltipData.items.forEach(item => {
|
|
143
|
+
item.name = item.xName;
|
|
144
|
+
});
|
|
145
|
+
tooltipData['title'] = this.getTooltipTitle(tooltipData);
|
|
146
|
+
return this.getToolTipDom(tooltipData);
|
|
147
|
+
},
|
|
148
|
+
markerStroke: '',
|
|
149
|
+
markerR: 5
|
|
163
150
|
});
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
appear: {
|
|
169
|
-
animation: 'fadeIn',
|
|
170
|
-
duration: 1000,
|
|
171
|
-
easing: 'easeLinear'
|
|
172
|
-
}
|
|
173
|
-
}).position('name*value').color(chartBarColor, colorCallBack).shape('circle').size(4).style({
|
|
174
|
-
stroke: 0,
|
|
175
|
-
fillOpacity: 1,
|
|
176
|
-
opacity: y_axis_show_value ? 1 : 0
|
|
151
|
+
const point = this.chart.point().encode('x', 'name').encode('y', 'value').style('shape', 'circle').style('r', 3).style('opacity', y_axis_show_value ? 1 : 0).animate('enter', {
|
|
152
|
+
type: 'fadeIn',
|
|
153
|
+
duration: 1000,
|
|
154
|
+
easing: 'linear'
|
|
177
155
|
}).tooltip(false);
|
|
178
|
-
this.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
lineWidth: 2
|
|
183
|
-
});
|
|
184
|
-
area.style({
|
|
185
|
-
fillOpacity: 0.1
|
|
186
|
-
});
|
|
187
|
-
if (point) point.style({
|
|
188
|
-
fillOpacity: 0.3,
|
|
189
|
-
stroke: 0,
|
|
190
|
-
opacity: 1
|
|
191
|
-
});
|
|
192
|
-
this.chart.render();
|
|
193
|
-
});
|
|
194
|
-
this.chart.on('tooltip:hide', () => {
|
|
195
|
-
if (line.styleOption.cfg.opacity === 1) return;
|
|
196
|
-
line.style({
|
|
197
|
-
opacity: 1,
|
|
198
|
-
lineWidth: 2
|
|
199
|
-
});
|
|
200
|
-
area.style({
|
|
201
|
-
fillOpacity: 0.3
|
|
202
|
-
});
|
|
203
|
-
if (point) point.style({
|
|
204
|
-
fillOpacity: 1,
|
|
205
|
-
stroke: 0,
|
|
206
|
-
opacity: 0
|
|
156
|
+
if (this.isGroupChart) {
|
|
157
|
+
line.encode('color', 'group_name');
|
|
158
|
+
area.encode('color', 'group_name').legend({
|
|
159
|
+
color: this.getLegendConfigNew('group_name', theme)
|
|
207
160
|
});
|
|
208
|
-
|
|
209
|
-
}
|
|
161
|
+
point.encode('color', 'group_name');
|
|
162
|
+
} else {
|
|
163
|
+
line.style('stroke', chartBarColor);
|
|
164
|
+
area.style('fill', chartBarColor);
|
|
165
|
+
point.style('fill', chartBarColor);
|
|
166
|
+
}
|
|
210
167
|
if (display_goal_line && goal_label && goal_value) {
|
|
211
168
|
this.setDispalyGoalLine(goal_label, goal_value, chartWidth);
|
|
212
169
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
170
|
+
};
|
|
171
|
+
this.getTooltipTitle = tooltipData => {
|
|
172
|
+
const {
|
|
173
|
+
chart,
|
|
174
|
+
summaryColumn
|
|
175
|
+
} = this.props;
|
|
176
|
+
const {
|
|
177
|
+
y_axis_summary_type,
|
|
178
|
+
column_groupby_multiple_numeric_column
|
|
179
|
+
} = chart.config;
|
|
180
|
+
const {
|
|
181
|
+
title
|
|
182
|
+
} = tooltipData;
|
|
183
|
+
if (column_groupby_multiple_numeric_column) {
|
|
184
|
+
return title;
|
|
185
|
+
}
|
|
186
|
+
if (y_axis_summary_type === 'count') {
|
|
187
|
+
return intl.get(TITLE_AMOUNT);
|
|
188
|
+
}
|
|
189
|
+
if (y_axis_summary_type === 'advanced') {
|
|
190
|
+
return summaryColumn === null || summaryColumn === void 0 ? void 0 : summaryColumn.name;
|
|
219
191
|
}
|
|
220
192
|
};
|
|
221
193
|
this.chart = null;
|
|
222
|
-
this.groupName = 'group_name';
|
|
223
194
|
this.isGroupChart = false;
|
|
224
195
|
this.needRenderAxisLabel = true;
|
|
225
196
|
}
|
|
@@ -227,7 +198,6 @@ class Area extends ChartComponent {
|
|
|
227
198
|
this.initChartType();
|
|
228
199
|
this.createChart();
|
|
229
200
|
this.drawChart();
|
|
230
|
-
this.renderAxisLabel(this.props.chart, this.props.tables);
|
|
231
201
|
super.componentDidMount();
|
|
232
202
|
}
|
|
233
203
|
componentDidUpdate(prevProps) {
|
|
@@ -238,7 +208,6 @@ class Area extends ChartComponent {
|
|
|
238
208
|
((_this$chart = this.chart) === null || _this$chart === void 0 ? void 0 : _this$chart.autoPadding) && this.chart.destroy();
|
|
239
209
|
this.createChart();
|
|
240
210
|
this.drawChart();
|
|
241
|
-
this.renderAxisLabel(prevProps.chart, prevProps.tables);
|
|
242
211
|
}
|
|
243
212
|
}
|
|
244
213
|
componentWillUnmount() {
|
|
@@ -247,14 +216,8 @@ class Area extends ChartComponent {
|
|
|
247
216
|
super.componentWillUnmount();
|
|
248
217
|
}
|
|
249
218
|
render() {
|
|
250
|
-
const {
|
|
251
|
-
chart
|
|
252
|
-
} = this.props;
|
|
253
219
|
return /*#__PURE__*/React.createElement("div", {
|
|
254
|
-
className:
|
|
255
|
-
'show-x-axis-label': this.isShowXAxisLabel(chart),
|
|
256
|
-
'show-y-axis-label': this.isShowYAxisLabel(chart)
|
|
257
|
-
}),
|
|
220
|
+
className: "sea-chart-container",
|
|
258
221
|
ref: ref => this.container = ref
|
|
259
222
|
});
|
|
260
223
|
}
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import DataSet from '@antv/data-set';
|
|
4
4
|
import { debounce, maxBy } from 'lodash-es';
|
|
5
|
-
import classNames from 'classnames';
|
|
6
5
|
import intl from '../../intl';
|
|
7
6
|
import { BaseUtils } from '../../utils/chart-utils';
|
|
8
7
|
import { EMPTY_NAME, CHART_THEME_COLOR } from '../../constants';
|
|
@@ -16,22 +15,12 @@ class BarCustom extends ChartComponent {
|
|
|
16
15
|
this.drawChart();
|
|
17
16
|
}, 300);
|
|
18
17
|
this.createChart = () => {
|
|
19
|
-
|
|
20
|
-
chart
|
|
21
|
-
} = this.props;
|
|
22
|
-
const {
|
|
23
|
-
y_axis_show_value
|
|
24
|
-
} = chart.config;
|
|
25
|
-
const appendPadding = [y_axis_show_value ? 17 : 0, 0, 0, 0]; // used to display value on the top
|
|
26
|
-
this.initChart(this.container, {
|
|
27
|
-
appendPadding
|
|
28
|
-
});
|
|
18
|
+
this.initChart(this.container);
|
|
29
19
|
this.chart.on('interval:click', e => {
|
|
30
20
|
this.props.toggleRecords(e.data.data);
|
|
31
21
|
});
|
|
32
22
|
};
|
|
33
23
|
this.clearChart = () => {
|
|
34
|
-
this.chart.annotation().clear(true);
|
|
35
24
|
this.chart.clear(true);
|
|
36
25
|
};
|
|
37
26
|
this.drawChart = () => {
|
|
@@ -45,6 +34,43 @@ class BarCustom extends ChartComponent {
|
|
|
45
34
|
requestAnimationFrame(() => {
|
|
46
35
|
this.chart.render();
|
|
47
36
|
this.renderAxisLabel(this.props.chart, this.props.tables);
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
const {
|
|
39
|
+
canvas
|
|
40
|
+
} = this.chart.getContext();
|
|
41
|
+
const elements = canvas.document.getElementsByClassName('element').filter(el => el.config.type === 'rect');
|
|
42
|
+
// update x position
|
|
43
|
+
elements.forEach((element, index) => {
|
|
44
|
+
const {
|
|
45
|
+
y_axis_type,
|
|
46
|
+
x,
|
|
47
|
+
width
|
|
48
|
+
} = element.attributes;
|
|
49
|
+
if (y_axis_type !== '__y_axis__0') {
|
|
50
|
+
const offsetX = y_axis_type.slice(-1) * width;
|
|
51
|
+
const marginX = y_axis_type.slice(-1) * 8;
|
|
52
|
+
element.attr('x', x + offsetX + marginX);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// update y position
|
|
56
|
+
const yAxisTypes = new Set([]);
|
|
57
|
+
elements.forEach(el => yAxisTypes.add(el.attributes.y_axis_type));
|
|
58
|
+
Array.from(yAxisTypes).forEach(type => {
|
|
59
|
+
const rects = elements.filter(item => item.attributes.y_axis_type === type);
|
|
60
|
+
this.handleRectPosition(rects);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Adjust the position of the label
|
|
64
|
+
const labels = canvas.document.getElementsByClassName('label');
|
|
65
|
+
labels.forEach(label => {
|
|
66
|
+
const {
|
|
67
|
+
y,
|
|
68
|
+
height
|
|
69
|
+
} = label.attributes.dependentElement.attributes;
|
|
70
|
+
const yPosition = y + height / 2;
|
|
71
|
+
label.attr('y', yPosition - 8); // 8 is font height
|
|
72
|
+
});
|
|
73
|
+
}, 0);
|
|
48
74
|
});
|
|
49
75
|
};
|
|
50
76
|
this.organizeData = data => {
|
|
@@ -86,33 +112,8 @@ class BarCustom extends ChartComponent {
|
|
|
86
112
|
goal_value,
|
|
87
113
|
goal_label
|
|
88
114
|
} = chart.style_config || {};
|
|
89
|
-
const displayData = display_each_block_data;
|
|
90
|
-
this.chart.scale('group_name', {
|
|
91
|
-
type: 'cat'
|
|
92
|
-
});
|
|
93
115
|
const organizedData = this.organizeData(data);
|
|
94
|
-
|
|
95
|
-
// item nums in a group
|
|
96
|
-
const groupCountSums = Object.entries(organizedData).map(_ref => {
|
|
97
|
-
let [name, group] = _ref;
|
|
98
|
-
const groupCount = Object.keys(group).length;
|
|
99
|
-
return [name, groupCount];
|
|
100
|
-
});
|
|
101
|
-
// e.g. [ 'a', 3], name "a" has 3 different y_axis_type
|
|
102
|
-
const mostCommonCountGroup = maxBy(groupCountSums, 1)[1];
|
|
103
|
-
const singleBarWidth = Math.round(chartWidth / (2 * groupCountSums.length * mostCommonCountGroup));
|
|
104
|
-
// borderRadius of each bar is designed to be 1/5 of singleBarWidth
|
|
105
|
-
const singleBarRadius = Math.min(singleBarWidth / 5, 10);
|
|
106
|
-
this.drawLabels(data);
|
|
107
|
-
|
|
108
|
-
// set Coord type
|
|
109
|
-
this.chart.coordinate('rect');
|
|
110
|
-
this.chart.scale({
|
|
111
|
-
// Set the type of the name column so that g2 can draw correctly
|
|
112
|
-
name: {
|
|
113
|
-
type: 'cat'
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
+
this.singleBarWidth = this.getSingleBarWidth(organizedData);
|
|
116
117
|
|
|
117
118
|
// get the total value of each stack
|
|
118
119
|
const dv = new DataSet.DataView().source(data);
|
|
@@ -123,65 +124,119 @@ class BarCustom extends ChartComponent {
|
|
|
123
124
|
as: ['value_sum'],
|
|
124
125
|
groupBy: ['name', 'y_axis_type']
|
|
125
126
|
});
|
|
126
|
-
this.chart.
|
|
127
|
-
|
|
128
|
-
type: 'cat'
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
let labelCfg = {
|
|
127
|
+
this.chart.interval().label({
|
|
128
|
+
text: display_each_block_data ? 'formatted_value' : '',
|
|
132
129
|
style: {
|
|
133
130
|
fontSize: BaseUtils.getLabelFontSize(label_font_size),
|
|
134
131
|
fill: theme.labelColor,
|
|
135
132
|
stroke: '#fff',
|
|
136
133
|
lineWidth: 1
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
134
|
+
},
|
|
135
|
+
transform: [{
|
|
136
|
+
type: 'overlapHide'
|
|
137
|
+
}]
|
|
138
|
+
}).encode('x', 'name').encode('y', 'value').encode('color', 'group_name').axis('x', this.getAxisStyle(theme, 'x')).axis('y', this.getAxisStyle(theme, 'y')).transform({
|
|
139
|
+
type: 'stackY',
|
|
140
|
+
groupBy: 'group_name'
|
|
141
|
+
}).scale('color', {
|
|
142
|
+
type: 'ordinal',
|
|
143
|
+
range: BaseUtils.getCurrentTheme(chartColorTheme).colors
|
|
144
|
+
}).scale('y', {
|
|
145
|
+
type: 'linear',
|
|
146
|
+
domainMax: this.getDomainMax(dv)
|
|
147
|
+
}).style('slugId', 'slugId').style('x_axis_name', 'name').style('y_axis_type', 'y_axis_type').style('maxWidth', this.singleBarWidth).state('active', {
|
|
148
|
+
fillOpacity: 1,
|
|
149
|
+
stroke: null
|
|
150
|
+
}).state('inactive', {
|
|
151
|
+
fillOpacity: 0.3
|
|
152
|
+
}).interaction('elementHighlight').tooltip(data => {
|
|
153
|
+
const {
|
|
154
|
+
group_name,
|
|
155
|
+
value
|
|
156
|
+
} = data;
|
|
143
157
|
let nameContent = group_name;
|
|
144
158
|
if (!group_name && typeof group_name !== 'number') {
|
|
145
159
|
nameContent = intl.get(EMPTY_NAME);
|
|
146
160
|
}
|
|
147
|
-
const title = !name && typeof name !== 'number' ? intl.get(EMPTY_NAME) : name;
|
|
148
161
|
return {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
name: nameContent
|
|
162
|
+
name: nameContent,
|
|
163
|
+
value
|
|
152
164
|
};
|
|
153
|
-
}).
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}, {
|
|
159
|
-
type: 'stack'
|
|
160
|
-
}]).state({
|
|
161
|
-
active: {
|
|
162
|
-
style: {
|
|
163
|
-
stroke: null
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}).style('isFirst', isFirst => {
|
|
167
|
-
if (isFirst) {
|
|
168
|
-
return {
|
|
169
|
-
radius: [singleBarRadius, singleBarRadius, 0, 0]
|
|
170
|
-
};
|
|
171
|
-
} else {
|
|
172
|
-
return {
|
|
173
|
-
radius: [0, 0, 0, 0]
|
|
174
|
-
};
|
|
165
|
+
}).interaction('tooltip', {
|
|
166
|
+
series: true,
|
|
167
|
+
css: this.getToolTipCss(),
|
|
168
|
+
render: (event, tooltipData) => {
|
|
169
|
+
return this.getToolTipDom(tooltipData);
|
|
175
170
|
}
|
|
171
|
+
}).legend({
|
|
172
|
+
color: this.getLegendConfigNew('group_name', theme)
|
|
176
173
|
});
|
|
177
174
|
if (display_goal_line && goal_label && goal_value) {
|
|
178
|
-
this.setDispalyGoalLine(goal_label, goal_value,
|
|
175
|
+
this.setDispalyGoalLine(goal_label, goal_value, this.chart.value.width);
|
|
179
176
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this.chart.
|
|
177
|
+
};
|
|
178
|
+
this.handleRectPosition = rects => {
|
|
179
|
+
const {
|
|
180
|
+
layout
|
|
181
|
+
} = this.chart.getView();
|
|
182
|
+
rects.forEach((rect, index) => {
|
|
183
|
+
const {
|
|
184
|
+
height,
|
|
185
|
+
x_axis_name,
|
|
186
|
+
slugId
|
|
187
|
+
} = rect.attributes;
|
|
188
|
+
const bottomY = layout.innerHeight - height; // Bottom position of the axis
|
|
189
|
+
const yAxisStackRects = rects.filter(item => item.attributes.x_axis_name === x_axis_name);
|
|
190
|
+
// Multiple stacks
|
|
191
|
+
if (yAxisStackRects.length > 1) {
|
|
192
|
+
const stackIndex = yAxisStackRects.findIndex(item => item.attributes.slugId === slugId);
|
|
193
|
+
if (stackIndex !== -1) {
|
|
194
|
+
if (stackIndex === 0) {
|
|
195
|
+
rect.attr('y', bottomY);
|
|
196
|
+
} else {
|
|
197
|
+
let offsetY = 0;
|
|
198
|
+
yAxisStackRects.slice(0, stackIndex).forEach(item => {
|
|
199
|
+
offsetY = offsetY + item.attributes.height;
|
|
200
|
+
});
|
|
201
|
+
rect.attr('y', bottomY - offsetY);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// the top rect
|
|
205
|
+
if (stackIndex === yAxisStackRects.length - 1) {
|
|
206
|
+
// update radius
|
|
207
|
+
const singleBarRadius = Math.min(this.singleBarWidth / 5, 10); // borderRadius of each bar is designed to be 1/5 of singleBarWidth
|
|
208
|
+
rect.attr('radius', [singleBarRadius, singleBarRadius, 0, 0]);
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
// Single stack
|
|
212
|
+
rect.attr('y', bottomY);
|
|
213
|
+
// update radius
|
|
214
|
+
const singleBarRadius = Math.min(this.singleBarWidth / 5, 10); // borderRadius of each bar is designed to be 1/5 of singleBarWidth
|
|
215
|
+
rect.attr('radius', [singleBarRadius, singleBarRadius, 0, 0]);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
this.getSingleBarWidth = organizedData => {
|
|
220
|
+
const chartWidth = this.chart.value.width;
|
|
221
|
+
// item nums in a group
|
|
222
|
+
const groupCountSums = Object.entries(organizedData).map(_ref => {
|
|
223
|
+
let [name, group] = _ref;
|
|
224
|
+
const groupCount = Object.keys(group).length;
|
|
225
|
+
return [name, groupCount];
|
|
226
|
+
});
|
|
227
|
+
// e.g. [ 'a', 3], name "a" has 3 different y_axis_type
|
|
228
|
+
const mostCommonCountGroup = maxBy(groupCountSums, 1)[1];
|
|
229
|
+
const singleBarWidth = Math.round(chartWidth / (2 * groupCountSums.length * mostCommonCountGroup));
|
|
230
|
+
return singleBarWidth;
|
|
231
|
+
};
|
|
232
|
+
this.getDomainMax = dv => {
|
|
233
|
+
let domainMax = 0;
|
|
234
|
+
dv.rows.forEach(item => {
|
|
235
|
+
if (item.value_sum > domainMax) {
|
|
236
|
+
domainMax = item.value_sum;
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
return domainMax;
|
|
185
240
|
};
|
|
186
241
|
this.chart = null;
|
|
187
242
|
}
|
|
@@ -205,14 +260,8 @@ class BarCustom extends ChartComponent {
|
|
|
205
260
|
window.removeEventListener('resize', this.handleResize);
|
|
206
261
|
}
|
|
207
262
|
render() {
|
|
208
|
-
const {
|
|
209
|
-
chart
|
|
210
|
-
} = this.props;
|
|
211
263
|
return /*#__PURE__*/React.createElement("div", {
|
|
212
|
-
className:
|
|
213
|
-
'show-x-axis-label': this.isShowXAxisLabel(chart),
|
|
214
|
-
'show-y-axis-label': this.isShowYAxisLabel(chart)
|
|
215
|
-
}),
|
|
264
|
+
className: "sea-chart-container",
|
|
216
265
|
ref: ref => this.container = ref
|
|
217
266
|
});
|
|
218
267
|
}
|