sea-chart 1.1.26 → 1.1.28

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,107 @@
1
+ import { COLUMNS_ICON_CONFIG } from 'dtable-utils';
2
+ import React, { useEffect, useRef } from 'react';
3
+ import { UncontrolledPopover } from 'reactstrap';
4
+ import isHotkey from 'is-hotkey';
5
+ import intl from '../../../intl';
6
+ import { getEventClassName } from '../../../utils/common-utils';
7
+ import styles from './index.module.css';
8
+ export default function DrillDownFieldsPopover(_ref) {
9
+ let {
10
+ onPopoverToggle,
11
+ columns,
12
+ drillDownFields,
13
+ setDrillDownFields
14
+ } = _ref;
15
+ const isAllColumnsVisible = columns.every(c => drillDownFields.includes(c.key));
16
+ const toggleAllColumnsVisible = () => {
17
+ const visible = !isAllColumnsVisible;
18
+ const newDrillDownFields = visible ? columns.map(c => c.key) : ['0000'];
19
+ if (!newDrillDownFields.includes('0000')) newDrillDownFields.push('0000');
20
+ setDrillDownFields(newDrillDownFields);
21
+ };
22
+ const changeColumnVisible = (columnKey, visible) => {
23
+ if (visible) {
24
+ setDrillDownFields(drillDownFields.concat(columnKey));
25
+ } else {
26
+ setDrillDownFields(drillDownFields.filter(key => key !== columnKey));
27
+ }
28
+ };
29
+ const popoverRef = useRef(null);
30
+ const onPopoverInsideClick = e => {
31
+ e.stopPropagation();
32
+ };
33
+ useEffect(() => {
34
+ const hidePopover = e => {
35
+ if (popoverRef.current && !getEventClassName(e).includes('popover') && !popoverRef.current.contains(e.target)) {
36
+ onPopoverToggle(false);
37
+ e.preventDefault();
38
+ e.stopPropagation();
39
+ }
40
+ };
41
+ const onHotKey = e => {
42
+ if (isHotkey('esc', e)) {
43
+ e.preventDefault();
44
+ onPopoverToggle(false);
45
+ }
46
+ };
47
+ document.addEventListener('click', hidePopover);
48
+ document.addEventListener('keydown', onHotKey);
49
+ return () => {
50
+ document.removeEventListener('click', hidePopover);
51
+ document.removeEventListener('keydown', onHotKey);
52
+ };
53
+ }, [onPopoverToggle]);
54
+ return /*#__PURE__*/React.createElement(UncontrolledPopover, {
55
+ placement: "left",
56
+ isOpen: true,
57
+ target: "set-drill-down-fields",
58
+ fade: false,
59
+ hideArrow: true,
60
+ className: styles['drill-down-fields-popover'],
61
+ boundariesElement: document.body
62
+ }, /*#__PURE__*/React.createElement("div", {
63
+ ref: popoverRef,
64
+ onClick: onPopoverInsideClick
65
+ }, /*#__PURE__*/React.createElement("div", {
66
+ className: styles['drill-down-fields-container']
67
+ }, /*#__PURE__*/React.createElement("table", {
68
+ className: styles['drill-down-fields-table']
69
+ }, /*#__PURE__*/React.createElement("thead", {
70
+ className: styles['drill-down-fields-table-header']
71
+ }, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", {
72
+ width: "80%",
73
+ className: styles['text-truncate']
74
+ }, ''), /*#__PURE__*/React.createElement("th", {
75
+ width: "20%",
76
+ className: "".concat(styles['column-checkbox'], " pr-3")
77
+ }, intl.get('Visible')))), /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", {
78
+ className: styles['drill-down-fields-row']
79
+ }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("span", {
80
+ className: styles['drill-down-fields-select-all']
81
+ }, intl.get('Select_all'))), /*#__PURE__*/React.createElement("td", {
82
+ className: "".concat(styles['column-checkbox'], " pr-3")
83
+ }, /*#__PURE__*/React.createElement("input", {
84
+ type: "checkbox",
85
+ checked: isAllColumnsVisible,
86
+ onChange: toggleAllColumnsVisible
87
+ }))), columns.map(column => {
88
+ const visibleChecked = drillDownFields.includes(column.key);
89
+ const checkedByDefault = column.key === '0000';
90
+ return /*#__PURE__*/React.createElement("tr", {
91
+ key: column.key,
92
+ className: styles['drill-down-fields-row']
93
+ }, /*#__PURE__*/React.createElement("td", {
94
+ className: "pl-5 text-truncate",
95
+ title: column.name
96
+ }, /*#__PURE__*/React.createElement("i", {
97
+ className: "".concat(COLUMNS_ICON_CONFIG[column.type], " mr-2 ").concat(styles['drill-down-fields-icon'])
98
+ }), /*#__PURE__*/React.createElement("span", null, column.name)), /*#__PURE__*/React.createElement("td", {
99
+ className: "".concat(styles['column-checkbox'], " pr-3")
100
+ }, /*#__PURE__*/React.createElement("input", {
101
+ disabled: checkedByDefault,
102
+ type: "checkbox",
103
+ checked: visibleChecked,
104
+ onChange: () => changeColumnVisible(column.key, !visibleChecked)
105
+ })));
106
+ }))))));
107
+ }
@@ -0,0 +1,50 @@
1
+
2
+ .drill-down-fields-popover :global(.popover) {
3
+ max-width: 410px;
4
+ }
5
+
6
+ .drill-down-fields-container {
7
+ max-height: 380px;
8
+ display: flex;
9
+ flex-direction: column;
10
+ overflow: auto;
11
+ }
12
+
13
+ .drill-down-fields-table {
14
+ width: 100%;
15
+ line-height: 30px;
16
+ color: #212529;
17
+ font-size: 14px;
18
+ table-layout: fixed;
19
+ }
20
+
21
+ .drill-down-fields-table-header {
22
+ background-color: #f7f9fe;
23
+ border-top: 1px solid #eee;
24
+ line-height: 30px;
25
+ font-size: 14px;
26
+ }
27
+
28
+ .column-checkbox {
29
+ text-align: center;
30
+ }
31
+
32
+ .drill-down-fields-row {
33
+ border-bottom: 1px solid #eee;
34
+ }
35
+
36
+ .drill-down-fields-select-all {
37
+ margin-left: 1.5rem
38
+ }
39
+
40
+ .drill-down-fields-icon {
41
+ font-size: 14px;
42
+ color: #666;
43
+ }
44
+
45
+ table td {
46
+ padding: 0.5rem 0.1875rem;
47
+ border-bottom: 1px solid #eee;
48
+ font-size: 0.875rem;
49
+ word-break: break-all;
50
+ }
@@ -0,0 +1,30 @@
1
+ import React, { useState } from 'react';
2
+ import DrillDownFieldsPopover from '../drill-down-fields-popover';
3
+ import intl from '../../../intl';
4
+ import styles from './index.module.css';
5
+ export default function DrillDownFieldSettings(_ref) {
6
+ let {
7
+ columns,
8
+ drillDownFields,
9
+ setDrillDownFields
10
+ } = _ref;
11
+ const [isFieldsPopoverShow, setFieldsPopoverShow] = useState(false);
12
+ const handleFieldsPopoverShow = e => {
13
+ // stop event propagation to prevent tragger click handler inside of the popover
14
+ // otherwise popover close handler will be triggered immediately after component mounted becase click event is still bubbling
15
+ e.stopPropagation();
16
+ setFieldsPopoverShow(!isFieldsPopoverShow);
17
+ };
18
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
19
+ className: styles['drill-down-fields-btn'],
20
+ id: "set-drill-down-fields",
21
+ onClick: handleFieldsPopoverShow
22
+ }, /*#__PURE__*/React.createElement("span", {
23
+ className: "ml-2"
24
+ }, intl.get('Field_settings'))), isFieldsPopoverShow && /*#__PURE__*/React.createElement(DrillDownFieldsPopover, {
25
+ onPopoverToggle: setFieldsPopoverShow,
26
+ columns: columns,
27
+ drillDownFields: drillDownFields,
28
+ setDrillDownFields: setDrillDownFields
29
+ }));
30
+ }
@@ -0,0 +1,16 @@
1
+ .drill-down-fields-btn {
2
+ align-items: center;
3
+ border: 1px solid #acacac;
4
+ border-radius: 4px;
5
+ cursor: pointer;
6
+ display: flex;
7
+ height: 32px;
8
+ justify-content: center;
9
+ margin-top: 10px;
10
+ -webkit-user-select: none;
11
+ user-select: none;
12
+ }
13
+
14
+ .drill-down-fields-btn:hover {
15
+ background-color: #eee;
16
+ }
@@ -0,0 +1,25 @@
1
+ import _CollapsibleSettingLayout from "dtable-ui-component/lib/CollapsibleSettingLayout";
2
+ import _DTableSwitch from "dtable-ui-component/lib/DTableSwitch";
3
+ import React from 'react';
4
+ import intl from '../../intl';
5
+ import DrillDownFieldSettings from './drill-down-fields-settings';
6
+ export default function DrillDownSettings(_ref) {
7
+ let {
8
+ columns,
9
+ drillDownStatus,
10
+ toggleDrillDownStatus,
11
+ drillDownFields,
12
+ setDrillDownFields
13
+ } = _ref;
14
+ return /*#__PURE__*/React.createElement(_CollapsibleSettingLayout, {
15
+ title: intl.get('Drill_down_settings')
16
+ }, /*#__PURE__*/React.createElement(_DTableSwitch, {
17
+ onChange: toggleDrillDownStatus,
18
+ checked: drillDownStatus,
19
+ placeholder: intl.get('Enable_drill_down_feature')
20
+ }), drillDownStatus && /*#__PURE__*/React.createElement(DrillDownFieldSettings, {
21
+ columns: columns,
22
+ drillDownFields: drillDownFields,
23
+ setDrillDownFields: setDrillDownFields
24
+ }));
25
+ }
@@ -35,7 +35,8 @@ class StatisticRecordDialog extends React.Component {
35
35
  } = statisticRecord || {};
