sea-chart 2.0.8 → 2.0.10

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.
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ const ToolTip = _ref => {
10
+ let {
11
+ tooltipData,
12
+ toolTipPosition,
13
+ chart
14
+ } = _ref;
15
+ const tooltipRef = (0, _react.useRef)(null);
16
+ const [position, setPosition] = (0, _react.useState)({
17
+ offsetX: -9999,
18
+ offsetY: -9999
19
+ });
20
+ const {
21
+ title,
22
+ items
23
+ } = tooltipData || {
24
+ title: '',
25
+ items: []
26
+ };
27
+ (0, _react.useEffect)(() => {
28
+ if (!toolTipPosition) {
29
+ setPosition({
30
+ offsetX: -9999,
31
+ offsetY: -9999
32
+ });
33
+ return;
34
+ }
35
+ if (chart && toolTipPosition) {
36
+ const width = Number(chart.node().getAttribute('width'));
37
+ const height = Number(chart.node().getAttribute('height'));
38
+ const {
39
+ height: tooltipHeight,
40
+ width: tooltipWidth
41
+ } = tooltipRef.current.getBoundingClientRect();
42
+ const {
43
+ offsetX,
44
+ offsetY
45
+ } = toolTipPosition;
46
+ const distance = 30;
47
+ const insertPadding = 30;
48
+ let translateX = offsetX + distance;
49
+ let translateY = offsetY;
50
+ const endOffsetX = offsetX + distance + tooltipWidth + insertPadding;
51
+ const endOffsetY = offsetY + tooltipHeight + insertPadding;
52
+ // Right overflow
53
+ if (endOffsetX > width) {
54
+ translateX = offsetX - distance - tooltipWidth - insertPadding;
55
+ }
56
+ // Bottom overflow
57
+ if (endOffsetY > height) {
58
+ translateY = offsetY - (endOffsetY - height);
59
+ }
60
+ setPosition({
61
+ offsetX: translateX,
62
+ offsetY: translateY
63
+ });
64
+ }
65
+ }, [chart, toolTipPosition, tooltipRef]);
66
+ return /*#__PURE__*/_react.default.createElement("div", {
67
+ ref: tooltipRef,
68
+ className: "sea-chart-d3-tooltip-container",
69
+ style: {
70
+ transform: "translate(".concat(position.offsetX, "px, ").concat(position.offsetY, "px)")
71
+ }
72
+ }, /*#__PURE__*/_react.default.createElement("div", {
73
+ className: "sea-chart-d3-tooltip-title"
74
+ }, title), /*#__PURE__*/_react.default.createElement("ul", {
75
+ className: "sea-chart-d3-tooltip-list"
76
+ }, items.map((item, index) => {
77
+ return /*#__PURE__*/_react.default.createElement("li", {
78
+ className: "sea-chart-d3-tooltip-list-item",
79
+ key: index
80
+ }, /*#__PURE__*/_react.default.createElement("span", {
81
+ className: "sea-chart-d3-tooltip-marker",
82
+ style: {
83
+ backgroundColor: item.color
84
+ }
85
+ }), /*#__PURE__*/_react.default.createElement("span", {
86
+ className: "sea-chart-d3-tooltip-name"
87
+ }, item.name), /*#__PURE__*/_react.default.createElement("span", {
88
+ className: "sea-chart-d3-tooltip-value"
89
+ }, item.value));
90
+ })));
91
+ };
92
+ var _default = exports.default = ToolTip;
@@ -69,10 +69,8 @@ const TypesDialog = _ref => {
69
69
  }, [onChange, selectedType, onToggle]);
