sea-chart 2.0.33 → 2.0.35

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.
@@ -23,8 +23,7 @@ const TypesDialog = _ref => {
23
23
  lang,
24
24
  onToggle: propsOnToggle,
25
25
  onChange,
26
- dataSources,
27
- hideTypeToggle
26
+ dataSources
28
27
  } = _ref;
29
28
  const [currentCatIndex, setCurrentCatIndex] = (0, _react.useState)(0);
30
29
  const [selectedType, setType] = (0, _react.useState)(type);
@@ -67,13 +66,6 @@ const TypesDialog = _ref => {
67
66
  onChange(selectedType);
68
67
  onToggle();
69
68
  }, [onChange, selectedType, onToggle]);
70
- const handleFilterTypes = (0, _react.useCallback)(() => {
71
- if (hideTypeToggle) {
72
- const newChartTypes = _constants.CHART_TYPES.filter(item => ['Histogram', 'Bar_chart', 'Line_chart', 'Area', 'Pie_chart', 'Scatter_chart', 'Combination_chart', 'Map', 'Heat_map', 'Facet_chart', 'Gauge', 'Tree_map'].includes(item.name));
73
- return newChartTypes;
74
- }
75
- return _constants.CHART_TYPES;
76
- }, [hideTypeToggle]);
77
69
  return /*#__PURE__*/_react.default.createElement(_reactstrap.Modal, {
78
70
  isOpen: true,
79
71
  toggle: onToggle,
@@ -86,7 +78,7 @@ const TypesDialog = _ref => {
86
78
  className: "sea-chart-types-container d-flex flex-column h-100"
87
79
  }, /*#__PURE__*/_react.default.createElement("ul", {
88
80
  className: "sea-chart-chart-categories-nav flex-shrink-0 d-flex flex-wrap align-items-center list-unstyled"
89
- }, handleFilterTypes().map((item, index) => {
81
+ }, _constants.CHART_TYPES.map((item, index) => {
90
82
  return /*#__PURE__*/_react.default.createElement("li", {
91
83
  key: index,
92
84
  className: "px-4 py-2 sea-chart-chart-cat-nav-item"
@@ -108,7 +100,7 @@ const TypesDialog = _ref => {
108
100
  })), /*#__PURE__*/_react.default.createElement("div", {
109
101
  className: "flex-fill o-auto sea-chart-type-container",
110
102
  ref: seaChartTypeContainerRef
111
- }, handleFilterTypes().map((item, index) => {
103
+ }, _constants.CHART_TYPES.map((item, index) => {
112
104
  return /*#__PURE__*/_react.default.createElement("div", {
113
105
  key: "sea-chart-type-".concat(index),
114
106
  className: "mb-7"
@@ -41,8 +41,7 @@ const Settings = _ref => {
41
41
  children,
42
42
  departments,
43
43
  globalTheme,
44
- lang,
45
- hideTypeToggle
44
+ lang
46
45
  } = _ref;
47
46
  const [type, setType] = (0, _react.useState)(_constants.CHART_SETTINGS_TYPE.DATA);
48
47
  const [labelColorConfigs, setLabelColorConfigs] = (0, _react.useState)([]);
@@ -98,8 +97,7 @@ const Settings = _ref => {
98
97
  }
99
98
  }, /*#__PURE__*/_react.default.createElement(_contexts.settingsContext.Provider, {
100
99
  value: {
101
- hideTitleStyleSetting,
102
- hideTypeToggle
100
+ hideTitleStyleSetting
103
101
  }
104
102
  }, /*#__PURE__*/_react.default.createElement("div", {
105
103
  className: "sea-chart-settings"
@@ -144,7 +142,6 @@ const settingsPropTypes = exports.settingsPropTypes = {
144
142
  title: _propTypes.default.object,
145
143
  hideTitleStyleSetting: _propTypes.default.bool,
146
144
  children: _propTypes.default.any,
147
- onChange: _propTypes.default.func.isRequired,
148
- hideTypeToggle: _propTypes.default.bool
145
+ onChange: _propTypes.default.func.isRequired
149
146
  };
150
147
  var _default = exports.default = Settings;
@@ -10,7 +10,6 @@ var _react = _interopRequireWildcard(require("react"));
10
10
  var _reactstrap = require("reactstrap");
11
11
  var _constants = require("../../../constants");
12
12
  var _utils = require("../../../utils");
13
- var _contexts = require("../../../utils/contexts");
14
13
  var _intl = _interopRequireDefault(require("../../../intl"));
15
14
  var _components = require("../../../components");
16
15
  require("./index.css");
@@ -21,9 +20,6 @@ const ChartType = _ref => {
21
20
  onChange,
22
21
  dataSources
23
22
  } = _ref;
24
- const {
25
- hideTypeToggle
26
- } = (0, _react.useContext)(_contexts.settingsContext);
27
23
  const [isDialogShow, setDialogShow] = (0, _react.useState)(false);
28
24
  const openTypesDialog = (0, _react.useCallback)(event => {
29
25
  (0, _utils.eventStopPropagation)(event);
@@ -74,8 +70,7 @@ const ChartType = _ref => {
74
70
  dataSources: dataSources,
75
71
  type: type,
76
72
  onToggle: closeTypesDialog,
77
- onChange: onTypeChange,
78
- hideTypeToggle: hideTypeToggle
73
+ onChange: onTypeChange
79
74
  }));
80
75
  };
81
76
  var _default = exports.default = ChartType;
@@ -0,0 +1,305 @@
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 _lodashEs = require("lodash-es");
12
+ var d3 = _interopRequireWildcard(require("d3"));
13
+ var _classnames = _interopRequireDefault(require("classnames"));
14
+ var _constants = require("../../constants");
15
+ var _utils = require("../../utils");
16
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
17
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
18
+ class Funnel extends _chartComponent.default {
19
+ constructor(props) {
20
+ super(props);
21
+ this.handleResize = () => {
22
+ this.destroyChart();
23
+ this.createChart();
24
+ this.drawChart();
25
+ };
26
+ this.createChart = () => {
27
+ const {
28
+ chart
29
+ } = this.props;
30
+ const initConfig = {
31
+ insertPadding: 30
32
+ };
33
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
34
+ };
35
+ this.drawChart = () => {
36
+ const {
37
+ chart,
38
+ result: data
39
+ } = this.props;
40
+ const {
41
+ x_axis_option_list,
42
+ funnel_accumulate_values
43
+ } = chart.config;
44
+ if (!x_axis_option_list.length) return;
45
+ const sortedData = (0, _utils.getSortedDataByGivenOrder)(data, x_axis_option_list);
46
+ const formatSortedData = this.formatSortedData(sortedData, funnel_accumulate_values);
47
+ this.draw(formatSortedData);
48
+ };
49
+ this.showTooltip = (event, data, title, colorScale) => {
50
+ const {
51
+ summaryColumn,
52
+ chart
53
+ } = this.props;
54
+ const {
55
+ y_axis_summary_method
56
+ } = chart.config;
57
+ const {
58
+ offsetX,
59
+ offsetY
60
+ } = event;
61
+ const newTooltipData = {
62
+ title: title,
63
+ items: [{
64
+ color: colorScale(data === null || data === void 0 ? void 0 : data.name),
65
+ name: data === null || data === void 0 ? void 0 : data.name,
66
+ value: _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, Number(data === null || data === void 0 ? void 0 : data.value), y_axis_summary_method)
67
+ }]
68
+ };
69
+ this.setState({
70
+ tooltipData: newTooltipData
71
+ });
72
+ this.setState({
73
+ toolTipPosition: {
74
+ offsetX,
75
+ offsetY
76
+ }
77
+ });
78
+ };
79
+ this.moveTooltip = event => {
80
+ const {
81
+ offsetX,
82
+ offsetY
83
+ } = event;
84
+ this.setState({
85
+ toolTipPosition: {
86
+ offsetX,
87
+ offsetY
88
+ }
89
+ });
90
+ };
91
+ this.hiddenTooltip = () => {
92
+ this.setState({
93
+ toolTipPosition: null
94
+ });
95
+ };
96
+ this.draw = data => {
97
+ const {
98
+ chart,
99
+ tables,
100
+ globalTheme
101
+ } = this.props;
102
+ const {
103
+ table_id,
104
+ y_axis_summary_type,
105
+ y_axis_column_key,
106
+ y_axis_summary_column_key,
107
+ funnel_show_legend,
108
+ funnel_label_position,
109
+ funnel_label_font_size,
110
+ funnel_label_format,
111
+ funnel_show_labels,
112
+ funnel_show_overall_rate
113
+ } = chart.config;
114
+ const {
115
+ width: chartWidth,
116
+ height: chartHeight,
117
+ insertPadding
118
+ } = this.chartBoundingClientRect;
119
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
120
+ const isInside = funnel_label_position === _constants.FUNNEL_LABEL_POSITIONS.INSIDE;
121
+ const title = this.getTitle(tables, table_id, y_axis_summary_type, y_axis_column_key || y_axis_summary_column_key);
122
+ const nameDomain = new Set(data.map(item => item.name));
123
+
124
+ // Color scale
125
+ const colorScale = d3.scaleOrdinal().domain(nameDomain).range(['#0050B3', '#1890FF', '#40A9FF', '#69C0FF', '#BAE7FF']);
126
+
127
+ // Y scale
128
+ const y = d3.scaleBand().domain(nameDomain).range([insertPadding, chartHeight - insertPadding]).paddingInner(0).paddingOuter(0);
129
+
130
+ // X scale
131
+ const x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([insertPadding, chartWidth - insertPadding]);
132
+
133
+ // Content
134
+ const contentWrapper = this.chart.append('g').attr('class', 'content-wrapper');
135
+ const allWidth = chartWidth - insertPadding * 2;
136
+ data.forEach((_ref, index) => {
137
+ let {
138
+ name: curName,
139
+ value: curValue
140
+ } = _ref;
141
+ const curOffsetX = (allWidth - (x(curValue) - x(0))) / 2;
142
+ let points3X = x(curValue) + curOffsetX;
143
+ let points3Y = y(curName) + y.bandwidth();
144
+ let points4X = x(0) + curOffsetX;
145
+ let points4Y = y(curName) + +y.bandwidth();
146
+ const nextD = data[index + 1];
147
+ if (nextD) {
148
+ const {
149
+ name: nextName,
150
+ value: nextValue
151
+ } = nextD;
152
+ const nextOffsetX = (allWidth - (x(nextValue) - x(0))) / 2;
153
+ points3X = x(nextValue) + nextOffsetX;
154
+ points3Y = y(nextName);
155
+ points4X = x(0) + nextOffsetX;
156
+ points4Y = y(nextName);
157
+ }
158
+ contentWrapper.append('polygon').attr('opacity', 1).attr('fill', colorScale(curName)).attr('points', "\n ".concat(x(0) + curOffsetX, ",").concat(y(curName), "\n ").concat(x(curValue) + curOffsetX, ",").concat(y(curName), "\n ").concat(points3X, ",").concat(points3Y, "\n ").concat(points4X, ",").concat(points4Y, "\n ")).attr('data-left', "".concat(Math.min(x(0) + curOffsetX, points4X))).attr('data-top', "".concat(y(curName))).attr('data-name', curName).call(g => {
159
+ Array.from(g.node().parentNode.children).forEach((g, index) => {
160
+ // Add label
161
+ if (funnel_show_labels) {
162
+ const left = Number(g.getAttribute('data-left'));
163
+ const top = Number(g.getAttribute('data-top'));
164
+ const name = g.getAttribute('data-name');
165
+ const {
166
+ width: gWidth,
167
+ height: gHeight
168
+ } = g.getBoundingClientRect();
169
+
170
+ // name
171
+ contentWrapper.append('text').attr('class', 'label-name').attr('stroke', '#fff').attr('stroke-width', 0.5).attr('paint-order', 'stroke').attr('fill', isInside ? '#fff' : theme.labelColor).attr('font-size', funnel_label_font_size).text(name).call(g => {
172
+ const {
173
+ width,
174
+ height
175
+ } = g.node().getBoundingClientRect();
176
+ const x = isInside ? left + gWidth / 2 - width / 2 : left - width - 5; // add offsetX is 5
177
+ const y = isInside ? top + height + 10 : top + gHeight / 2 + height / 2; // add offsetY is 10
178
+ g.attr('x', x);
179
+ g.attr('y', y);
180
+ });
181
+
182
+ // content
183
+ const obj = data.find(item => item.name === name);
184
+ contentWrapper.append('text').attr('class', 'label-content').attr('stroke', '#fff').attr('stroke-width', 0.5).attr('paint-order', 'stroke').attr('fill', '#fff').attr('font-size', funnel_label_font_size).text(this.contentFormatterMap[funnel_label_format](obj)).call(g => {
185
+ const {
186
+ width,
187
+ height
188
+ } = g.node().getBoundingClientRect();
189
+ g.attr('x', left + gWidth / 2 - width / 2);
190
+ g.attr('y', top + gHeight / 2 + height / 2);
191
+ });
192
+
193
+ // total
194
+ if (funnel_show_overall_rate && index === 0) {
195
+ var _data;
196
+ contentWrapper.append('text').attr('class', 'label-total').attr('fill', theme.labelColor).attr('font-size', funnel_label_font_size).text((((_data = data[data.length - 1]) === null || _data === void 0 ? void 0 : _data.percent) || 0) + '%').call(g => {
197
+ const {
198
+ width
199
+ } = g.node().getBoundingClientRect();
200
+ g.attr('x', left + gWidth / 2 - width / 2);
201
+ g.attr('y', top - 5); // add offsetY is 5
202
+ });
203
+ }
204
+ }
205
+ });
206
+ }).on('click', () => {
207
+ this.props.toggleRecords(data[index]);
208
+ }).on('mouseover', event => {
209
+ this.showTooltip(event, data[index], title, colorScale);
210
+ }).on('mousemove', event => {
211
+ this.moveTooltip(event);
212
+ }).on('mouseleave', event => {
213
+ this.hiddenTooltip(event);
214
+ });
215
+ });
216
+ if (funnel_show_legend) {
217
+ this.setLegend({
218
+ legendName: 'name',
219
+ theme,
220
+ legendPosition: 'top-right',
221
+ data,
222
+ chart,
223
+ colorScale
224
+ });
225
+ }
226
+ };
227
+ this.formatSortedData = (sortedData, funnel_accumulate_values) => {
228
+ sortedData.total = 0;
229
+ sortedData.forEach(item => {
230
+ sortedData.total += item.value;
231
+ });
232
+ if (funnel_accumulate_values) {
233
+ for (let i = sortedData.length - 2; i >= 0; i--) {
234
+ sortedData[i].value += sortedData[i + 1].value;
235
+ }
236
+ }
237
+ sortedData.forEach(item => {
238
+ item.percent = sortedData.total === 0 ? 0 : (item.value / sortedData.total * 100).toFixed(2);
239
+ });
240
+ return sortedData;
241
+ };
242
+ this.chart = null;
243
+ this.state = {
244
+ tooltipData: null,
245
+ toolTipPosition: null
246
+ };
247
+ this.contentFormatterMap = {
248
+ [_constants.FUNNEL_LABEL_FORMAT.NUMBER]: obj => obj === null || obj === void 0 ? void 0 : obj.value,
249
+ [_constants.FUNNEL_LABEL_FORMAT.PERCENTAGE]: obj => ((obj === null || obj === void 0 ? void 0 : obj.percent) || 0) + '%',
250
+ [_constants.FUNNEL_LABEL_FORMAT.NUMBER_AND_PERCENTAGE]: obj => "".concat(obj === null || obj === void 0 ? void 0 : obj.value, " (").concat((obj === null || obj === void 0 ? void 0 : obj.percent) || 0, "%)")
251
+ };
252
+ }
253
+ componentDidMount() {
254
+ this.createChart();
255
+ this.drawChart();
256
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
257
+ window.addEventListener('resize', this.debouncedHandleResize);
258
+ }
259
+ componentDidUpdate(prevProps) {
260
+ super.componentDidUpdate(prevProps);
261
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
262
+ this.destroyChart();
263
+ this.createChart();
264
+ this.drawChart();
265
+ }
266
+ }
267
+ componentWillUnmount() {
268
+ this.destroyChart();
269
+ window.removeEventListener('resize', this.debouncedHandleResize);
270
+ }
271
+ render() {
272
+ const {
273
+ chart
274
+ } = this.props;
275
+ const {
276
+ tooltipData,
277
+ toolTipPosition
278
+ } = this.state;
279
+ return /*#__PURE__*/_react.default.createElement("div", {
280
+ ref: ref => this.container = ref,
281
+ className: (0, _classnames.default)('sea-chart-container', {
282
+ 'show-x-axis-label': this.isShowXAxisLabel(chart),
283
+ 'show-y-axis-label': this.isShowYAxisLabel(chart)
284
+ })
285
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
286
+ tooltipData: tooltipData,
287
+ toolTipPosition: toolTipPosition,
288
+ chart: this.chart
289
+ }));
290
+ }
291
+ }
292
+ Funnel.propTypes = {
293
+ canvasStyle: _propTypes.default.object,
294
+ chart: _propTypes.default.object,
295
+ groupbyColumn: _propTypes.default.object,
296
+ columnGroupbyColumn: _propTypes.default.object,
297
+ summaryColumn: _propTypes.default.object,
298
+ result: _propTypes.default.array,
299
+ tables: _propTypes.default.array,
300
+ globalTheme: _propTypes.default.string,
301
+ chartColorTheme: _propTypes.default.string,
302
+ toggleRecords: _propTypes.default.func,
303
+ customRender: _propTypes.default.func
304
+ };
305
+ var _default = exports.default = Funnel;
@@ -38,6 +38,7 @@ var _heatMap = _interopRequireDefault(require("./heat-map"));
38
38
  var _mirror = _interopRequireDefault(require("./mirror"));
39
39
  var _dashboard = _interopRequireDefault(require("./dashboard"));
40
40
  var _treemap = _interopRequireDefault(require("./treemap"));
41
+ var _funnel = _interopRequireDefault(require("./funnel"));
41
42
  var _trend = _interopRequireDefault(require("./trend"));
42
43
  var _tableElement = _interopRequireDefault(require("./table-element"));
43
44
  const Wrapper = _ref => {
@@ -309,6 +310,12 @@ const Wrapper = _ref => {
309
310
  canvasStyle: canvasStyle
310
311
  }));
311
312
  }
313
+ case _constants.CHART_TYPE.FUNNEL:
314
+ {
315
+ return /*#__PURE__*/_react.default.createElement(_funnel.default, Object.assign({}, baseProps, {
316
+ canvasStyle: canvasStyle
317
+ }));
318
+ }
312
319
  case _constants.CHART_TYPE.BASIC_NUMBER_CARD:
313
320
  {
314
321
  return /*#__PURE__*/_react.default.createElement(_basicNumberCard.default, Object.assign({}, baseProps, {
@@ -135,8 +135,8 @@ class Treemap extends _chartComponent.default {
135
135
  t.attr('y', height / 2 - tHeight / 2);
136
136
  });
137
137
  });
138
- }).on('click', (event, data) => {
139
- this.props.toggleRecords(data);
138
+ }).on('click', (event, d) => {
139
+ this.props.toggleRecords(d.data);
140
140
  }).on('mouseover', (event, data) => {
141
141
  this.showTooltip(event, data);
142
142
  }).on('mousemove', event => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.33",
3
+ "version": "2.0.35",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",