36
36
  const {
37
37
  table_id,
38
- view_id
38
+ view_id,
39
+ drill_down_fields
39
40
  } = chart.config;
40
41
  this.table = getTableById(tables, table_id);
41
42
  const currentElementId = chart.id;
@@ -44,7 +45,7 @@ class StatisticRecordDialog extends React.Component {
44
45
  this.isArchiveView = isArchiveView(this.view);
45
46
  }
46
47
  this.unShowColumnKeyList = this.getUnShowColumnKeyList(this.view);
47
- this.renderedColumns = this.getRenderedColumns(this.table);
48
+ this.renderedColumns = this.getRenderedColumns(this.table, drill_down_fields, isCalculateByView);
48
49
  if (this.isArchiveView || !isCalculateByView || statisticRecord.isQueryBySql) {
49
50
  var _context$api, _context$api2;
50
51
  if ((_context$api = context.api) === null || _context$api === void 0 ? void 0 : _context$api.customQueryRows) {
@@ -100,11 +101,18 @@ class StatisticRecordDialog extends React.Component {
100
101
  } = view;
101
102
  return [firstColumnKey, ...hidden_columns];
102
103
  };
103
- this.getRenderedColumns = table => {
104
+ this.getRenderedColumns = (table, drillDownFields, isCalculateByView) => {
104
105
  const {
105
106
  columns
106
107
  } = table;
107
- return columns.filter(column => !this.unShowColumnKeyList.includes(column.key));
108
+ const renderedColumns = columns.filter(column => !this.unShowColumnKeyList.includes(column.key));
109
+ // in dtable-statistics always show all columns
110
+ if (isCalculateByView || !drillDownFields) {
111
+ // use all columns as default
112
+ return renderedColumns;
113
+ } else {
114
+ return renderedColumns.filter(column => drillDownFields.includes(column.key));
115
+ }
108
116
  };
109
117
  this.processDrilledRows = drilledRows => {
110
118
  const {
@@ -265,6 +265,11 @@ const de = {
265
265
  "Show_overall_rate": "Gesamtpreisbeschriftung anzeigen",
266
266
  "Percentage": "Prozentsatz",
267
267
  "Number_and_percentage": "Anzahl und Prozentsatz",
268
- "No_record": "Keine Aufzeichnung"
268
+ "No_record": "Keine Aufzeichnung",
269
+ "Drill_down_settings": "Drilldown-Einstellungen",
270
+ "Enable_drill_down_feature": "Aktivieren Sie die Drilldown-Funktion",
271
+ "Field_settings": "Feldeinstellungen",
272
+ "Select_all": "Alles auswählen",
273
+ "Visible": "Sichtbar"
269
274
  };
270
275
  export default de;
@@ -265,6 +265,11 @@ const en = {
265
265
  "Show_overall_rate": "Show overall rate",
266
266
  "Percentage": "Percentage",
267
267
  "Number_and_percentage": "Number and percentage",
268
- "No_record": "No record"
268
+ "No_record": "No record",
269
+ "Drill_down_settings": "Drill down settings",
270
+ "Enable_drill_down_feature": "Enable drill down feature",
271
+ "Field_settings": "Field settings",
272
+ "Select_all": "Select all",
273
+ "Visible": "Visible"
269
274
  };
270
275
  export default en;
@@ -265,6 +265,11 @@ const es = {
265
265
  "Show_overall_rate": "Show overall rate",
266
266
  "Percentage": "Percentage",
267
267
  "Number_and_percentage": "Number and percentage",
268
- "No_record": "No record"
268
+ "No_record": "No record",
269
+ "Drill_down_settings": "Drill down settings",
270
+ "Enable_drill_down_feature": "Enable drill down feature",
271
+ "Field_settings": "Field settings",
272
+ "Select_all": "Select all",
273
+ "Visible": "Visible"
269
274
  };
270
275
  export default es;
@@ -265,6 +265,11 @@ const fr = {
265
265
  "Show_overall_rate": "Afficher le libellé du tarif global",
266
266
  "Percentage": "Couche d'entonnoir",
267
267
  "Number_and_percentage": "Nombre et pourcentage",
268
- "No_record": "Aucun enregistrement"
268
+ "No_record": "Aucun enregistrement",
269
+ "Drill_down_settings": "Paramètres d'exploration",
270
+ "Enable_drill_down_feature": "Activer la fonctionnalité d'exploration vers le bas",
271
+ "Field_settings": "Paramètres de champ",
272
+ "Select_all": "Tout sélectionner",
273
+ "Visible": "Visible"
269
274
  };
270
275
  export default fr;
@@ -265,6 +265,11 @@ const pt = {
265
265
  "Show_overall_rate": "Show overall rate",
266
266
  "Percentage": "Percentage",
267
267
  "Number_and_percentage": "Number and percentage",
268
- "No_record": "No record"
268
+ "No_record": "No record",
269
+ "Drill_down_settings": "Drill down settings",
270
+ "Enable_drill_down_feature": "Enable drill down feature",
271
+ "Field_settings": "Field settings",
272
+ "Select_all": "Select all",
273
+ "Visible": "Visible"
269
274
  };
270
275
  export default pt;
@@ -265,6 +265,11 @@ const ru = {
265
265
  "Show_overall_rate": "Show overall rate",
266
266
  "Percentage": "Percentage",
267
267
  "Number_and_percentage": "Number and percentage",
268
- "No_record": "No record"
268
+ "No_record": "No record",
269
+ "Drill_down_settings": "Drill down settings",
270
+ "Enable_drill_down_feature": "Enable drill down feature",
271
+ "Field_settings": "Field settings",
272
+ "Select_all": "Select all",
273
+ "Visible": "Visible"
269
274
  };
270
275
  export default ru;
@@ -265,6 +265,11 @@ const zh_CN = {
265
265
  "Show_overall_rate": "显示总转化率标签",
266
266
  "Percentage": "百分比",
267
267
  "Number_and_percentage": "数值和百分比",
268
- "No_record": "没有记录"
268
+ "No_record": "没有记录",
269
+ "Drill_down_settings": "钻取设置",
270
+ "Enable_drill_down_feature": "开启钻取功能",
271
+ "Field_settings": "字段设置",
272
+ "Select_all": "选择全部",
273
+ "Visible": "可见"
269
274
  };
270
275
  export default zh_CN;
@@ -5,5 +5,9 @@ export default class BaseModel {
5
5
  this.table_id = options.table_id || null;
6
6
  this.filters = options.filters || [];
7
7
  this.filter_conjunction = options.filter_conjunction || 'And';
8
+ // set to null to use all columns as default
9
+ this.drill_down_fields = options.drill_down_fields || null;
10
+ // default set to true
11
+ this.drill_down_status = typeof options.drill_down_status === 'boolean' ? options.drill_down_status : true;
8
12
  }
9
13
  }
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { generateChartConfig } from '../../utils';
3
+ import DrillDownSettings from '../../components/drill-down-settings';
3
4
  import StatisticType from './chart-type';
4
5
  import SelectTable from './select-table';
5
6
  import SelectView from './select-view';
@@ -12,10 +13,10 @@ const CommonDataSettings = _ref => {
12
13
  tables,
13
14
  onChange
14
15
  } = _ref;
16
+ const {
17
+ config
18
+ } = chart;
15
19
  const onTableChange = useCallback(option => {
16
- const {
17
- config
18
- } = chart;
19
20
  const {
20
21
  table_id
21
22
  } = config;
@@ -26,11 +27,8 @@ const CommonDataSettings = _ref => {
26
27
  filters: [],
27
28
  filter_conjunction: 'And'
28
29
  });
29
- }, [chart, onChange]);
30
+ }, [config, onChange]);
30
31
  const onViewChange = useCallback(option => {
31
- const {
32
- config
33
- } = chart;
34
32
  const {
35
33
  view_id
36
34
  } = config;
@@ -39,13 +37,30 @@ const CommonDataSettings = _ref => {
39
37
  onChange && onChange({
40
38
  view_id: selectedViewId
41
39
  });
42
- }, [chart, onChange]);
40
+ }, [config, onChange]);
41
+ const onDrillDownStatusChange = useCallback(event => {
42
+ onChange && onChange({
43
+ drill_down_status: event.target.checked
44
+ });
45
+ }, [onChange]);
46
+ const onDrillDownFieldChange = useCallback(fields => {
47
+ onChange && onChange({
48
+ drill_down_fields: fields
49
+ });
50
+ }, [onChange]);
43
51
  const generateConfig = useCallback(config => {
44
52
  return generateChartConfig(config, tables);
45
53
  }, [tables]);