70
70
  const handleFilterTypes = (0, _react.useCallback)(() => {
71
71
  if (hideTypeToggle) {
72
- const newChartTypes = _constants.CHART_TYPES.filter(item => ['Histogram'].includes(item.name));
73
- newChartTypes.forEach(item => {
74
- item.children = item.children.slice(0, 3);
75
- });
72
+ const newChartTypes = _constants.CHART_TYPES.filter(item => ['Histogram', 'Bar_chart'].includes(item.name));
73
+ newChartTypes[1].children = newChartTypes[1].children.slice(0, 2);
76
74
  return newChartTypes;
77
75
  }
78
76
  return _constants.CHART_TYPES;
@@ -306,7 +306,7 @@ const BAR_MAP_TO_HORIZONTAL_MAP = exports.BAR_MAP_TO_HORIZONTAL_MAP = {
306
306
  y_axis_label_color: 'horizontal_axis_label_color',
307
307
  y_axis_auto_range: 'horizontal_axis_auto_range',
308
308
  y_axis_max: 'horizontal_axis_max',
309
- y_axis_mix: 'horizontal_axis_min'
309
+ y_axis_min: 'horizontal_axis_min'
310
310
  };
311
311
  const DEFAULT_NUMBER_FORMAT_OBJECT = exports.DEFAULT_NUMBER_FORMAT_OBJECT = {
312
312
  format: _dtableUtils.DEFAULT_NUMBER_FORMAT
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+ var d3 = _interopRequireWildcard(require("d3"));
12
+ var _classnames = _interopRequireDefault(require("classnames"));
13
+ var _dtableUtils = require("dtable-utils");
14
+ var _constants = require("../../constants");
15
+ var _chartUtils = require("../../utils/chart-utils");
16
+ var _intl = _interopRequireDefault(require("../../intl"));
17
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
18
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
19
+ class BarCompare extends _chartComponent.default {
20
+ constructor(props) {
21
+ super(props);
22
+ this.createChart = () => {
23
+ const {
24
+ chart
25
+ } = this.props;
26
+ const {
27
+ y_axis_show_label,
28
+ x_axis_show_label
29
+ } = chart.config;
30
+ const initConfig = {
31
+ insertPadding: 30,
32
+ borderRadius: 0.2,
33
+ marginLeft: y_axis_show_label ? 20 : 0,
34
+ marginBottom: x_axis_show_label ? 20 : 0
35
+ };
36
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
37
+ };
38
+ this.drawChart = () => {
39
+ let {
40
+ result: data
41
+ } = this.props;
42
+ data = _chartUtils.BaseUtils.formatEmptyName(data, '', _intl.default.get('Empty'));
43
+ if (!Array.isArray(data)) return;
44
+ this.draw(data);
45
+ this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
46
+ };
47
+ this.draw = data => {
48
+ const {
49
+ chart,
50
+ globalTheme,
51
+ chartColorTheme
52
+ } = this.props;
53
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
54
+ const {
55
+ display_increase,
56
+ y_axis_auto_range,
57
+ y_axis_min,
58
+ y_axis_max
59
+ } = chart.config;
60
+ const {
61
+ width: chartWidth,
62
+ height: chartHeight,
63
+ insertPadding
64
+ } = this.chartBoundingClientRect;
65
+ data = data.sort((a, b) => d3.ascending(a.name, b.name));
66
+ const fx = d3.scaleBand().domain(d3.group(data, d => d.name).keys()).range([insertPadding, chartWidth - insertPadding]).paddingInner(0.1).paddingOuter(0.1);
67
+ const color = d3.scaleOrdinal().domain(d3.group(data, d => d.group_name).keys()).range(_chartUtils.BaseUtils.getCurrentTheme(chartColorTheme).colors).unknown('#ccc');
68
+ const x = d3.scaleBand().domain(d3.group(data, d => d.group_name).keys()).range([0, fx.bandwidth()]);
69
+ const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, d3.max(data, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding]);
70
+
71
+ // X axis
72
+ this.chart.append('g').attr('transform', "translate(0,".concat(chartHeight - insertPadding, ")")).call(d3.axisBottom(fx).tickSizeOuter(0).tickSizeInner(5)).call(g => {
73
+ g.selectAll('.domain').attr('stroke', theme.XAxisColor);
74
+ g.selectAll('.tick line').attr('stroke', theme.XAxisColor);
75
+ g.selectAll('text').attr('font-size', theme.fontSize);
76
+ g.selectAll('text').attr('fill', theme.textColor);
77
+ });
78
+
79
+ // Y axis
80
+ this.chart.append('g').attr('transform', "translate(".concat(insertPadding, ",0)")).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => d)).call(g => {
81
+ g.select('.domain').remove();
82
+ g.selectAll('line').node() && g.selectAll('line').node().remove(); // delete the first line
83
+ g.selectAll('.tick line').clone().attr('x2', chartWidth - insertPadding * 2).attr('stroke', theme.gridColor).attr('stroke-dasharray', '8,3');
84
+ g.selectAll('text').attr('font-size', theme.fontSize);
85
+ g.selectAll('text').attr('fill', theme.textColor);
86
+ });
87
+
88
+ // Rect group
89
+ this.chart.append('g').attr('class', "rects-wrapper-".concat(chart === null || chart === void 0 ? void 0 : chart.id)).selectAll().data(() => d3.group(data, d => d.name)).join('g').attr('transform', _ref => {
90
+ let [name, dum] = _ref;
91
+ // Each group is horizontally centered
92
+ const offset = (fx.bandwidth() - dum.length * x.bandwidth()) / 2;
93
+ return "translate(".concat(fx(name) + offset, ",0)");
94
+ })
95
+ // rect item
96
+ .selectAll().data(_ref2 => {
97
+ let [a, d] = _ref2;
98
+ return d;
99
+ }).join('rect').attr('x', (d, index) => index * x.bandwidth()).attr('y', d => y(d.value)).attr('width', x.bandwidth()).attr('height', d => y(0) - y(d.value) === 0 ? 0 : y(0) - y(d.value)).attr('fill', d => color(d.group_name)).attr('data-value', d => d.value).attr('data-groupName', d => d.name).attr('data-slugid', d => d.slugId).call(g => {
100
+ g.nodes().forEach(rect => {
101
+ const parentNode = rect.parentNode;
102
+ // add rect borderRadius
103
+ this.addClipPath({
104
+ rect,
105
+ parentNode,
106
+ rectId: rect.getAttribute('data-slugid')
107
+ });
108
+ });
109
+ }).on('click', (event, data) => {
110
+ this.props.toggleRecords(data);
111
+ }).on('mouseover', event => {
112
+ this.showTooltip(event, color);
113
+ this.handleAcitveAndInActiveState('inActive', event);
114
+ }).on('mousemove', event => {
115
+ this.moveTooltip(event, color);
116
+ }).on('mouseleave', event => {
117
+ this.hiddenTooltip();
118
+ this.handleAcitveAndInActiveState('active', event);
119
+ });
120
+ if (display_increase) {
121
+ const increaseData = this.getIncreaseData(data);
122
+ this.drawIncreaseLine(increaseData);
123
+ }
124
+ this.setColorMap(data, chartColorTheme);
125
+ this.setLegend({
126
+ legendName: 'group_name',
127
+ theme,
128
+ legendPosition: 'top-right',
129
+ data
130
+ });
131
+ };
132
+ this.showTooltip = (event, colorScale, isCircle) => {
133
+ const {
134
+ y_axis_summary_type,
135
+ y_axis_summary_method,
136
+ increase_line_color
137
+ } = this.props.chart.config;
138
+ const {
139
+ offsetX,
140
+ offsetY
141
+ } = event;
142
+ let newTooltipData = {};
143
+ if (isCircle) {
144
+ const circleEl = event.target;
145
+ newTooltipData = {
146
+ title: _intl.default.get(_constants.TITLE_INCREASE),
147
+ items: [{
148
+ color: increase_line_color || '#fbd44a',
149
+ name: circleEl.getAttribute('data-name'),
150
+ value: circleEl.getAttribute('data-text')
151
+ }]
152
+ };
153
+ } else {
154
+ const curGroup = event.target.parentNode;
155
+ const [, data] = curGroup.__data__;
156
+ newTooltipData = {
157
+ title: y_axis_summary_type === 'count' ? _intl.default.get(_constants.TITLE_AMOUNT) : _intl.default.get(_constants.CHART_SUMMARY_SHOW[y_axis_summary_method]),
158
+ items: data.map(item => {
159
+ return {
160
+ color: colorScale(item.group_name),
161
+ name: item.group_name,
162
+ value: item.value
163
+ };
164
+ })
165
+ };
166
+ }
167
+ this.setState({
168
+ tooltipData: newTooltipData
169
+ });
170
+ this.setState({
171
+ toolTipPosition: {
172
+ offsetX,
173
+ offsetY
174
+ }
175
+ });
176
+ };
177
+ this.moveTooltip = event => {
178
+ const {
179
+ offsetX,
180
+ offsetY
181
+ } = event;
182
+ this.setState({
183
+ toolTipPosition: {
184
+ offsetX,
185
+ offsetY
186
+ }
187
+ });
188
+ };
189
+ this.hiddenTooltip = event => {
190
+ this.setState({
191
+ toolTipPosition: null
192
+ });
193
+ };
194
+ this.drawIncreaseLine = increaseData => {
195
+ const {
196
+ chart,
197
+ globalTheme
198
+ } = this.props;
199
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
200
+ const {
201
+ label_font_size,
202
+ y_axis_auto_range,
203
+ y_axis_min,
204
+ y_axis_max,
205
+ increase_line_color,
206
+ display_increase_percentage
207
+ } = chart.config;
208
+ const {
209
+ width: chartWidth,
210
+ height: chartHeight,
211
+ insertPadding
212
+ } = this.chartBoundingClientRect;
213
+ const circleData = increaseData.map(() => ({}));
214
+ const lineX = d3.scaleBand().domain(increaseData.map(d => d.name)).range([insertPadding, chartWidth - insertPadding]).paddingInner(0.1).paddingOuter(0.1);
215
+ const lineY = d3.scaleLinear().domain(y_axis_auto_range ? [d3.min(increaseData, d => d.value), d3.max(increaseData, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding]);
216
+ const line = d3.line().x((d, index) => {
217
+ const x = lineX(d.name) + lineX.bandwidth() / 2;
218
+ circleData[index]['x'] = x;
219
+ circleData[index]['name'] = d.name;
220
+ return x;
221
+ }).y((d, index) => {
222
+ const y = lineY(d.value);
223
+ circleData[index]['y'] = y;
224
+ circleData[index]['value'] = d.formatValue;
225
+ return y;
226
+ }).curve(d3.curveBumpX);
227
+ const wrapper = this.chart.append('g').attr('class', "increase-line-wrapper-".concat(chart === null || chart === void 0 ? void 0 : chart.id));
228
+
229
+ // line
230
+ wrapper.append('path').attr('fill', 'none').attr('stroke', increase_line_color || '#fbd44a').attr('stroke-width', 2).attr('d', () => line(increaseData));
231
+
232
+ // circle
233
+ circleData.forEach(item => {
234
+ wrapper.append('circle').attr('cx', item.x).attr('cy', item.y).attr('r', 3).attr('fill', increase_line_color || '#fbd44a').attr('data-text', item.value).attr('data-name', item.name).call(g => {
235
+ // circle label
236
+ if (display_increase_percentage) {
237
+ const curCircleEl = g.node();
238
+ wrapper.append('text').attr('fill', theme.labelColor).attr('font-size', _chartUtils.BaseUtils.getLabelFontSize(label_font_size)).text(curCircleEl.getAttribute('data-text')).call(g => {
239
+ const {
240
+ width
241
+ } = g.node().getBoundingClientRect();
242
+ const translateX = Number(curCircleEl.getAttribute('cx')) - width / 2;
243
+ const translateY = Number(curCircleEl.getAttribute('cy')) - 10;
244
+ g.attr('transform', "translate(".concat(translateX, ", ").concat(translateY, ")"));
245
+ });
246
+ }
247
+ }).on('mouseover', event => {
248
+ this.updateCircleStyle(event, 'zoomIn');
249
+ this.showTooltip(event, '', true);
250
+ }).on('mousemove', event => {
251
+ this.moveTooltip(event);
252
+ }).on('mouseleave', event => {
253
+ this.hiddenTooltip();
254
+ this.updateCircleStyle(event, 'zoomOut');
255
+ });
256
+ });
257
+ };
258
+ this.getIncreaseData = data => {
259
+ const increaseData = [];
260
+ d3.group(data, d => d.name).forEach((value, key) => {
261
+ var _increaseValue$, _increaseValue$2;
262
+ const increaseValue = value.filter(d => (d === null || d === void 0 ? void 0 : d.increase_value) !== undefined) || [{
263
+ increaseValue: 0
264
+ }];
265
+ const formatValue = (0, _dtableUtils.getNumberDisplayString)((_increaseValue$ = increaseValue[0]) === null || _increaseValue$ === void 0 ? void 0 : _increaseValue$.increase_value, {
266
+ format: 'percent'
267
+ });
268
+ const data = {
269
+ name: key,
270
+ value: ((_increaseValue$2 = increaseValue[0]) === null || _increaseValue$2 === void 0 ? void 0 : _increaseValue$2.increase_value) || 0,
271
+ formatValue: formatValue || '0%',
272
+ rowData: value
273
+ };
274
+ increaseData.push(data);
275
+ });
276
+ return increaseData;
277
+ };
278
+ this.updateCircleStyle = (event, state) => {
279
+ if (state === 'zoomIn') {
280
+ d3.select(event.currentTarget).attr('r', 5);
281
+ return;
282
+ }
283
+ const circles = d3.select(event.currentTarget.parentNode).selectAll('circle').nodes();
284
+ circles.forEach(circle => d3.select(circle).attr('r', 3));
285
+ };
286
+ this.handleAcitveAndInActiveState = (state, event) => {
287
+ const curGroup = event.target.parentNode;
288
+ const allGroup = Array.from(curGroup.parentNode.children);
289
+ const [curGroupName] = curGroup.__data__;
290
+ this.setActiveAndInActiveState(state, allGroup, curGroupName);
291
+ };
292
+ this.chart = null;
293
+ this.state = {
294
+ tooltipData: null,
295
+ toolTipPosition: null
296
+ };
297
+ }
298
+ componentDidMount() {
299
+ this.createChart();
300
+ this.drawChart();
301
+ }
302
+ componentDidUpdate(prevProps) {
303
+ super.componentDidUpdate(prevProps);
304
+ if (_chartUtils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
305
+ this.createChart();
306
+ this.drawChart();
307
+ }
308
+ }
309
+ componentWillUnmount() {
310
+ this.chart.node() && this.chart.node().remove();
311
+ }
312
+ render() {
313
+ const {
314
+ chart
315
+ } = this.props;
316
+ const {
317
+ tooltipData,
318
+ toolTipPosition
319
+ } = this.state;
320
+ return /*#__PURE__*/_react.default.createElement("div", {
321
+ ref: ref => this.container = ref,
322
+ className: (0, _classnames.default)('sea-chart-container', {
323
+ 'show-x-axis-label': this.isShowXAxisLabel(chart),
324
+ 'show-y-axis-label': this.isShowYAxisLabel(chart)
325
+ })
326
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
327
+ tooltipData: tooltipData,
328
+ toolTipPosition: toolTipPosition,
329
+ chart: this.chart
330
+ }));
331
+ }
332
+ }
333
+ BarCompare.propTypes = {
334
+ canvasStyle: _propTypes.default.object,
335
+ chart: _propTypes.default.object,
336
+ groupbyColumn: _propTypes.default.object,
337
+ columnGroupbyColumn: _propTypes.default.object,
338
+ summaryColumn: _propTypes.default.object,
339
+ result: _propTypes.default.array,
340
+ tables: _propTypes.default.array,
341
+ globalTheme: _propTypes.default.string,
342
+ chartColorTheme: _propTypes.default.string,
343
+ toggleRecords: _propTypes.default.func
344
+ };
345
+ var _default = exports.default = BarCompare;