46
54
  const {
47
- table_id
48
- } = chart.config;
55
+ table_id,
56
+ drill_down_status,
57
+ drill_down_fields
58
+ } = config;
59
+ const selectedTable = tables.find(table => table._id === table_id);
60
+ const columns = selectedTable ? selectedTable.columns : [];
61
+ const drillDownStatus = drill_down_status !== undefined && drill_down_status !== null ? drill_down_status : true;
62
+ // use all columns as default
63
+ const drillDownFields = drill_down_fields || columns.map(column => column.key);
49
64
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StatisticType, {
50
65
  chart: chart,
51
66
  generateChartConfig: generateConfig,
@@ -63,7 +78,13 @@ const CommonDataSettings = _ref => {
63
78
  selectedTableId: table_id,
64
79
  selectedViewId: chart.config.view_id,
65
80
  onChange: onViewChange
66
- }), /*#__PURE__*/React.createElement(Divider, null));
81
+ }), /*#__PURE__*/React.createElement(Divider, null), dataSources === 'filter' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DrillDownSettings, {
82
+ columns: columns,
83
+ drillDownStatus: drillDownStatus,
84
+ toggleDrillDownStatus: onDrillDownStatusChange,
85
+ drillDownFields: drillDownFields,
86
+ setDrillDownFields: onDrillDownFieldChange
87
+ }), /*#__PURE__*/React.createElement(Divider, null)));
67
88
  };
68
89
  CommonDataSettings.defaultProps = {
69
90
  dataSources: 'filter'
@@ -1476,19 +1476,14 @@ SQLStatisticsUtils.trendMapChartSQLResult2JavaScript = (chart, sqlRows, chartSQL
1476
1476
  compareDate,
1477
1477
  comparedDate
1478
1478
  } = getCompareDate(date_granularity);
1479
- for (let index = sqlRows.length - 1; index >= 0; index--) {
1480
- const item = sqlRows[index];
1479
+ for (const item of sqlRows) {
1481
1480
  if (!item[sqlGroupbyColumnKey]) continue;
1482
1481
  const currentDate = item[sqlGroupbyColumnKey] + '';
1483
- if (currentDate && currentDate < comparedDate) {
1484
- break;
1485
- }
1486
1482
  if (currentDate === compareDate) {
1487
1483
  compareValue = item[sqlSummaryColumnKey];
1488
1484
  }
1489
1485
  if (currentDate === comparedDate) {
1490
1486
  comparedValue = item[sqlSummaryColumnKey];
1491
- break;
1492
1487
  }
1493
1488
  }
1494
1489
  }
@@ -99,8 +99,8 @@ class Funnel extends ChartComponent {
99
99
  }
100
100
  const contentFormatterMap = {
101
101
  [FUNNEL_LABEL_FORMAT.NUMBER]: obj => obj.value,
102
- [FUNNEL_LABEL_FORMAT.PERCENTAGE]: obj => obj.percent + '%',
103
- [FUNNEL_LABEL_FORMAT.NUMBER_AND_PERCENTAGE]: obj => "".concat(obj.value, " (").concat(obj.percent, "%)")
102
+ [FUNNEL_LABEL_FORMAT.PERCENTAGE]: obj => ((obj === null || obj === void 0 ? void 0 : obj.percent) || 0) + '%',
103
+ [FUNNEL_LABEL_FORMAT.NUMBER_AND_PERCENTAGE]: obj => "".concat(obj.value, " (").concat((obj === null || obj === void 0 ? void 0 : obj.percent) || 0, "%)")
104
104
  };
105
105
  this.chart.axis(false);
106
106
  this.chart.coordinate('rect').transpose().scale(1, -1);
@@ -149,10 +149,11 @@ class Funnel extends ChartComponent {
149
149
  });
150
150
  });
151
151
  if (funnel_show_overall_rate) {
152
+ var _sortedData;
152
153
  this.chart.annotation().text({
153
154
  top: true,
154
155
  position: ['50.5%', '-4%'],
155
- content: sortedData[sortedData.length - 1].percent + '%',
156
+ content: (((_sortedData = sortedData[sortedData.length - 1]) === null || _sortedData === void 0 ? void 0 : _sortedData.percent) || 0) + '%',
156
157
  style: {
157
158
  fontSize: funnel_label_font_size,
158
159
  stroke: null,
@@ -289,7 +289,16 @@ const Wrapper = _ref => {
289
289
  }
290
290
  }
291
291
  };
292
- return /*#__PURE__*/React.createElement(React.Fragment, null, renderChart(), isStatisticRecordsDialogShow && /*#__PURE__*/React.createElement(StatisticRecordDialog, {
292
+ const {
293
+ config
294
+ } = chart;
295
+ const {
296
+ drill_down_status
297
+ } = config;
298
+ const drillDownStatus = drill_down_status !== undefined && drill_down_status !== null ? drill_down_status : true;
299
+ // in dtable-statistics always support drill down
300
+ const supportDrillDown = isCalculateByView ? true : drillDownStatus;
301
+ return /*#__PURE__*/React.createElement(React.Fragment, null, renderChart(), isStatisticRecordsDialogShow && supportDrillDown && /*#__PURE__*/React.createElement(StatisticRecordDialog, {
293
302
  chartRecordsParams: {
294
303
  statisticRecord: {
295
304
  ...statisticRecords
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "1.1.26",
3
+ "version": "1.1.28",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@antv/data-set": "0.11.8",