sea-chart 2.0.43 → 2.0.45
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/api/index.js +4 -11
- package/dist/components/cell-factory/FormatterConfig.js +55 -62
- package/dist/components/cell-factory/SimpleCellFormatter.js +4 -11
- package/dist/components/cell-factory/SingleSelectOption.js +11 -18
- package/dist/components/cell-factory/cell-editor-factory.js +5 -12
- package/dist/components/cell-factory/cell-formatter-factory.js +4 -11
- package/dist/components/cell-factory/link-content.js +27 -35
- package/dist/components/chart-color-selector/color-selector.js +11 -18
- package/dist/components/collaborator/index.js +7 -14
- package/dist/components/color-picker/index.js +11 -18
- package/dist/components/color-popover/color-rules/color-rule.js +25 -33
- package/dist/components/color-popover/color-rules/index.js +6 -14
- package/dist/components/color-popover/color-rules/rule-filters/filter.js +27 -34
- package/dist/components/color-popover/color-rules/rule-filters/index.js +17 -25
- package/dist/components/color-popover/color-rules/rule-filters/number-input.js +10 -18
- package/dist/components/color-popover/color-rules-popover.js +26 -34
- package/dist/components/color-popover/color-selector-popover.js +10 -18
- package/dist/components/color-setting/color-group-selector.js +12 -20
- package/dist/components/common-add-tool/index.js +6 -13
- package/dist/components/data-process-setter/data-setting-header.js +7 -14
- package/dist/components/data-process-setter/hide-column-setter.js +12 -19
- package/dist/components/data-process-setter/index.js +4 -27
- package/dist/components/data-process-setter/sort-setter.js +16 -24
- package/dist/components/draggable/Draggable.js +7 -13
- package/dist/components/drill-down-settings/drill-down-fields-popover/index.js +42 -50
- package/dist/components/drill-down-settings/drill-down-fields-settings/index.js +10 -18
- package/dist/components/drill-down-settings/index.js +11 -18
- package/dist/components/dtable-popover/index.js +13 -20
- package/dist/components/dtable-search-input/index.js +13 -21
- package/dist/components/font-settings/index.js +14 -22
- package/dist/components/goal-line-setting/goal-setting-item.js +6 -14
- package/dist/components/goal-line-setting/index.js +12 -19
- package/dist/components/highlighter/highlighter.js +7 -14
- package/dist/components/icon/index.js +4 -11
- package/dist/components/index.js +7 -48
- package/dist/components/loading/index.js +6 -13
- package/dist/components/number-input/index.js +4 -11
- package/dist/components/pixel-editor/index.js +15 -23
- package/dist/components/popover/hide-column-popover/hide-column-popover-widgets/hide-column-item.js +8 -15
- package/dist/components/popover/hide-column-popover/hide-column-popover.js +25 -33
- package/dist/components/popover/sort-popover/sort-popover-widgets/sort-utils.js +9 -18
- package/dist/components/popover/sort-popover/sort-popover.js +54 -64
- package/dist/components/resize-handle/ResizeHandle.js +6 -13
- package/dist/components/row-card/row-card-header-cell.js +15 -22
- package/dist/components/row-card/row-card-header.js +14 -21
- package/dist/components/row-card/row-card-item.js +33 -41
- package/dist/components/row-card/row-card.js +15 -23
- package/dist/components/statistic-record-dialog/index.js +56 -64
- package/dist/components/tooltip/index.js +21 -21
- package/dist/components/types-dialog/index.js +56 -64
- package/dist/components/types-dialog/use-force-update.js +4 -10
- package/dist/constants/color-rules.js +8 -14
- package/dist/constants/common-constants.js +8 -14
- package/dist/constants/error.js +2 -8
- package/dist/constants/geolocation.js +9 -15
- package/dist/constants/index.js +149 -273
- package/dist/constants/key-codes.js +0 -2
- package/dist/constants/model.js +3 -9
- package/dist/constants/regions.js +3 -8
- package/dist/constants/style.js +6 -12
- package/dist/constants/table.js +1 -7
- package/dist/constants/type-image.js +33 -39
- package/dist/constants/type.js +3 -9
- package/dist/context.js +20 -24
- package/dist/editor/index.js +8 -15
- package/dist/index.js +13 -104
- package/dist/intl.js +10 -17
- package/dist/locale/index.js +16 -23
- package/dist/locale/lang/de.js +1 -7
- package/dist/locale/lang/en.js +1 -7
- package/dist/locale/lang/es.js +1 -7
- package/dist/locale/lang/fr.js +1 -7
- package/dist/locale/lang/pt.js +1 -7
- package/dist/locale/lang/ru.js +1 -7
- package/dist/locale/lang/zh_CN.js +1 -7
- package/dist/model/area-group.js +12 -19
- package/dist/model/area.js +12 -19
- package/dist/model/bar-custom.js +11 -18
- package/dist/model/bar-group.js +12 -19
- package/dist/model/bar-stack.js +10 -17
- package/dist/model/bar.js +11 -18
- package/dist/model/base-model.js +8 -11
- package/dist/model/basic-number-card.js +13 -20
- package/dist/model/chart.js +7 -13
- package/dist/model/combination.js +19 -22
- package/dist/model/compare-bar.js +14 -21
- package/dist/model/completeness-group.js +11 -18
- package/dist/model/completeness.js +10 -17
- package/dist/model/dashboard.js +7 -14
- package/dist/model/funnel.js +14 -21
- package/dist/model/generic-model.js +135 -143
- package/dist/model/heat-map.js +9 -16
- package/dist/model/horizontal-bar.js +15 -18
- package/dist/model/horizontal-group-bar.js +14 -17
- package/dist/model/index.js +69 -93
- package/dist/model/line-group.js +13 -20
- package/dist/model/line.js +12 -19
- package/dist/model/map-bubble.js +12 -19
- package/dist/model/map.js +12 -19
- package/dist/model/mirror.js +13 -20
- package/dist/model/pie.js +12 -19
- package/dist/model/ring.js +12 -19
- package/dist/model/scatter.js +10 -17
- package/dist/model/stacked-horizontal-bar.js +15 -18
- package/dist/model/table-element.js +5 -12
- package/dist/model/table.js +7 -14
- package/dist/model/tree-map.js +7 -14
- package/dist/model/trend.js +11 -18
- package/dist/model/user.js +1 -7
- package/dist/model/world-map-bubble.js +12 -19
- package/dist/model/world-map.js +12 -19
- package/dist/services/map-json.js +7 -13
- package/dist/settings/advance-bar-settings/data-settings.js +36 -44
- package/dist/settings/advance-bar-settings/index.js +3 -20
- package/dist/settings/advance-bar-settings/style-settings.js +83 -74
- package/dist/settings/bar-settings/data-settings.js +39 -47
- package/dist/settings/bar-settings/index.js +3 -20
- package/dist/settings/bar-settings/style-settings.js +69 -60
- package/dist/settings/basic-number-card/data-settings.js +49 -57
- package/dist/settings/basic-number-card/index.js +3 -20
- package/dist/settings/basic-number-card/style-settings.js +18 -26
- package/dist/settings/combination-settings/data-settings.js +55 -63
- package/dist/settings/combination-settings/index.js +3 -20
- package/dist/settings/combination-settings/style-settings.js +94 -77
- package/dist/settings/completeness-settings/callbacks/callbacks.js +16 -27
- package/dist/settings/completeness-settings/data-settings/completion-settings.js +21 -28
- package/dist/settings/completeness-settings/data-settings/data-settings.js +25 -32
- package/dist/settings/completeness-settings/index.js +3 -20
- package/dist/settings/completeness-settings/style-settings.js +19 -26
- package/dist/settings/dashboard-settings/data-settings.js +43 -51
- package/dist/settings/dashboard-settings/index.js +2 -13
- package/dist/settings/data-settings.js +72 -79
- package/dist/settings/funnel-settings/components/dnd-item/dnd-item.js +12 -19
- package/dist/settings/funnel-settings/components/dnd-list.js +15 -23
- package/dist/settings/funnel-settings/components/funnel-label-setting.js +32 -40
- package/dist/settings/funnel-settings/components/funnel-layer-setting.js +20 -28
- package/dist/settings/funnel-settings/data-settings.js +23 -31
- package/dist/settings/funnel-settings/index.js +3 -20
- package/dist/settings/funnel-settings/style-settings.js +11 -19
- package/dist/settings/heat-map-settings/data-settings.js +18 -26
- package/dist/settings/heat-map-settings/index.js +3 -20
- package/dist/settings/heat-map-settings/style-settings.js +18 -26
- package/dist/settings/horizontal-bar-settings/data-settings.js +12 -19
- package/dist/settings/horizontal-bar-settings/index.js +3 -20
- package/dist/settings/horizontal-bar-settings/style-settings.js +12 -19
- package/dist/settings/index.js +52 -70
- package/dist/settings/map-settings/components/location-field-selector.js +10 -17
- package/dist/settings/map-settings/components/map-level-selector.js +11 -18
- package/dist/settings/map-settings/components/map-province-city-selector.js +19 -26
- package/dist/settings/map-settings/index.js +3 -20
- package/dist/settings/map-settings/map-data-settings.js +23 -30
- package/dist/settings/map-settings/map-style-settings.js +26 -34
- package/dist/settings/mirror-settings/data-settings.js +26 -34
- package/dist/settings/mirror-settings/index.js +2 -13
- package/dist/settings/pie-settings/data-settings.js +33 -41
- package/dist/settings/pie-settings/index.js +3 -20
- package/dist/settings/pie-settings/style-settings.js +47 -55
- package/dist/settings/scatter/data-settings.js +27 -34
- package/dist/settings/scatter/index.js +3 -12
- package/dist/settings/stacks-settings/index.js +19 -27
- package/dist/settings/stacks-settings/stack-item-settings.js +19 -27
- package/dist/settings/style-settings.js +64 -72
- package/dist/settings/table-element-settings/components/data-filter.js +30 -38
- package/dist/settings/table-element-settings/data-settings.js +21 -29
- package/dist/settings/table-element-settings/index.js +2 -13
- package/dist/settings/table-settings/data-settings.js +111 -119
- package/dist/settings/table-settings/index.js +2 -13
- package/dist/settings/time-comparison-settings/data-settings.js +43 -51
- package/dist/settings/time-comparison-settings/index.js +3 -20
- package/dist/settings/time-comparison-settings/style-settings.js +62 -53
- package/dist/settings/trend-settings/data-settings.js +24 -32
- package/dist/settings/trend-settings/index.js +3 -20
- package/dist/settings/trend-settings/style-setting.js +17 -25
- package/dist/settings/widgets/axis-title-font-settings/index.js +39 -0
- package/dist/settings/widgets/basic-summary/index.js +55 -63
- package/dist/settings/widgets/chart-type/index.js +18 -26
- package/dist/settings/widgets/color-settings/index.js +72 -80
- package/dist/settings/widgets/common-data-settings.js +21 -29
- package/dist/settings/widgets/data-filter/index.js +35 -43
- package/dist/settings/widgets/data-sort.js +16 -24
- package/dist/settings/widgets/date-summary-item.js +24 -32
- package/dist/settings/widgets/display-values-settings/index.js +14 -22
- package/dist/settings/widgets/divider/index.js +8 -16
- package/dist/settings/widgets/font-settings/font-color-settings.js +11 -19
- package/dist/settings/widgets/font-settings/font-size-settings.js +14 -22
- package/dist/settings/widgets/font-settings/font-weight-settings.js +17 -25
- package/dist/settings/widgets/font-settings/index.js +4 -27
- package/dist/settings/widgets/group-by.js +51 -59
- package/dist/settings/widgets/min-max-setting.js +10 -18
- package/dist/settings/widgets/mininum-slice-percent.js +10 -18
- package/dist/settings/widgets/numeric-summary-item.js +23 -31
- package/dist/settings/widgets/select-line-type/index.js +10 -17
- package/dist/settings/widgets/select-table/index.js +9 -16
- package/dist/settings/widgets/select-view/index.js +20 -28
- package/dist/settings/widgets/stack.js +14 -22
- package/dist/settings/widgets/summary-method-setting.js +17 -25
- package/dist/settings/widgets/summary-settings.js +72 -80
- package/dist/settings/widgets/switch/index.js +8 -15
- package/dist/settings/widgets/text-horizontal-settings.js +15 -23
- package/dist/settings/widgets/time-picker.js +29 -37
- package/dist/settings/widgets/title-settings/index.js +29 -37
- package/dist/settings/widgets/title-settings/title-text.js +5 -12
- package/dist/settings/widgets/x-axios.js +0 -1
- package/dist/settings/widgets/y-axis-group-settings.js +63 -71
- package/dist/utils/cell-format-utils.js +18 -28
- package/dist/utils/cell-value-utils.js +5 -12
- package/dist/utils/chart-utils/base-utils.js +362 -334
- package/dist/utils/chart-utils/index.js +28 -41
- package/dist/utils/chart-utils/original-data-utils/basic-chart-calculator.js +80 -86
- package/dist/utils/chart-utils/original-data-utils/card-calculator.js +13 -20
- package/dist/utils/chart-utils/original-data-utils/combination-calculator.js +45 -52
- package/dist/utils/chart-utils/original-data-utils/compare-bar-chart-calculator.js +19 -26
- package/dist/utils/chart-utils/original-data-utils/completeness-calculator.js +32 -39
- package/dist/utils/chart-utils/original-data-utils/dashboard-calculator.js +16 -23
- package/dist/utils/chart-utils/original-data-utils/index.js +50 -57
- package/dist/utils/chart-utils/original-data-utils/mirror-calculator.js +21 -28
- package/dist/utils/chart-utils/original-data-utils/pivot-table-calculator.js +91 -97
- package/dist/utils/chart-utils/original-data-utils/scatter-calculator.js +19 -26
- package/dist/utils/chart-utils/original-data-utils/trend-calculator.js +31 -38
- package/dist/utils/chart-utils/sql-statistics-utils.js +284 -246
- package/dist/utils/chart.js +9 -17
- package/dist/utils/collaborator-manager.js +3 -9
- package/dist/utils/collaborator-utils.js +18 -30
- package/dist/utils/collaborator.js +4 -13
- package/dist/utils/color-utils.js +18 -29
- package/dist/utils/column-utils.js +65 -92
- package/dist/utils/common-utils.js +27 -52
- package/dist/utils/concurrency-manager.js +1 -7
- package/dist/utils/contexts.js +5 -12
- package/dist/utils/date-translate.js +11 -19
- package/dist/utils/digital-sign-utils.js +7 -14
- package/dist/utils/event-bus.js +1 -7
- package/dist/utils/hotkey.js +5 -11
- package/dist/utils/index.js +54 -221
- package/dist/utils/key-generator.js +2 -9
- package/dist/utils/map.js +22 -31
- package/dist/utils/object-utils.js +1 -7
- package/dist/utils/options-utils.js +8 -16
- package/dist/utils/row-record-utils.js +182 -178
- package/dist/utils/row-utils.js +27 -38
- package/dist/utils/search.js +24 -32
- package/dist/utils/sql/chart-data-sql.js +49 -55
- package/dist/utils/sql/column-2-sql-column.js +146 -154
- package/dist/utils/sql/index.js +3 -27
- package/dist/utils/trend-utils.js +39 -47
- package/dist/view/index.css +0 -17
- package/dist/view/index.js +89 -95
- package/dist/view/title/index.js +15 -23
- package/dist/view/wrapper/area-group.js +57 -74
- package/dist/view/wrapper/area.js +51 -72
- package/dist/view/wrapper/bar-compare.js +47 -58
- package/dist/view/wrapper/bar-custom-stack.js +53 -121
- package/dist/view/wrapper/bar-group.js +55 -96
- package/dist/view/wrapper/bar-stack.js +58 -92
- package/dist/view/wrapper/bar.js +45 -66
- package/dist/view/wrapper/basic-number-card.js +25 -26
- package/dist/view/wrapper/chart-component.js +600 -166
- package/dist/view/wrapper/combination.js +79 -87
- package/dist/view/wrapper/completeness-group.js +46 -98
- package/dist/view/wrapper/completeness.js +45 -97
- package/dist/view/wrapper/dashboard.js +33 -47
- package/dist/view/wrapper/funnel.js +65 -64
- package/dist/view/wrapper/heat-map.js +126 -104
- package/dist/view/wrapper/horizontal-bar-group.js +61 -78
- package/dist/view/wrapper/horizontal-bar-stack.js +60 -111
- package/dist/view/wrapper/horizontal-bar.js +45 -68
- package/dist/view/wrapper/index.js +110 -115
- package/dist/view/wrapper/line-group.js +52 -68
- package/dist/view/wrapper/line.js +47 -67
- package/dist/view/wrapper/map-bubble.js +46 -59
- package/dist/view/wrapper/map-world-bubble.js +45 -58
- package/dist/view/wrapper/map-world.js +47 -60
- package/dist/view/wrapper/map.js +48 -60
- package/dist/view/wrapper/mirror.js +45 -64
- package/dist/view/wrapper/pie.js +51 -59
- package/dist/view/wrapper/ring.js +57 -64
- package/dist/view/wrapper/scatter.js +53 -69
- package/dist/view/wrapper/table/index.js +13 -21
- package/dist/view/wrapper/table/one-dimension-table-no-numeric-columns.js +49 -57
- package/dist/view/wrapper/table/one-dimension-table-with-numeric-columns.js +50 -58
- package/dist/view/wrapper/table/pivot-table-display-name.js +83 -91
- package/dist/view/wrapper/table/two-dimension-table.js +76 -84
- package/dist/view/wrapper/table-element/components/dataset-utils.js +23 -36
- package/dist/view/wrapper/table-element/components/formatter.js +96 -105
- package/dist/view/wrapper/table-element/components/formatters/FileFormatter/index.js +22 -31
- package/dist/view/wrapper/table-element/components/formatters/formula-formatter.js +9 -16
- package/dist/view/wrapper/table-element/components/formatters/link-formatter.js +73 -80
- package/dist/view/wrapper/table-element/components/formula-formatter.js +9 -16
- package/dist/view/wrapper/table-element/components/link-formatter.js +73 -80
- package/dist/view/wrapper/table-element/components/record.js +10 -17
- package/dist/view/wrapper/table-element/components/records-body.js +17 -19
- package/dist/view/wrapper/table-element/components/records-header/index.js +7 -15
- package/dist/view/wrapper/table-element/components/records-header/records-header-cell.js +8 -16
- package/dist/view/wrapper/table-element/components/records.js +23 -33
- package/dist/view/wrapper/table-element/components/resize-column-handle/resize-column-handle.js +5 -12
- package/dist/view/wrapper/table-element/components/utils.js +5 -15
- package/dist/view/wrapper/table-element/components/value-display-utils.js +4 -11
- package/dist/view/wrapper/table-element/components/vertical-scrollbar/index.js +6 -13
- package/dist/view/wrapper/table-element/index.js +18 -26
- package/dist/view/wrapper/treemap.js +39 -57
- package/dist/view/wrapper/trend.js +41 -48
- package/package.json +1 -1
|
@@ -1,56 +1,116 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var _dtableUtils = require("dtable-utils");
|
|
13
|
-
var _utils = require("../../utils");
|
|
14
|
-
var _constants = require("../../constants");
|
|
15
|
-
var _style = require("../../constants/style");
|
|
16
|
-
var _intl = _interopRequireDefault(require("../../intl"));
|
|
17
|
-
require("../../assets/css/sea-chart-d3-tooltip.css");
|
|
18
|
-
class ChartComponent extends _react.Component {
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Component } from 'react';
|
|
3
|
+
import * as d3 from 'd3';
|
|
4
|
+
import { cloneDeep, debounce } from 'lodash-es';
|
|
5
|
+
import { getTableById, getTableColumnByKey } from 'dtable-utils';
|
|
6
|
+
import { BaseUtils, formatXAxisLabel } from '../../utils';
|
|
7
|
+
import { CHART_TYPE, CHART_SUMMARY_TYPE, LABEL_POSITION_TYPE, CHART_THEME_COLOR, EMPTY_NAME, THEME_NAME_MAP, CHART_STYLE_COLORS, DEFAULT_AXIS_LABEL_FONT_COLOR, DEFAULT_AXIS_LABEL_FONT_COLOR_DARK, DEFAULT_AXIS_LABEL_FONT_SIZE } from '../../constants';
|
|
8
|
+
import { FILL_BORDER_COLOR_MAP } from '../../constants/style';
|
|
9
|
+
import intl from '../../intl';
|
|
10
|
+
import '../../assets/css/sea-chart-d3-tooltip.css';
|
|
11
|
+
export default class ChartComponent extends Component {
|
|
19
12
|
constructor(props) {
|
|
20
13
|
var _this;
|
|
21
14
|
super(props);
|
|
22
15
|
_this = this;
|
|
16
|
+
// Filter out the data whose legend group has been toggled off, so the chart
|
|
17
|
+
// body can be re-laid out without the hidden categories. The full data set is
|
|
18
|
+
// still passed to setLegend so every legend item (including hidden ones) shows.
|
|
19
|
+
this.getVisibleLegendData = (data, legendName) => {
|
|
20
|
+
if (!Array.isArray(data) || !this.hiddenLegendGroups || this.hiddenLegendGroups.size === 0) {
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
const filtered = data.filter(d => !this.hiddenLegendGroups.has(String(d === null || d === void 0 ? void 0 : d[legendName])));
|
|
24
|
+
// Never hide everything, keep the original data as a fallback.
|
|
25
|
+
return filtered.length ? filtered : data;
|
|
26
|
+
};
|
|
27
|
+
this.handleLegendClick = groupName => {
|
|
28
|
+
if (!this.hiddenLegendGroups) this.hiddenLegendGroups = new Set();
|
|
29
|
+
const key = String(groupName);
|
|
30
|
+
const isHidden = this.hiddenLegendGroups.has(key);
|
|
31
|
+
if (isHidden) {
|
|
32
|
+
this.hiddenLegendGroups.delete(key);
|
|
33
|
+
} else {
|
|
34
|
+
// Keep at least one visible group so the chart is never fully empty.
|
|
35
|
+
const total = this.legendGroupNames ? this.legendGroupNames.size : 0;
|
|
36
|
+
const visibleCount = total - this.hiddenLegendGroups.size;
|
|
37
|
+
if (visibleCount <= 1) return;
|
|
38
|
+
this.hiddenLegendGroups.add(key);
|
|
39
|
+
}
|
|
40
|
+
this.redrawChart();
|
|
41
|
+
};
|
|
42
|
+
this.redrawChart = () => {
|
|
43
|
+
if (!this.createChart || !this.drawChart) return;
|
|
44
|
+
this.destroyChart();
|
|
45
|
+
this.createChart();
|
|
46
|
+
this.drawChart();
|
|
47
|
+
};
|
|
23
48
|
this.initLabelStroke = theme => {
|
|
24
|
-
this.globalTheme = theme ||
|
|
25
|
-
this.labelStroke = theme ===
|
|
49
|
+
this.globalTheme = theme || THEME_NAME_MAP.LIGHT;
|
|
50
|
+
this.labelStroke = theme === THEME_NAME_MAP.DARK ? {} : {
|
|
26
51
|
stroke: '#fff',
|
|
27
52
|
lineWidth: 1
|
|
28
53
|
};
|
|
29
54
|
};
|
|
30
|
-
this.handleResize =
|
|
55
|
+
this.handleResize = debounce(() => {
|
|
31
56
|
if (!this.createChart || !this.drawChart) return;
|
|
32
57
|
this.destroyChart();
|
|
33
58
|
this.createChart();
|
|
34
59
|
this.drawChart();
|
|
35
|
-
if (this.needRenderAxisLabel) {
|
|
36
|
-
this.renderAxisLabel(this.props.chart, this.props.tables);
|
|
37
|
-
}
|
|
38
60
|
}, 300);
|
|
39
61
|
this.destroyChart = () => {
|
|
40
62
|
this.chart && this.chart.node() && this.chart.node().remove();
|
|
63
|
+
this.container && this.setAxisTitlePadding(this.container, {
|
|
64
|
+
left: null,
|
|
65
|
+
bottom: null,
|
|
66
|
+
right: null
|
|
67
|
+
});
|
|
68
|
+
this._clipMaskByRect.clear();
|
|
69
|
+
this._defs = null;
|
|
70
|
+
};
|
|
71
|
+
this.toggleRecords = function (statisticRecord) {
|
|
72
|
+
if (!statisticRecord) return;
|
|
73
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
74
|
+
args[_key - 1] = arguments[_key];
|
|
75
|
+
}
|
|
76
|
+
_this.props.toggleRecords && _this.props.toggleRecords(statisticRecord, ...args);
|
|
41
77
|
};
|
|
42
78
|
this.getTitle = (tables, table_id, yAxisType, yAxisKey) => {
|
|
43
|
-
return yAxisType ===
|
|
79
|
+
return yAxisType === CHART_SUMMARY_TYPE.COUNT ? intl.get('Amount') : this.getAxisLabel(tables, table_id, yAxisKey);
|
|
44
80
|
};
|
|
45
81
|
this.getColumn = (tables, table_id, columnKey) => {
|
|
46
|
-
const table =
|
|
47
|
-
const column =
|
|
82
|
+
const table = getTableById(tables, table_id);
|
|
83
|
+
const column = getTableColumnByKey(table, columnKey) || {};
|
|
48
84
|
return column;
|
|
49
85
|
};
|
|
50
86
|
this.getAxisLabel = (tables, tableId, columnKey) => {
|
|
51
87
|
const column = this.getColumn(tables, tableId, columnKey);
|
|
52
88
|
return column.name || '';
|
|
53
89
|
};
|
|
90
|
+
this.getAxisTitleHeight = fontSize => {
|
|
91
|
+
const safeFontSize = Number(fontSize) || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
92
|
+
return Math.max(this.axisTitleMinHeight, safeFontSize + 4);
|
|
93
|
+
};
|
|
94
|
+
this.setAxisTitlePadding = function (chartContainer) {
|
|
95
|
+
let {
|
|
96
|
+
left = null,
|
|
97
|
+
bottom = null,
|
|
98
|
+
right = null
|
|
99
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
100
|
+
if (!chartContainer) return;
|
|
101
|
+
chartContainer.style.paddingLeft = left != null ? `${left}px` : '';
|
|
102
|
+
chartContainer.style.paddingBottom = bottom != null ? `${bottom}px` : '';
|
|
103
|
+
chartContainer.style.paddingRight = right != null ? `${right}px` : '';
|
|
104
|
+
};
|
|
105
|
+
this.getRotatedAxisTitleTransform = function (containerHeight, titleHeight) {
|
|
106
|
+
let placement = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'left';
|
|
107
|
+
const translateX = containerHeight / 2 - titleHeight / 2;
|
|
108
|
+
const translateY = containerHeight / 2 - titleHeight / 2;
|
|
109
|
+
if (placement === 'right') {
|
|
110
|
+
return `translate(${translateX}px, ${translateY}px) rotate(-90deg)`;
|
|
111
|
+
}
|
|
112
|
+
return `translate(-${translateX}px, ${translateY}px) rotate(-90deg)`;
|
|
113
|
+
};
|
|
54
114
|
this.initChart = function (container, id) {
|
|
55
115
|
let initConfig = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
56
116
|
const {
|
|
@@ -68,6 +128,8 @@ class ChartComponent extends _react.Component {
|
|
|
68
128
|
const height = customHeight ? customHeight : containerHeight - marginBottom;
|
|
69
129
|
_this.chart = d3.create('svg').attr('id', id).attr('width', width).attr('height', height).attr('viewBox', [0, 0, width, height]);
|
|
70
130
|
_this.container.appendChild(_this.chart.node());
|
|
131
|
+
_this._defs = null;
|
|
132
|
+
_this._clipMaskByRect = new Map();
|
|
71
133
|
_this.chartBoundingClientRect = {
|
|
72
134
|
...JSON.parse(JSON.stringify(_this.chart.node().getBoundingClientRect())),
|
|
73
135
|
...initConfig,
|
|
@@ -75,6 +137,12 @@ class ChartComponent extends _react.Component {
|
|
|
75
137
|
height
|
|
76
138
|
};
|
|
77
139
|
};
|
|
140
|
+
this.getDefs = () => {
|
|
141
|
+
if (!this._defs || !this._defs.node() || !this._defs.node().isConnected) {
|
|
142
|
+
this._defs = this.chart.append('defs').attr('class', 'sea-chart-defs');
|
|
143
|
+
}
|
|
144
|
+
return this._defs;
|
|
145
|
+
};
|
|
78
146
|
this.initDefs = () => {
|
|
79
147
|
if (this.container) {
|
|
80
148
|
// add Mask
|
|
@@ -107,7 +175,7 @@ class ChartComponent extends _react.Component {
|
|
|
107
175
|
if (item.group_name === 'rest' && isCompleteness) return;
|
|
108
176
|
const groupData = chartGroupData.find(g => g.name === item.name);
|
|
109
177
|
if (!groupData) {
|
|
110
|
-
const newItem =
|
|
178
|
+
const newItem = cloneDeep(item);
|
|
111
179
|
newItem.currentGroupCount = 1;
|
|
112
180
|
chartGroupData.push(newItem);
|
|
113
181
|
} else {
|
|
@@ -161,13 +229,13 @@ class ChartComponent extends _react.Component {
|
|
|
161
229
|
// mark the first item in each group,but if item value is 0, mark the next item
|
|
162
230
|
let targetMarkItem = item[0],
|
|
163
231
|
i = 1;
|
|
164
|
-
while (!((_targetMarkItem = targetMarkItem)
|
|
232
|
+
while (!((_targetMarkItem = targetMarkItem) === null || _targetMarkItem === void 0 ? void 0 : _targetMarkItem.value) && !Number.isNaN((_targetMarkItem2 = targetMarkItem) === null || _targetMarkItem2 === void 0 ? void 0 : _targetMarkItem2.value)) {
|
|
165
233
|
var _targetMarkItem, _targetMarkItem2;
|
|
166
234
|
targetMarkItem = item[i];
|
|
167
235
|
i++;
|
|
168
236
|
if (i >= item.length) break;
|
|
169
237
|
}
|
|
170
|
-
if (!((_targetMarkItem3 = targetMarkItem)
|
|
238
|
+
if (!((_targetMarkItem3 = targetMarkItem) === null || _targetMarkItem3 === void 0 ? void 0 : _targetMarkItem3.value)) return;
|
|
171
239
|
targetMarkItem.isFirst = 1;
|
|
172
240
|
} else if (position === 'last') {
|
|
173
241
|
var _targetMarkItem6;
|
|
@@ -175,13 +243,13 @@ class ChartComponent extends _react.Component {
|
|
|
175
243
|
const l = item.length;
|
|
176
244
|
let targetMarkItem = item[l - 1],
|
|
177
245
|
i = l - 2;
|
|
178
|
-
while (!((_targetMarkItem4 = targetMarkItem)
|
|
246
|
+
while (!((_targetMarkItem4 = targetMarkItem) === null || _targetMarkItem4 === void 0 ? void 0 : _targetMarkItem4.value) && !Number.isNaN((_targetMarkItem5 = targetMarkItem) === null || _targetMarkItem5 === void 0 ? void 0 : _targetMarkItem5.value)) {
|
|
179
247
|
var _targetMarkItem4, _targetMarkItem5;
|
|
180
248
|
targetMarkItem = item[i];
|
|
181
249
|
i--;
|
|
182
250
|
if (i < 0) break;
|
|
183
251
|
}
|
|
184
|
-
if (!((_targetMarkItem6 = targetMarkItem)
|
|
252
|
+
if (!((_targetMarkItem6 = targetMarkItem) === null || _targetMarkItem6 === void 0 ? void 0 : _targetMarkItem6.value)) return;
|
|
185
253
|
targetMarkItem.isLast = 1;
|
|
186
254
|
} else {
|
|
187
255
|
console.error('on markFirstOrLast: unknown position');
|
|
@@ -229,23 +297,38 @@ class ChartComponent extends _react.Component {
|
|
|
229
297
|
y_axis_summary_type,
|
|
230
298
|
type,
|
|
231
299
|
title_name,
|
|
300
|
+
x_axis_label_font_size,
|
|
301
|
+
x_axis_label_font_color,
|
|
302
|
+
y_axis_label_font_size,
|
|
303
|
+
y_axis_label_font_color,
|
|
232
304
|
// left axis - combination chart
|
|
233
305
|
show_y_axis_left_label,
|
|
234
306
|
y_axis_left_label_position,
|
|
235
307
|
y_axis_left_summary_type,
|
|
236
308
|
y_axis_left_summary_column,
|
|
309
|
+
y_axis_left_label_font_size,
|
|
310
|
+
y_axis_left_label_font_color,
|
|
237
311
|
// right axis - combination chart
|
|
238
312
|
show_y_axis_right_label,
|
|
239
313
|
y_axis_right_label_position,
|
|
240
314
|
y_axis_right_summary_type,
|
|
241
|
-
y_axis_right_summary_column
|
|
315
|
+
y_axis_right_summary_column,
|
|
316
|
+
y_axis_right_label_font_size,
|
|
317
|
+
y_axis_right_label_font_color
|
|
242
318
|
} = chart.config;
|
|
243
319
|
if (y_axis_summary_column_key) {
|
|
244
320
|
y_axis_column_key = y_axis_summary_column_key;
|
|
245
321
|
}
|
|
246
|
-
const table =
|
|
247
|
-
|
|
248
|
-
|
|
322
|
+
const table = getTableById(tables, table_id);
|
|
323
|
+
const defaultTextColor = this.globalTheme === THEME_NAME_MAP.DARK ? DEFAULT_AXIS_LABEL_FONT_COLOR_DARK : DEFAULT_AXIS_LABEL_FONT_COLOR;
|
|
324
|
+
const xColor = x_axis_label_font_color || defaultTextColor;
|
|
325
|
+
const xFontSize = x_axis_label_font_size || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
326
|
+
const yColor = y_axis_label_font_color || defaultTextColor;
|
|
327
|
+
const yFontSize = y_axis_label_font_size || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
328
|
+
const yLeftColor = y_axis_left_label_font_color || defaultTextColor;
|
|
329
|
+
const yLeftFontSize = y_axis_left_label_font_size || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
330
|
+
const yRightColor = y_axis_right_label_font_color || defaultTextColor;
|
|
331
|
+
const yRightFontSize = y_axis_right_label_font_size || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
249
332
|
|
|
250
333
|
// xAxis
|
|
251
334
|
const xAxisID = `chart-x-axis-label_${chart.id}`;
|
|
@@ -253,17 +336,18 @@ class ChartComponent extends _react.Component {
|
|
|
253
336
|
const {
|
|
254
337
|
width: containerWidth
|
|
255
338
|
} = this.chartBoundingClientRect;
|
|
339
|
+
const xTitleHeight = this.getAxisTitleHeight(xFontSize);
|
|
256
340
|
if (!xLabel && x_axis_show_label) {
|
|
257
341
|
const div = document.createElement('div');
|
|
258
342
|
div.id = xAxisID;
|
|
259
343
|
div.className = 'chart-axis-label';
|
|
260
|
-
const column =
|
|
344
|
+
const column = getTableColumnByKey(table, x_axis_column_key);
|
|
261
345
|
div.innerHTML = `${column ? column.name : ''}`;
|
|
262
|
-
div.setAttribute('style', `color:${
|
|
346
|
+
div.setAttribute('style', `color:${xColor}; font-size:${xFontSize}px; width: ${containerWidth}px; height: ${xTitleHeight}px; line-height: ${xTitleHeight}px; text-align: ${x_axis_label_position}; position: absolute; bottom: 0;`);
|
|
263
347
|
chartContainer.appendChild(div);
|
|
264
348
|
}
|
|
265
349
|
if (xLabel && x_axis_show_label) {
|
|
266
|
-
xLabel.setAttribute('style', `color:${
|
|
350
|
+
xLabel.setAttribute('style', `color:${xColor}; font-size:${xFontSize}px; width: ${containerWidth}px; height: ${xTitleHeight}px; line-height: ${xTitleHeight}px; text-align: ${x_axis_label_position}; position: absolute; bottom: 0;`);
|
|
267
351
|
}
|
|
268
352
|
if (xLabel && !x_axis_show_label) {
|
|
269
353
|
xLabel.parentNode.removeChild(xLabel);
|
|
@@ -272,18 +356,18 @@ class ChartComponent extends _react.Component {
|
|
|
272
356
|
// yAxis
|
|
273
357
|
const yAxisID = `chart-y-axis-label_${chart.id}`;
|
|
274
358
|
const yLabel = chartContainer.querySelector(`#${yAxisID}`);
|
|
275
|
-
const
|
|
359
|
+
const yTitleHeight = this.getAxisTitleHeight(yFontSize);
|
|
276
360
|
if (!yLabel && y_axis_show_label) {
|
|
277
361
|
const div = document.createElement('div');
|
|
278
362
|
div.id = yAxisID;
|
|
279
363
|
div.className = 'chart-axis-label';
|
|
280
364
|
// SCATTER always has y_axis_column_key
|
|
281
|
-
if (y_axis_summary_type ===
|
|
282
|
-
div.innerHTML =
|
|
365
|
+
if (y_axis_summary_type === CHART_SUMMARY_TYPE.COUNT && type !== CHART_TYPE.SCATTER) {
|
|
366
|
+
div.innerHTML = intl.get('Amount');
|
|
283
367
|
} else {
|
|
284
|
-
const column =
|
|
368
|
+
const column = getTableColumnByKey(table, y_axis_column_key) || {};
|
|
285
369
|
div.innerHTML = column.name || '';
|
|
286
|
-
if (type ===
|
|
370
|
+
if (type === CHART_TYPE.BAR_STACK) {
|
|
287
371
|
div.innerHTML = title_name || '';
|
|
288
372
|
}
|
|
289
373
|
}
|
|
@@ -291,9 +375,9 @@ class ChartComponent extends _react.Component {
|
|
|
291
375
|
height: containerHeight
|
|
292
376
|
} = this.chartBoundingClientRect;
|
|
293
377
|
let textAlign = 'center';
|
|
294
|
-
if (y_axis_label_position ===
|
|
295
|
-
if (y_axis_label_position ===
|
|
296
|
-
div.setAttribute('style', `color:${
|
|
378
|
+
if (y_axis_label_position === LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
379
|
+
if (y_axis_label_position === LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
380
|
+
div.setAttribute('style', `color:${yColor}; font-size:${yFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yTitleHeight}px; line-height: ${yTitleHeight}px; text-align: ${textAlign}; top: 0; left: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yTitleHeight)}`);
|
|
297
381
|
chartContainer.appendChild(div);
|
|
298
382
|
}
|
|
299
383
|
if (yLabel && y_axis_show_label) {
|
|
@@ -301,9 +385,9 @@ class ChartComponent extends _react.Component {
|
|
|
301
385
|
height: containerHeight
|
|
302
386
|
} = this.chartBoundingClientRect;
|
|
303
387
|
let textAlign = 'center';
|
|
304
|
-
if (y_axis_label_position ===
|
|
305
|
-
if (y_axis_label_position ===
|
|
306
|
-
yLabel.setAttribute('style', `color:${
|
|
388
|
+
if (y_axis_label_position === LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
389
|
+
if (y_axis_label_position === LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
390
|
+
yLabel.setAttribute('style', `color:${yColor}; font-size:${yFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yTitleHeight}px; line-height: ${yTitleHeight}px; text-align: ${textAlign}; top: 0; left: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yTitleHeight)}`);
|
|
307
391
|
}
|
|
308
392
|
if (yLabel && !y_axis_show_label) {
|
|
309
393
|
yLabel.parentNode.removeChild(yLabel);
|
|
@@ -312,21 +396,22 @@ class ChartComponent extends _react.Component {
|
|
|
312
396
|
// yAxis(left) - combination chart
|
|
313
397
|
const yAxisLeftID = `chart-y-axis-left-label_${chart.id}`;
|
|
314
398
|
const yAxisLeftLabel = chartContainer.querySelector(`#${yAxisLeftID}`);
|
|
399
|
+
const yLeftTitleHeight = this.getAxisTitleHeight(yLeftFontSize);
|
|
315
400
|
if (!yAxisLeftLabel && show_y_axis_left_label) {
|
|
316
401
|
const div = document.createElement('div');
|
|
317
402
|
div.id = yAxisLeftID;
|
|
318
403
|
div.className = 'chart-axis-label text-truncate';
|
|
319
|
-
if (y_axis_left_summary_type ===
|
|
320
|
-
div.innerHTML =
|
|
404
|
+
if (y_axis_left_summary_type === CHART_SUMMARY_TYPE.COUNT) {
|
|
405
|
+
div.innerHTML = intl.get('Amount');
|
|
321
406
|
} else {
|
|
322
|
-
const column =
|
|
407
|
+
const column = getTableColumnByKey(table, y_axis_left_summary_column) || {};
|
|
323
408
|
div.innerHTML = column.name || '';
|
|
324
409
|
}
|
|
325
410
|
const containerHeight = chartContainer.offsetHeight;
|
|
326
411
|
let textAlign = 'center';
|
|
327
|
-
if (y_axis_left_label_position ===
|
|
328
|
-
if (y_axis_left_label_position ===
|
|
329
|
-
div.setAttribute('style', `color:${
|
|
412
|
+
if (y_axis_left_label_position === LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
413
|
+
if (y_axis_left_label_position === LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
414
|
+
div.setAttribute('style', `color:${yLeftColor}; font-size:${yLeftFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yLeftTitleHeight}px; line-height: ${yLeftTitleHeight}px; text-align: ${textAlign}; top: 0; left: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yLeftTitleHeight)}`);
|
|
330
415
|
chartContainer.appendChild(div);
|
|
331
416
|
}
|
|
332
417
|
if (yAxisLeftLabel && show_y_axis_left_label) {
|
|
@@ -334,7 +419,7 @@ class ChartComponent extends _react.Component {
|
|
|
334
419
|
let textAlign = 'center';
|
|
335
420
|
if (y_axis_left_label_position === 'bottom') textAlign = 'left';
|
|
336
421
|
if (y_axis_left_label_position === 'top') textAlign = 'right';
|
|
337
|
-
yAxisLeftLabel.setAttribute('style', `color:${
|
|
422
|
+
yAxisLeftLabel.setAttribute('style', `color:${yLeftColor}; font-size:${yLeftFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yLeftTitleHeight}px; line-height: ${yLeftTitleHeight}px; text-align: ${textAlign}; top: 0; left: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yLeftTitleHeight)}`);
|
|
338
423
|
}
|
|
339
424
|
if (yAxisLeftLabel && !show_y_axis_left_label) {
|
|
340
425
|
yAxisLeftLabel.parentNode.removeChild(yAxisLeftLabel);
|
|
@@ -343,21 +428,22 @@ class ChartComponent extends _react.Component {
|
|
|
343
428
|
// yAxis(right) - combination chart
|
|
344
429
|
const yAxisRightID = `chart-y-axis-right-label_${chart.id}`;
|
|
345
430
|
const yAxisRightLabel = chartContainer.querySelector(`#${yAxisRightID}`);
|
|
431
|
+
const yRightTitleHeight = this.getAxisTitleHeight(yRightFontSize);
|
|
346
432
|
if (!yAxisRightLabel && show_y_axis_right_label) {
|
|
347
433
|
const div = document.createElement('div');
|
|
348
434
|
div.id = yAxisRightID;
|
|
349
435
|
div.className = 'chart-axis-label text-truncate';
|
|
350
|
-
if (y_axis_right_summary_type ===
|
|
351
|
-
div.innerHTML =
|
|
436
|
+
if (y_axis_right_summary_type === CHART_SUMMARY_TYPE.COUNT) {
|
|
437
|
+
div.innerHTML = intl.get('Amount');
|
|
352
438
|
} else {
|
|
353
|
-
const column =
|
|
439
|
+
const column = getTableColumnByKey(table, y_axis_right_summary_column) || {};
|
|
354
440
|
div.innerHTML = column.name || '';
|
|
355
441
|
}
|
|
356
442
|
const containerHeight = chartContainer.offsetHeight;
|
|
357
443
|
let textAlign = 'center';
|
|
358
|
-
if (y_axis_right_label_position ===
|
|
359
|
-
if (y_axis_right_label_position ===
|
|
360
|
-
div.setAttribute('style', `color:${
|
|
444
|
+
if (y_axis_right_label_position === LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
445
|
+
if (y_axis_right_label_position === LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
446
|
+
div.setAttribute('style', `color:${yRightColor}; font-size:${yRightFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yRightTitleHeight}px; line-height: ${yRightTitleHeight}px; text-align: ${textAlign}; top: 0; right: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yRightTitleHeight, 'right')}`);
|
|
361
447
|
chartContainer.appendChild(div);
|
|
362
448
|
}
|
|
363
449
|
if (yAxisRightLabel && show_y_axis_right_label) {
|
|
@@ -365,11 +451,16 @@ class ChartComponent extends _react.Component {
|
|
|
365
451
|
let textAlign = 'center';
|
|
366
452
|
if (y_axis_right_label_position === 'bottom') textAlign = 'left';
|
|
367
453
|
if (y_axis_right_label_position === 'top') textAlign = 'right';
|
|
368
|
-
yAxisRightLabel.setAttribute('style', `color:${
|
|
454
|
+
yAxisRightLabel.setAttribute('style', `color:${yRightColor}; font-size:${yRightFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yRightTitleHeight}px; line-height: ${yRightTitleHeight}px; text-align: ${textAlign}; top: 0; right: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yRightTitleHeight, 'right')}`);
|
|
369
455
|
}
|
|
370
456
|
if (yAxisRightLabel && !show_y_axis_right_label) {
|
|
371
457
|
yAxisRightLabel.parentNode.removeChild(yAxisRightLabel);
|
|
372
458
|
}
|
|
459
|
+
this.setAxisTitlePadding(chartContainer, {
|
|
460
|
+
left: y_axis_show_label ? yTitleHeight : show_y_axis_left_label ? yLeftTitleHeight : null,
|
|
461
|
+
right: show_y_axis_right_label ? yRightTitleHeight : null,
|
|
462
|
+
bottom: x_axis_show_label ? xTitleHeight : null
|
|
463
|
+
});
|
|
373
464
|
};
|
|
374
465
|
this.renderHorizontalLabel = (chart, tables, chartContainer) => {
|
|
375
466
|
if (!this.chart || !chart) return;
|
|
@@ -381,85 +472,97 @@ class ChartComponent extends _react.Component {
|
|
|
381
472
|
horizontal_axis_label_position,
|
|
382
473
|
vertical_axis_label_position,
|
|
383
474
|
show_vertical_axis_label,
|
|
384
|
-
show_horizontal_axis_label
|
|
475
|
+
show_horizontal_axis_label,
|
|
476
|
+
horizontal_axis_label_font_size,
|
|
477
|
+
horizontal_axis_label_font_color,
|
|
478
|
+
vertical_axis_label_font_size,
|
|
479
|
+
vertical_axis_label_font_color
|
|
385
480
|
} = chart.config;
|
|
386
|
-
const table =
|
|
387
|
-
const
|
|
481
|
+
const table = getTableById(tables, table_id);
|
|
482
|
+
const defaultTextColor = this.globalTheme === THEME_NAME_MAP.DARK ? DEFAULT_AXIS_LABEL_FONT_COLOR_DARK : DEFAULT_AXIS_LABEL_FONT_COLOR;
|
|
483
|
+
const xColor = horizontal_axis_label_font_color || defaultTextColor;
|
|
484
|
+
const xFontSize = horizontal_axis_label_font_size || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
485
|
+
const yColor = vertical_axis_label_font_color || defaultTextColor;
|
|
486
|
+
const yFontSize = vertical_axis_label_font_size || DEFAULT_AXIS_LABEL_FONT_SIZE;
|
|
388
487
|
const xAxisID = `chart-x-axis-label_${chart.id}`;
|
|
389
488
|
const xLabel = chartContainer.querySelector(`#${xAxisID}`);
|
|
390
489
|
const {
|
|
391
490
|
width: containerWidth
|
|
392
491
|
} = this.chartBoundingClientRect;
|
|
492
|
+
const xTitleHeight = this.getAxisTitleHeight(xFontSize);
|
|
393
493
|
if (!xLabel && show_horizontal_axis_label) {
|
|
394
494
|
const div = document.createElement('div');
|
|
395
495
|
div.id = xAxisID;
|
|
396
496
|
div.className = 'chart-axis-label';
|
|
397
|
-
if (horizontal_axis_summary_type ===
|
|
398
|
-
div.innerHTML =
|
|
497
|
+
if (horizontal_axis_summary_type === CHART_SUMMARY_TYPE.COUNT) {
|
|
498
|
+
div.innerHTML = intl.get('Amount');
|
|
399
499
|
} else {
|
|
400
|
-
const column =
|
|
500
|
+
const column = getTableColumnByKey(table, horizontal_axis_column_key);
|
|
401
501
|
div.innerHTML = `${column ? column.name : ''}`;
|
|
402
502
|
}
|
|
403
|
-
div.setAttribute('style', `color:${
|
|
503
|
+
div.setAttribute('style', `color:${xColor}; font-size:${xFontSize}px; width: ${containerWidth}px; height: ${xTitleHeight}px; line-height: ${xTitleHeight}px; text-align: ${horizontal_axis_label_position}; position: absolute`);
|
|
404
504
|
chartContainer.appendChild(div);
|
|
405
505
|
}
|
|
406
506
|
if (xLabel && show_horizontal_axis_label) {
|
|
407
|
-
xLabel.setAttribute('style', `color:${
|
|
507
|
+
xLabel.setAttribute('style', `color:${xColor}; font-size:${xFontSize}px; width: ${containerWidth}px; height: ${xTitleHeight}px; line-height: ${xTitleHeight}px; text-align: ${horizontal_axis_label_position}; position: absolute`);
|
|
408
508
|
}
|
|
409
509
|
if (xLabel && !show_horizontal_axis_label) {
|
|
410
510
|
xLabel.parentNode.removeChild(xLabel);
|
|
411
511
|
}
|
|
412
512
|
const yAxisID = `chart-y-axis-label_${chart.id}`;
|
|
413
513
|
const yLabel = chartContainer.querySelector(`#${yAxisID}`);
|
|
414
|
-
const
|
|
514
|
+
const yTitleHeight = this.getAxisTitleHeight(yFontSize);
|
|
415
515
|
if (!yLabel && show_vertical_axis_label) {
|
|
416
516
|
const div = document.createElement('div');
|
|
417
517
|
div.id = yAxisID;
|
|
418
518
|
div.className = 'chart-axis-label';
|
|
419
|
-
const column =
|
|
519
|
+
const column = getTableColumnByKey(table, vertical_axis_column_key) || {};
|
|
420
520
|
div.innerHTML = column.name || '';
|
|
421
521
|
const {
|
|
422
522
|
height: containerHeight
|
|
423
523
|
} = this.chartBoundingClientRect;
|
|
424
524
|
let textAlign = 'center';
|
|
425
|
-
if (vertical_axis_label_position ===
|
|
426
|
-
if (vertical_axis_label_position ===
|
|
427
|
-
div.setAttribute('style', `color:${
|
|
525
|
+
if (vertical_axis_label_position === LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
526
|
+
if (vertical_axis_label_position === LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
527
|
+
div.setAttribute('style', `color:${yColor}; font-size:${yFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yTitleHeight}px; line-height: ${yTitleHeight}px; text-align: ${textAlign}; top: 0; left: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yTitleHeight)}`);
|
|
428
528
|
chartContainer.appendChild(div);
|
|
429
529
|
}
|
|
430
|
-
if (yLabel &&
|
|
530
|
+
if (yLabel && show_vertical_axis_label) {
|
|
431
531
|
const {
|
|
432
532
|
height: containerHeight
|
|
433
533
|
} = this.chartBoundingClientRect;
|
|
434
534
|
let textAlign = 'center';
|
|
435
|
-
if (vertical_axis_label_position ===
|
|
436
|
-
if (vertical_axis_label_position ===
|
|
437
|
-
yLabel.setAttribute('style', `color:${
|
|
535
|
+
if (vertical_axis_label_position === LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
536
|
+
if (vertical_axis_label_position === LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
537
|
+
yLabel.setAttribute('style', `color:${yColor}; font-size:${yFontSize}px; position: absolute; width: ${containerHeight}px; height: ${yTitleHeight}px; line-height: ${yTitleHeight}px; text-align: ${textAlign}; top: 0; left: 0; transform: ${this.getRotatedAxisTitleTransform(containerHeight, yTitleHeight)}`);
|
|
438
538
|
}
|
|
439
|
-
if (yLabel && !
|
|
539
|
+
if (yLabel && !show_vertical_axis_label) {
|
|
440
540
|
yLabel.parentNode.removeChild(yLabel);
|
|
441
541
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return !!(chart && chart.config && chart.config.show_horizontal_axis_label);
|
|
542
|
+
this.setAxisTitlePadding(chartContainer, {
|
|
543
|
+
left: show_vertical_axis_label ? yTitleHeight : null,
|
|
544
|
+
bottom: show_horizontal_axis_label ? xTitleHeight : null,
|
|
545
|
+
right: null
|
|
546
|
+
});
|
|
448
547
|
};
|
|
449
548
|
this.formatterLegendName = name => {
|
|
450
|
-
if (
|
|
451
|
-
return
|
|
549
|
+
if (typeof name !== 'string') {
|
|
550
|
+
if (!name && typeof name !== 'number') return intl.get(EMPTY_NAME);
|
|
551
|
+
return intl.get(String(name)) || String(name);
|
|
552
|
+
}
|
|
553
|
+
if (name.trim() === 'undefined' || name.trim() === 'null' || name.trim() === '') {
|
|
554
|
+
return intl.get(EMPTY_NAME);
|
|
452
555
|
} else if (name === '_Others') {
|
|
453
|
-
return
|
|
556
|
+
return intl.get('Others');
|
|
454
557
|
} else {
|
|
455
|
-
return
|
|
558
|
+
return intl.get(name) || name;
|
|
456
559
|
}
|
|
457
560
|
};
|
|
458
561
|
this.setLegend = _ref => {
|
|
459
562
|
var _chart$config, _chart$config2;
|
|
460
563
|
let {
|
|
461
564
|
legendName,
|
|
462
|
-
theme =
|
|
565
|
+
theme = CHART_THEME_COLOR['light'],
|
|
463
566
|
legendPosition = 'top-left',
|
|
464
567
|
data,
|
|
465
568
|
colorScale,
|
|
@@ -468,23 +571,32 @@ class ChartComponent extends _react.Component {
|
|
|
468
571
|
} = _ref;
|
|
469
572
|
if (!this.chart) return;
|
|
470
573
|
this.legendConfig = {
|
|
471
|
-
legendRectWidth: [
|
|
472
|
-
legendRectHeight: [
|
|
574
|
+
legendRectWidth: [CHART_TYPE.SCATTER, CHART_TYPE.MIRROR].includes(chart === null || chart === void 0 ? void 0 : (_chart$config = chart.config) === null || _chart$config === void 0 ? void 0 : _chart$config.type) ? 8 : 20,
|
|
575
|
+
legendRectHeight: [CHART_TYPE.SCATTER, CHART_TYPE.MIRROR].includes(chart === null || chart === void 0 ? void 0 : (_chart$config2 = chart.config) === null || _chart$config2 === void 0 ? void 0 : _chart$config2.type) ? 8 : 6,
|
|
473
576
|
r: this.getLegendR(chart),
|
|
474
577
|
legendItemPaddingTop: 5,
|
|
475
578
|
legendItemTextPaddingTop: 13,
|
|
476
579
|
legendItemMargin: 20,
|
|
477
580
|
legendRecTextGap: 8,
|
|
478
|
-
|
|
479
|
-
|
|
581
|
+
// Space reserved for the page navigator. Start at 0 and only reserve it when
|
|
582
|
+
// pagination is actually needed, so a legend that fits is not pushed onto a
|
|
583
|
+
// hidden page (which made the legend look incomplete/clipped).
|
|
584
|
+
legendPageNavWrapperWidth: 0,
|
|
585
|
+
legendPageNavWrapperHeight: 0,
|
|
586
|
+
legendPageNavMaxWidth: 100,
|
|
587
|
+
legendPageNavMaxHeight: 18,
|
|
480
588
|
legendPosition,
|
|
481
589
|
legendName,
|
|
482
590
|
theme
|
|
483
591
|
};
|
|
484
592
|
|
|
485
593
|
// sort legend data and format data
|
|
486
|
-
|
|
487
|
-
|
|
594
|
+
const clonedData = cloneDeep(data);
|
|
595
|
+
clonedData.forEach(item => item[legendName] = String(item[legendName]));
|
|
596
|
+
const legendData = BaseUtils.sortDataByGroupName(clonedData, legendName, groupColumn, chart);
|
|
597
|
+
|
|
598
|
+
// Record every legend group name so legend click can keep at least one visible.
|
|
599
|
+
this.legendGroupNames = new Set(legendData.map(item => String(item[legendName])));
|
|
488
600
|
const {
|
|
489
601
|
width: chartWidth,
|
|
490
602
|
height: chartHeight,
|
|
@@ -492,7 +604,14 @@ class ChartComponent extends _react.Component {
|
|
|
492
604
|
rightLegendSpace,
|
|
493
605
|
bottomLegendSpace
|
|
494
606
|
} = this.chartBoundingClientRect;
|
|
495
|
-
|
|
607
|
+
let groupsData = this.getLegendDataGroups(legendData);
|
|
608
|
+
// If more than one page is required, reserve room for the page navigator and
|
|
609
|
+
// re-paginate against the reduced space.
|
|
610
|
+
if (groupsData.length > 1) {
|
|
611
|
+
this.legendConfig.legendPageNavWrapperWidth = this.legendConfig.legendPageNavMaxWidth;
|
|
612
|
+
this.legendConfig.legendPageNavWrapperHeight = this.legendConfig.legendPageNavMaxHeight;
|
|
613
|
+
groupsData = this.getLegendDataGroups(legendData);
|
|
614
|
+
}
|
|
496
615
|
if (groupsData.length === 0) return;
|
|
497
616
|
const legendWrapper = this.chart.append('g').attr('class', 'legend-wrapper');
|
|
498
617
|
|
|
@@ -625,7 +744,7 @@ class ChartComponent extends _react.Component {
|
|
|
625
744
|
}).append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('y', legendItemPaddingTop).attr('rx', r).attr('fill', _ref4 => {
|
|
626
745
|
let [groupName] = _ref4;
|
|
627
746
|
if (colorScale) return colorScale(groupName);
|
|
628
|
-
return this.colorMap[groupName] ||
|
|
747
|
+
return this.colorMap[groupName] || CHART_STYLE_COLORS[0];
|
|
629
748
|
}).attr('data-text', _ref5 => {
|
|
630
749
|
let [groupName] = _ref5;
|
|
631
750
|
return groupName;
|
|
@@ -655,6 +774,7 @@ class ChartComponent extends _react.Component {
|
|
|
655
774
|
translateY = prevTranslateY + height + legendItemMargin;
|
|
656
775
|
}
|
|
657
776
|
d3.select(item).attr('transform', `translate(${start},${translateY})`).attr('data-translateY', translateY);
|
|
777
|
+
this.bindLegendItemInteraction(item);
|
|
658
778
|
});
|
|
659
779
|
} else {
|
|
660
780
|
// update g translateX
|
|
@@ -669,6 +789,7 @@ class ChartComponent extends _react.Component {
|
|
|
669
789
|
translateX = prevTranslateX + width + legendItemMargin;
|
|
670
790
|
}
|
|
671
791
|
d3.select(item).attr('transform', `translate(${translateX},0)`).attr('data-translateX', translateX);
|
|
792
|
+
this.bindLegendItemInteraction(item);
|
|
672
793
|
|
|
673
794
|
// legend items add offset
|
|
674
795
|
if (legendPosition === 'top-right') {
|
|
@@ -707,7 +828,7 @@ class ChartComponent extends _react.Component {
|
|
|
707
828
|
if (top && bottom) {
|
|
708
829
|
let allHeight = top;
|
|
709
830
|
const groupsData = [];
|
|
710
|
-
const newLegendData =
|
|
831
|
+
const newLegendData = cloneDeep(legendData);
|
|
711
832
|
let lastIndex = 0;
|
|
712
833
|
legendData.forEach((item, index) => {
|
|
713
834
|
const virtualLegend = this.chart.append('g').attr('opacity', 0);
|
|
@@ -732,7 +853,7 @@ class ChartComponent extends _react.Component {
|
|
|
732
853
|
} else {
|
|
733
854
|
let allWidth = start;
|
|
734
855
|
const groupsData = [];
|
|
735
|
-
const newLegendData =
|
|
856
|
+
const newLegendData = cloneDeep(legendData);
|
|
736
857
|
let lastIndex = 0;
|
|
737
858
|
legendData.forEach((item, index) => {
|
|
738
859
|
const virtualLegend = this.chart.append('g').attr('opacity', 0);
|
|
@@ -816,19 +937,26 @@ class ChartComponent extends _react.Component {
|
|
|
816
937
|
legendItems.forEach(legendItem => {
|
|
817
938
|
const curTranslateX = Number(legendItem.getAttribute('data-translateX')) + offset;
|
|
818
939
|
d3.select(legendItem).attr('transform', `translate(${curTranslateX}, 0)`).attr('data-translateX', curTranslateX);
|
|
819
|
-
|
|
940
|
+
const isHidden = this.hiddenLegendGroups && this.hiddenLegendGroups.has(String(legendItem.getAttribute('data-groupName')));
|
|
941
|
+
d3.select(legendItem).attr('opacity', isHidden ? 0.35 : 1);
|
|
820
942
|
});
|
|
821
943
|
};
|
|
944
|
+
this.bindLegendItemInteraction = item => {
|
|
945
|
+
if (!item) return;
|
|
946
|
+
const groupName = item.getAttribute('data-groupName');
|
|
947
|
+
const isHidden = this.hiddenLegendGroups && this.hiddenLegendGroups.has(String(groupName));
|
|
948
|
+
d3.select(item).style('cursor', 'pointer').attr('opacity', isHidden ? 0.35 : 1).on('click', () => this.handleLegendClick(groupName));
|
|
949
|
+
};
|
|
822
950
|
this.sortLegend = (result, groupColumn, legendName) => {
|
|
823
951
|
result.forEach(item => {
|
|
824
952
|
const option = groupColumn.data.options.find(option => option.name === item[legendName]);
|
|
825
|
-
if (option
|
|
953
|
+
if (option === null || option === void 0 ? void 0 : option.id) {
|
|
826
954
|
item['group_name_id'] = option.id;
|
|
827
955
|
item['oldName'] = item.name;
|
|
828
956
|
item.name = item['group_name_id'];
|
|
829
957
|
}
|
|
830
958
|
});
|
|
831
|
-
|
|
959
|
+
BaseUtils.sortCharts(result, groupColumn, 'name');
|
|
832
960
|
result.forEach(item => {
|
|
833
961
|
item.name = item['oldName'];
|
|
834
962
|
});
|
|
@@ -841,8 +969,8 @@ class ChartComponent extends _react.Component {
|
|
|
841
969
|
const {
|
|
842
970
|
type
|
|
843
971
|
} = config;
|
|
844
|
-
if (type ===
|
|
845
|
-
if (type ===
|
|
972
|
+
if (type === CHART_TYPE.SCATTER) return 4;
|
|
973
|
+
if (type === CHART_TYPE.MIRROR) return 0;
|
|
846
974
|
return 3;
|
|
847
975
|
};
|
|
848
976
|
this.calcEquilateralTriangle = (cx, cy, size, direction) => {
|
|
@@ -856,12 +984,12 @@ class ChartComponent extends _react.Component {
|
|
|
856
984
|
let groupName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'group_name';
|
|
857
985
|
let groupColumn = arguments.length > 3 ? arguments[3] : undefined;
|
|
858
986
|
let chart = arguments.length > 4 ? arguments[4] : undefined;
|
|
859
|
-
const newData =
|
|
987
|
+
const newData = BaseUtils.sortDataByGroupName(cloneDeep(data), groupName, groupColumn, chart);
|
|
860
988
|
let currentIdx = 0;
|
|
861
|
-
const defaultColors =
|
|
989
|
+
const defaultColors = CHART_STYLE_COLORS;
|
|
862
990
|
let colors = defaultColors;
|
|
863
991
|
if (chartColorTheme) {
|
|
864
|
-
colors =
|
|
992
|
+
colors = BaseUtils.getCurrentTheme(chartColorTheme).colors;
|
|
865
993
|
}
|
|
866
994
|
const colorMap = newData.reduce((acc, cur) => {
|
|
867
995
|
const key = cur[groupName] || cur[groupName] === 0 ? cur[groupName] : '';
|
|
@@ -961,37 +1089,25 @@ class ChartComponent extends _react.Component {
|
|
|
961
1089
|
formatted_value: item.formatted_value + ''
|
|
962
1090
|
});
|
|
963
1091
|
}
|
|
964
|
-
if (type ===
|
|
1092
|
+
if (type === CHART_TYPE.WORLD_MAP_BUBBLE) {
|
|
965
1093
|
sum += item.value;
|
|
966
1094
|
}
|
|
967
1095
|
}
|
|
968
1096
|
}
|
|
969
1097
|
});
|
|
970
|
-
if (type ===
|
|
1098
|
+
if (type === CHART_TYPE.WORLD_MAP_BUBBLE) {
|
|
971
1099
|
statisticNewData.sum = sum;
|
|
972
1100
|
}
|
|
973
1101
|
return statisticNewData;
|
|
974
1102
|
};
|
|
975
|
-
this.isShowXAxisLabel = chart => {
|
|
976
|
-
return !!(chart && chart.config && chart.config.x_axis_show_label);
|
|
977
|
-
};
|
|
978
|
-
this.isShowYAxisLabel = chart => {
|
|
979
|
-
return !!(chart && chart.config && chart.config.y_axis_show_label);
|
|
980
|
-
};
|
|
981
|
-
this.isShowYAxisLeftLabel = chart => {
|
|
982
|
-
return !!(chart && chart.config && chart.config.show_y_axis_left_label);
|
|
983
|
-
};
|
|
984
|
-
this.isShowYAxisRightLabel = chart => {
|
|
985
|
-
return !!(chart && chart.config && chart.config.show_y_axis_right_label);
|
|
986
|
-
};
|
|
987
1103
|
this.getThemeColors = function () {
|
|
988
1104
|
let themeColors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
989
1105
|
let theme = arguments.length > 1 ? arguments[1] : undefined;
|
|
990
1106
|
// dark->custom->light
|
|
991
|
-
if (theme ===
|
|
992
|
-
themeColors =
|
|
1107
|
+
if (theme === THEME_NAME_MAP.DARK) {
|
|
1108
|
+
themeColors = CHART_THEME_COLOR.dark;
|
|
993
1109
|
}
|
|
994
|
-
return themeColors ||
|
|
1110
|
+
return themeColors || CHART_THEME_COLOR[THEME_NAME_MAP.LIGHT];
|
|
995
1111
|
};
|
|
996
1112
|
this.setDispalyGoalLine = (goal_label, goal_value, insertPadding, yScale) => {
|
|
997
1113
|
const {
|
|
@@ -1012,7 +1128,7 @@ class ChartComponent extends _react.Component {
|
|
|
1012
1128
|
label_font_size,
|
|
1013
1129
|
text
|
|
1014
1130
|
} = _ref6;
|
|
1015
|
-
d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('y', Number(y) - 10).attr('fill', theme.labelColor).attr('font-size',
|
|
1131
|
+
d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('y', Number(y) - 10).attr('fill', theme.labelColor).attr('font-size', BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
|
|
1016
1132
|
if (!g.node()) return;
|
|
1017
1133
|
const {
|
|
1018
1134
|
width
|
|
@@ -1031,7 +1147,7 @@ class ChartComponent extends _react.Component {
|
|
|
1031
1147
|
label_font_size,
|
|
1032
1148
|
text
|
|
1033
1149
|
} = _ref7;
|
|
1034
|
-
d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('x', Number(x) + Number(xWidth) + 10).attr('y', Number(y)).attr('fill', theme.labelColor).attr('dominant-baseline', 'hanging').attr('font-size',
|
|
1150
|
+
d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('x', Number(x) + Number(xWidth) + 10).attr('y', Number(y)).attr('fill', theme.labelColor).attr('dominant-baseline', 'hanging').attr('font-size', BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
|
|
1035
1151
|
if (g.node()) {
|
|
1036
1152
|
var _g$node;
|
|
1037
1153
|
const {
|
|
@@ -1053,7 +1169,7 @@ class ChartComponent extends _react.Component {
|
|
|
1053
1169
|
label_font_size,
|
|
1054
1170
|
text
|
|
1055
1171
|
} = _ref8;
|
|
1056
|
-
d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('fill', theme.labelColor).attr('font-size',
|
|
1172
|
+
d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('fill', theme.labelColor).attr('font-size', BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
|
|
1057
1173
|
if (!g.node()) return;
|
|
1058
1174
|
const {
|
|
1059
1175
|
width,
|
|
@@ -1061,7 +1177,7 @@ class ChartComponent extends _react.Component {
|
|
|
1061
1177
|
} = g.node().getBoundingClientRect();
|
|
1062
1178
|
const translateX = Number(x) + xWidth / 2 - width / 2;
|
|
1063
1179
|
let translateY = Number(y) + Number(yheight / 2) + height / 2;
|
|
1064
|
-
if (chartType ===
|
|
1180
|
+
if (chartType === CHART_TYPE.BAR_STACK) {
|
|
1065
1181
|
translateY = translateY;
|
|
1066
1182
|
}
|
|
1067
1183
|
g.attr('transform', `translate(${translateX}, ${translateY})`);
|
|
@@ -1072,8 +1188,8 @@ class ChartComponent extends _react.Component {
|
|
|
1072
1188
|
allGroup.forEach(g => {
|
|
1073
1189
|
const rects = Array.from(g.children).filter(item => item.tagName !== 'text');
|
|
1074
1190
|
rects.forEach(item => {
|
|
1075
|
-
d3.select(item).transition().duration(this.
|
|
1076
|
-
if ([
|
|
1191
|
+
d3.select(item).transition().duration(this.interactionDuration).attr('opacity', 1);
|
|
1192
|
+
if ([CHART_TYPE.PIE, CHART_TYPE.RING].includes(chartType)) {
|
|
1077
1193
|
d3.select(item).attr('stroke-width', 2);
|
|
1078
1194
|
}
|
|
1079
1195
|
});
|
|
@@ -1084,9 +1200,9 @@ class ChartComponent extends _react.Component {
|
|
|
1084
1200
|
const rects = Array.from(g.children).filter(item => item.tagName !== 'text');
|
|
1085
1201
|
rects.forEach(item => {
|
|
1086
1202
|
if (item.getAttribute('data-groupName') !== curGroupName) {
|
|
1087
|
-
d3.selectAll([item]).transition().duration(this.
|
|
1203
|
+
d3.selectAll([item]).transition().duration(this.interactionDuration).attr('opacity', 0.3);
|
|
1088
1204
|
} else {
|
|
1089
|
-
if ([
|
|
1205
|
+
if ([CHART_TYPE.PIE, CHART_TYPE.RING].includes(chartType)) {
|
|
1090
1206
|
d3.select(item).attr('stroke-width', 0.5);
|
|
1091
1207
|
}
|
|
1092
1208
|
}
|
|
@@ -1094,37 +1210,222 @@ class ChartComponent extends _react.Component {
|
|
|
1094
1210
|
});
|
|
1095
1211
|
}
|
|
1096
1212
|
};
|
|
1097
|
-
// Use clipPath to make rectangle rounded corners
|
|
1098
1213
|
this.addClipPath = _ref9 => {
|
|
1099
1214
|
let {
|
|
1100
1215
|
rect,
|
|
1101
|
-
parentNode,
|
|
1102
1216
|
attr,
|
|
1103
|
-
rectId,
|
|
1104
1217
|
borderRadiusVal
|
|
1105
1218
|
} = _ref9;
|
|
1219
|
+
return this.addRoundedClip(rect, attr === 'x' ? 'x' : 'y', null, borderRadiusVal);
|
|
1220
|
+
};
|
|
1221
|
+
this.addRoundedClip = function (rect, orient) {
|
|
1222
|
+
let width = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
1223
|
+
let radiusOverride = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1106
1224
|
const {
|
|
1107
1225
|
borderRadius
|
|
1108
|
-
} =
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1226
|
+
} = _this.chartBoundingClientRect;
|
|
1227
|
+
const x = Number(rect.getAttribute('x'));
|
|
1228
|
+
const y = Number(rect.getAttribute('y'));
|
|
1229
|
+
const w = width != null ? width : Number(rect.getAttribute('width'));
|
|
1230
|
+
const h = Number(rect.getAttribute('height'));
|
|
1231
|
+
const computedRadius = orient === 'x' ? Math.min(h * borderRadius, h / 2, w / 2) : Math.min(w * borderRadius, w / 2, h / 2);
|
|
1232
|
+
const radius = radiusOverride != null ? Math.min(radiusOverride, w / 2, h / 2) : computedRadius;
|
|
1233
|
+
const d = orient === 'x' ? _this.getRightRoundedRectPath(x, y, w, h, radius) : _this.getTopRoundedRectPath(x, y, w, h, radius);
|
|
1234
|
+
const clipId = `rounded-clip-${Math.random().toString(36).slice(2)}`;
|
|
1235
|
+
const path = _this.getDefs().append('clipPath').attr('id', clipId).append('path').attr('class', 'rounded-clip-path').attr('data-x', x).attr('data-y', y).attr('data-width', w).attr('data-height', h).attr('data-radius', radius).attr('data-orient', orient).attr('d', d);
|
|
1236
|
+
d3.select(rect).attr('clip-path', `url(#${clipId})`);
|
|
1237
|
+
_this._clipMaskByRect.set(rect, path.node());
|
|
1238
|
+
return path.node();
|
|
1239
|
+
};
|
|
1240
|
+
this.animateMaskForRect = (rect, orient, baseline, t) => {
|
|
1241
|
+
const path = this._clipMaskByRect && this._clipMaskByRect.get(rect);
|
|
1242
|
+
if (!path) return;
|
|
1243
|
+
const x = Number(path.getAttribute('data-x'));
|
|
1244
|
+
const y = Number(path.getAttribute('data-y'));
|
|
1245
|
+
const width = Number(path.getAttribute('data-width'));
|
|
1246
|
+
const height = Number(path.getAttribute('data-height'));
|
|
1247
|
+
const radius = Number(path.getAttribute('data-radius'));
|
|
1248
|
+
const el = d3.select(path);
|
|
1249
|
+
if (orient === 'x') {
|
|
1250
|
+
const interpX = d3.interpolateNumber(baseline, x);
|
|
1251
|
+
const interpW = d3.interpolateNumber(0, width);
|
|
1252
|
+
el.attr('d', this.getRightRoundedRectPath(baseline, y, 0, height, radius)).transition(t).attrTween('d', () => tt => this.getRightRoundedRectPath(interpX(tt), y, interpW(tt), height, radius));
|
|
1117
1253
|
} else {
|
|
1118
|
-
const
|
|
1119
|
-
const
|
|
1120
|
-
|
|
1121
|
-
const safeBorderRadius = Math.min(borderRadiusVal !== null && borderRadiusVal !== void 0 ? borderRadiusVal : computedBorderRadius, rectWidth / 2, rectHeight / 2);
|
|
1122
|
-
clipRect.attr('rx', safeBorderRadius);
|
|
1123
|
-
clipRect.attr('height', rectHeight + safeBorderRadius);
|
|
1254
|
+
const interpY = d3.interpolateNumber(baseline, y);
|
|
1255
|
+
const interpH = d3.interpolateNumber(0, height);
|
|
1256
|
+
el.attr('d', this.getTopRoundedRectPath(x, baseline, width, 0, radius)).transition(t).attrTween('d', () => tt => this.getTopRoundedRectPath(x, interpY(tt), width, interpH(tt), radius));
|
|
1124
1257
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1258
|
+
};
|
|
1259
|
+
this.getTopRoundedRectPath = (x, y, width, height, radius) => {
|
|
1260
|
+
const r = Math.min(radius, width / 2, height / 2);
|
|
1261
|
+
if (height <= 0) return `M${x},${y} L${x + width},${y} L${x + width},${y} L${x},${y} Z`;
|
|
1262
|
+
return `M${x},${y + r} Q${x},${y} ${x + r},${y} L${x + width - r},${y} Q${x + width},${y} ${x + width},${y + r} L${x + width},${y + height} L${x},${y + height} Z`;
|
|
1263
|
+
};
|
|
1264
|
+
this.getRightRoundedRectPath = (x, y, width, height, radius) => {
|
|
1265
|
+
const r = Math.min(radius, width / 2, height / 2);
|
|
1266
|
+
if (width <= 0) return `M${x},${y} L${x},${y + height} L${x},${y + height} L${x},${y} Z`;
|
|
1267
|
+
return `M${x},${y} L${x + width - r},${y} Q${x + width},${y} ${x + width},${y + r} L${x + width},${y + height - r} Q${x + width},${y + height} ${x + width - r},${y + height} L${x},${y + height} Z`;
|
|
1268
|
+
};
|
|
1269
|
+
this.animateRectGrowInY = function (selection) {
|
|
1270
|
+
let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.transitionDuration;
|
|
1271
|
+
if (!selection || selection.empty()) return;
|
|
1272
|
+
const self = _this;
|
|
1273
|
+
selection.each(function () {
|
|
1274
|
+
const finalY = Number(this.getAttribute('y'));
|
|
1275
|
+
const finalHeight = Number(this.getAttribute('height'));
|
|
1276
|
+
if (!(finalHeight > 0)) return;
|
|
1277
|
+
const baseline = finalY + finalHeight;
|
|
1278
|
+
const t = d3.transition(self.enterTransitionName).duration(duration).ease(d3.easeCubicOut);
|
|
1279
|
+
d3.select(this).attr('y', baseline).attr('height', 0).transition(t).attr('y', finalY).attr('height', finalHeight);
|
|
1280
|
+
self.animateMaskForRect(this, 'y', baseline, t);
|
|
1281
|
+
});
|
|
1282
|
+
};
|
|
1283
|
+
this.animateStackGrowInY = function (selection) {
|
|
1284
|
+
let groupKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : node => node.getAttribute('x');
|
|
1285
|
+
let duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this.transitionDuration;
|
|
1286
|
+
if (!selection || selection.empty()) return null;
|
|
1287
|
+
const columns = new Map();
|
|
1288
|
+
selection.each(function () {
|
|
1289
|
+
if (!(Number(this.getAttribute('height')) > 0)) return;
|
|
1290
|
+
const key = groupKey(this);
|
|
1291
|
+
if (!columns.has(key)) columns.set(key, []);
|
|
1292
|
+
columns.get(key).push(this);
|
|
1293
|
+
});
|
|
1294
|
+
if (columns.size === 0) return null;
|
|
1295
|
+
const t = d3.transition(_this.enterTransitionName).duration(duration).ease(d3.easeCubicOut);
|
|
1296
|
+
columns.forEach(rects => {
|
|
1297
|
+
let baselineY = -Infinity;
|
|
1298
|
+
rects.forEach(rect => {
|
|
1299
|
+
baselineY = Math.max(baselineY, Number(rect.getAttribute('y')) + Number(rect.getAttribute('height')));
|
|
1300
|
+
});
|
|
1301
|
+
rects.forEach(rect => {
|
|
1302
|
+
const finalY = Number(rect.getAttribute('y'));
|
|
1303
|
+
const finalHeight = Number(rect.getAttribute('height'));
|
|
1304
|
+
d3.select(rect).attr('y', baselineY).attr('height', 0).transition(t).attr('y', finalY).attr('height', finalHeight);
|
|
1305
|
+
_this.animateMaskForRect(rect, 'y', baselineY, t);
|
|
1306
|
+
});
|
|
1307
|
+
});
|
|
1308
|
+
return t;
|
|
1309
|
+
};
|
|
1310
|
+
this.animateRectGrowInX = function (selection) {
|
|
1311
|
+
let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.transitionDuration;
|
|
1312
|
+
if (!selection || selection.empty()) return;
|
|
1313
|
+
const self = _this;
|
|
1314
|
+
selection.each(function () {
|
|
1315
|
+
const finalX = Number(this.getAttribute('x'));
|
|
1316
|
+
const finalWidth = Number(this.getAttribute('width'));
|
|
1317
|
+
if (!(finalWidth > 0)) return;
|
|
1318
|
+
const t = d3.transition(self.enterTransitionName).duration(duration).ease(d3.easeCubicOut);
|
|
1319
|
+
d3.select(this).attr('width', 0).transition(t).attr('width', finalWidth);
|
|
1320
|
+
self.animateMaskForRect(this, 'x', finalX, t);
|
|
1321
|
+
});
|
|
1322
|
+
};
|
|
1323
|
+
this.animateStackGrowInX = function (selection) {
|
|
1324
|
+
let groupKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : node => node.getAttribute('y');
|
|
1325
|
+
let duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this.transitionDuration;
|
|
1326
|
+
if (!selection || selection.empty()) return null;
|
|
1327
|
+
const rows = new Map();
|
|
1328
|
+
selection.each(function () {
|
|
1329
|
+
if (!(Number(this.getAttribute('width')) > 0)) return;
|
|
1330
|
+
const key = groupKey(this);
|
|
1331
|
+
if (!rows.has(key)) rows.set(key, []);
|
|
1332
|
+
rows.get(key).push(this);
|
|
1333
|
+
});
|
|
1334
|
+
if (rows.size === 0) return null;
|
|
1335
|
+
const t = d3.transition(_this.enterTransitionName).duration(duration).ease(d3.easeCubicOut);
|
|
1336
|
+
rows.forEach(rects => {
|
|
1337
|
+
let baselineX = Infinity;
|
|
1338
|
+
rects.forEach(rect => {
|
|
1339
|
+
baselineX = Math.min(baselineX, Number(rect.getAttribute('x')));
|
|
1340
|
+
});
|
|
1341
|
+
rects.forEach(rect => {
|
|
1342
|
+
const finalX = Number(rect.getAttribute('x'));
|
|
1343
|
+
const finalWidth = Number(rect.getAttribute('width'));
|
|
1344
|
+
d3.select(rect).attr('x', baselineX).attr('width', 0).transition(t).attr('x', finalX).attr('width', finalWidth);
|
|
1345
|
+
_this.animateMaskForRect(rect, 'x', baselineX, t);
|
|
1346
|
+
});
|
|
1347
|
+
});
|
|
1348
|
+
return t;
|
|
1349
|
+
};
|
|
1350
|
+
this.animateArcGrowIn = function (selection, arc) {
|
|
1351
|
+
let duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this.transitionDuration;
|
|
1352
|
+
if (!selection || selection.empty()) return;
|
|
1353
|
+
const transitionName = _this.enterTransitionName;
|
|
1354
|
+
selection.each(function (d) {
|
|
1355
|
+
const path = d3.select(this);
|
|
1356
|
+
const interpolate = d3.interpolate({
|
|
1357
|
+
startAngle: d.startAngle,
|
|
1358
|
+
endAngle: d.startAngle,
|
|
1359
|
+
padAngle: d.padAngle
|
|
1360
|
+
}, {
|
|
1361
|
+
startAngle: d.startAngle,
|
|
1362
|
+
endAngle: d.endAngle,
|
|
1363
|
+
padAngle: d.padAngle
|
|
1364
|
+
});
|
|
1365
|
+
path.attr('d', arc(interpolate(0))).transition(transitionName).duration(duration).ease(d3.easeCubicOut).attrTween('d', () => t => arc(interpolate(t)));
|
|
1366
|
+
});
|
|
1367
|
+
};
|
|
1368
|
+
this.animatePathDrawIn = function (selection) {
|
|
1369
|
+
let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.transitionDuration;
|
|
1370
|
+
if (!selection || selection.empty()) return;
|
|
1371
|
+
const transitionName = _this.enterTransitionName;
|
|
1372
|
+
selection.each(function () {
|
|
1373
|
+
const path = d3.select(this);
|
|
1374
|
+
let totalLength = 0;
|
|
1375
|
+
try {
|
|
1376
|
+
totalLength = this.getTotalLength();
|
|
1377
|
+
} catch (e) {
|
|
1378
|
+
totalLength = 0;
|
|
1379
|
+
}
|
|
1380
|
+
if (!(totalLength > 0)) return;
|
|
1381
|
+
path.attr('stroke-dasharray', `${totalLength} ${totalLength}`).attr('stroke-dashoffset', totalLength).transition(transitionName).duration(duration).ease(d3.easeLinear).attr('stroke-dashoffset', 0).on('end', function () {
|
|
1382
|
+
d3.select(this).attr('stroke-dasharray', null).attr('stroke-dashoffset', null);
|
|
1383
|
+
});
|
|
1384
|
+
});
|
|
1385
|
+
};
|
|
1386
|
+
this.animateRevealInX = function (selection, width) {
|
|
1387
|
+
let duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this.transitionDuration;
|
|
1388
|
+
if (!selection || selection.empty()) return;
|
|
1389
|
+
const {
|
|
1390
|
+
height: chartHeight
|
|
1391
|
+
} = _this.chartBoundingClientRect;
|
|
1392
|
+
const clipId = `reveal-clip-${Math.random().toString(36).slice(2)}`;
|
|
1393
|
+
const clipPath = _this.getDefs().append('clipPath').attr('id', clipId);
|
|
1394
|
+
const clipRect = clipPath.append('rect').attr('x', 0).attr('y', 0).attr('width', 0).attr('height', chartHeight);
|
|
1395
|
+
selection.attr('clip-path', `url(#${clipId})`);
|
|
1396
|
+
clipRect.transition(_this.enterTransitionName).duration(duration).ease(d3.easeLinear).attr('width', width).on('end', () => {
|
|
1397
|
+
selection.attr('clip-path', null);
|
|
1398
|
+
clipPath.remove();
|
|
1399
|
+
});
|
|
1400
|
+
};
|
|
1401
|
+
this.animateFadeIn = function (selection) {
|
|
1402
|
+
let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.transitionDuration;
|
|
1403
|
+
let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
1404
|
+
let finalOpacity = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1405
|
+
if (!selection || selection.empty()) return;
|
|
1406
|
+
const transitionName = _this.enterTransitionName;
|
|
1407
|
+
selection.each(function () {
|
|
1408
|
+
const el = d3.select(this);
|
|
1409
|
+
let target = finalOpacity;
|
|
1410
|
+
if (target == null) {
|
|
1411
|
+
const orig = this.getAttribute('opacity');
|
|
1412
|
+
const parsed = orig === null || orig === '' ? 1 : Number(orig);
|
|
1413
|
+
target = Number.isNaN(parsed) ? 1 : parsed;
|
|
1414
|
+
}
|
|
1415
|
+
if (!(target > 0)) return;
|
|
1416
|
+
el.attr('opacity', 0).transition(transitionName).duration(duration).delay(delay).ease(d3.easeLinear).attr('opacity', target);
|
|
1417
|
+
});
|
|
1418
|
+
};
|
|
1419
|
+
this.animateCircleZoomIn = function (selection) {
|
|
1420
|
+
let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.transitionDuration;
|
|
1421
|
+
if (!selection || selection.empty()) return;
|
|
1422
|
+
const transitionName = _this.enterTransitionName;
|
|
1423
|
+
selection.each(function () {
|
|
1424
|
+
const circle = d3.select(this);
|
|
1425
|
+
const finalR = Number(this.getAttribute('r')) || 0;
|
|
1426
|
+
if (!(finalR > 0)) return;
|
|
1427
|
+
circle.attr('r', 0).transition(transitionName).duration(duration).ease(d3.easeCubicOut).attr('r', finalR);
|
|
1428
|
+
});
|
|
1128
1429
|
};
|
|
1129
1430
|
this.drawYaxis = function (g, theme) {
|
|
1130
1431
|
let rightAxisOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
@@ -1138,33 +1439,92 @@ class ChartComponent extends _react.Component {
|
|
|
1138
1439
|
// add text
|
|
1139
1440
|
g.selectAll('text').attr('font-size', theme.fontSize);
|
|
1140
1441
|
g.selectAll('text').attr('fill', theme.textColor);
|
|
1442
|
+
_this.thinYAxisTicks(g);
|
|
1141
1443
|
_this.checkTextOverflow(g.selectAll('text').nodes());
|
|
1142
1444
|
|
|
1143
1445
|
// line
|
|
1144
1446
|
g.selectAll('line').node() && g.selectAll('line').node().remove(); // delete the first line
|
|
1145
|
-
g.selectAll('.tick line').clone().attr('x2', chartWidth -
|
|
1447
|
+
g.selectAll('.tick line').clone().attr('x2', chartWidth - _this.getYAxisTranslateX() - insertPadding - rightAxisOffset).attr('stroke', theme.gridColor).attr('stroke-dasharray', '8,3');
|
|
1146
1448
|
|
|
1147
1449
|
// update g translateX
|
|
1148
|
-
g.attr('transform', `translate(${
|
|
1450
|
+
g.attr('transform', `translate(${_this.getYAxisTranslateX()}, 0)`);
|
|
1451
|
+
};
|
|
1452
|
+
this.thinYAxisTicks = g => {
|
|
1453
|
+
const ticks = g.selectAll('.tick').nodes();
|
|
1454
|
+
if (ticks.length <= 2) return;
|
|
1455
|
+
const visibleTicks = ticks.map((tick, index) => {
|
|
1456
|
+
const text = d3.select(tick).select('text').node();
|
|
1457
|
+
if (!text) return null;
|
|
1458
|
+
const {
|
|
1459
|
+
top,
|
|
1460
|
+
bottom
|
|
1461
|
+
} = text.getBoundingClientRect();
|
|
1462
|
+
return {
|
|
1463
|
+
tick,
|
|
1464
|
+
index,
|
|
1465
|
+
top,
|
|
1466
|
+
bottom
|
|
1467
|
+
};
|
|
1468
|
+
}).filter(Boolean).sort((a, b) => a.top - b.top);
|
|
1469
|
+
const keptTicks = [];
|
|
1470
|
+
let prevBottom = -Infinity;
|
|
1471
|
+
visibleTicks.forEach(_ref10 => {
|
|
1472
|
+
let {
|
|
1473
|
+
tick,
|
|
1474
|
+
index,
|
|
1475
|
+
top,
|
|
1476
|
+
bottom
|
|
1477
|
+
} = _ref10;
|
|
1478
|
+
const shouldKeepFirstTick = index === 0;
|
|
1479
|
+
const shouldKeepLastTick = index === ticks.length - 1;
|
|
1480
|
+
const hasEnoughSpace = top > prevBottom + this.yAxisTickLabelGap;
|
|
1481
|
+
if (shouldKeepLastTick) {
|
|
1482
|
+
keptTicks.forEach(keptTick => {
|
|
1483
|
+
if (keptTick.bottom + this.yAxisTickLabelGap >= top) {
|
|
1484
|
+
d3.select(keptTick.tick).attr('opacity', 0);
|
|
1485
|
+
}
|
|
1486
|
+
});
|
|
1487
|
+
d3.select(tick).attr('opacity', 1);
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
if (shouldKeepFirstTick || hasEnoughSpace) {
|
|
1491
|
+
d3.select(tick).attr('opacity', 1);
|
|
1492
|
+
keptTicks.push({
|
|
1493
|
+
tick,
|
|
1494
|
+
bottom
|
|
1495
|
+
});
|
|
1496
|
+
prevBottom = bottom;
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
d3.select(tick).attr('opacity', 0);
|
|
1500
|
+
});
|
|
1149
1501
|
};
|
|
1150
1502
|
this.checkTextOverflow = allTextEl => {
|
|
1151
1503
|
const {
|
|
1152
1504
|
insertPadding
|
|
1153
1505
|
} = this.chartBoundingClientRect;
|
|
1154
1506
|
const allTextWidth = allTextEl.map(item => {
|
|
1507
|
+
const tick = item.parentNode;
|
|
1508
|
+
if (tick && Number(tick.getAttribute('opacity')) === 0) return 0;
|
|
1155
1509
|
const {
|
|
1156
1510
|
width
|
|
1157
1511
|
} = item.getBoundingClientRect();
|
|
1158
1512
|
return width;
|
|
1159
1513
|
});
|
|
1160
|
-
const maxTextWidth = Math.max(...allTextWidth);
|
|
1514
|
+
const maxTextWidth = Math.max(...allTextWidth, 0);
|
|
1161
1515
|
this.horizontalOverflowOffset = 0;
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
const offset =
|
|
1516
|
+
const requiredLeftSpace = maxTextWidth + 3;
|
|
1517
|
+
if (requiredLeftSpace > insertPadding) {
|
|
1518
|
+
const offset = requiredLeftSpace - insertPadding;
|
|
1165
1519
|
this.horizontalOverflowOffset = offset;
|
|
1166
1520
|
}
|
|
1167
1521
|
};
|
|
1522
|
+
this.getYAxisTranslateX = () => {
|
|
1523
|
+
const {
|
|
1524
|
+
insertPadding
|
|
1525
|
+
} = this.chartBoundingClientRect;
|
|
1526
|
+
return insertPadding + this.horizontalOverflowOffset;
|
|
1527
|
+
};
|
|
1168
1528
|
this.checkTickOverlap = (g, axis) => {
|
|
1169
1529
|
const allTicks = g.selectAll('.tick').nodes();
|
|
1170
1530
|
if (axis === 'yAxis') {
|
|
@@ -1316,10 +1676,85 @@ class ChartComponent extends _react.Component {
|
|
|
1316
1676
|
const annotationWrapper = contentWrapper.insert('g', ':first-child').attr('class', 'vertical-annotation-wrapper');
|
|
1317
1677
|
annotationWrapper.append('line').attr('x1', x).attr('y1', insertPadding + marginTop).attr('x2', x).attr('y2', chartHeight - insertPadding).attr('stroke', theme.XAxisColor);
|
|
1318
1678
|
};
|
|
1679
|
+
this.setLegendForHeatMap = _ref11 => {
|
|
1680
|
+
let {
|
|
1681
|
+
exampleColors,
|
|
1682
|
+
themeColors
|
|
1683
|
+
} = _ref11;
|
|
1684
|
+
const legendOffsetY = 3;
|
|
1685
|
+
const legendItemTextWidth = 32;
|
|
1686
|
+
const legendItemWidth = 12;
|
|
1687
|
+
const legendItemHeight = 12;
|
|
1688
|
+
const legendItemGap = 3;
|
|
1689
|
+
const legendItemRadius = 2;
|
|
1690
|
+
const legendWrapper = this.chart.append('g').attr('class', 'legend-heat-map-wrapper').attr('transform', `translate(0, ${legendOffsetY})`);
|
|
1691
|
+
legendWrapper.append('text').attr('y', 10).attr('fill', themeColors.textColor).attr('font-size', 12).attr('font-weight', 'bold').text(intl.get('Less'));
|
|
1692
|
+
exampleColors.forEach((color, index) => {
|
|
1693
|
+
legendWrapper.append('rect').attr('x', legendItemTextWidth + index * legendItemWidth + index * legendItemGap).attr('width', legendItemWidth).attr('height', legendItemHeight).attr('rx', legendItemRadius).attr('fill', color).attr('stroke', FILL_BORDER_COLOR_MAP[color]).attr('stroke-width', 1);
|
|
1694
|
+
});
|
|
1695
|
+
legendWrapper.append('text').attr('x', 182).attr('y', 10).attr('fill', themeColors.textColor).attr('font-size', 12).attr('font-weight', 'bold').text(intl.get('More'));
|
|
1696
|
+
};
|
|
1697
|
+
this.setContinuousLegend = _ref12 => {
|
|
1698
|
+
var _this$chart$node2;
|
|
1699
|
+
let {
|
|
1700
|
+
previewType,
|
|
1701
|
+
theme,
|
|
1702
|
+
colorRange = [],
|
|
1703
|
+
legendDirection,
|
|
1704
|
+
legendSize,
|
|
1705
|
+
legendTextRange,
|
|
1706
|
+
bubbleColor,
|
|
1707
|
+
type
|
|
1708
|
+
} = _ref12;
|
|
1709
|
+
const {
|
|
1710
|
+
width: chartWidth,
|
|
1711
|
+
height: chartHeight,
|
|
1712
|
+
insertPadding
|
|
1713
|
+
} = this.chartBoundingClientRect;
|
|
1714
|
+
const legendRectWidth = legendDirection === 'vertical' ? 12 : Math.min(legendSize * 100, chartWidth - insertPadding * 2);
|
|
1715
|
+
const legendRectHeight = legendDirection === 'vertical' ? Math.min(legendSize * 100, chartHeight - insertPadding * 2) : 12;
|
|
1716
|
+
const legendTextOffset = 2;
|
|
1717
|
+
const legendTextHeightSpace = legendDirection === 'vertical' ? 0 : 14 + legendTextOffset;
|
|
1718
|
+
if (![CHART_TYPE.MAP_BUBBLE, CHART_TYPE.WORLD_MAP_BUBBLE].includes(type)) {
|
|
1719
|
+
var _this$chart$node;
|
|
1720
|
+
const gradient = this.chart.append('defs').attr('class', 'linear-gradient-wrapper').append('linearGradient').attr("id", `gradient-${(_this$chart$node = this.chart.node()) === null || _this$chart$node === void 0 ? void 0 : _this$chart$node.id}-${previewType}`).attr("x1", '0%').attr("y1", '0%').attr("x2", legendDirection === 'vertical' ? '0%' : '100%').attr("y2", legendDirection === 'vertical' ? '100%' : '0%');
|
|
1721
|
+
gradient.append('stop').attr('offset', '0%').attr('stop-color', `${colorRange[0]}`);
|
|
1722
|
+
gradient.append('stop').attr('offset', '50%').attr('stop-color', `${colorRange[4]}`);
|
|
1723
|
+
gradient.append('stop').attr('offset', '100%').attr('stop-color', `${colorRange[8]}`);
|
|
1724
|
+
}
|
|
1725
|
+
const continuousLegendWrapper = this.chart.append('g').attr('class', 'legend-continuous-wrapper').attr('transform', `translate(0, ${chartHeight - legendRectHeight - legendTextHeightSpace})`);
|
|
1726
|
+
continuousLegendWrapper.append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('fill', [CHART_TYPE.MAP_BUBBLE, CHART_TYPE.WORLD_MAP_BUBBLE].includes(type) ? bubbleColor : `url(#gradient-${(_this$chart$node2 = this.chart.node()) === null || _this$chart$node2 === void 0 ? void 0 : _this$chart$node2.id}-${previewType})`).call(g => {
|
|
1727
|
+
if ([CHART_TYPE.MAP_BUBBLE, CHART_TYPE.WORLD_MAP_BUBBLE].includes(type)) {
|
|
1728
|
+
continuousLegendWrapper.append('polygon').attr('points', `0,0 ${legendRectWidth - 0.5},0 0,${legendRectHeight - 0.5}`).attr('fill', '#fff').attr('stroke', '#fff');
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
continuousLegendWrapper.append('text').attr('class', 'range-start').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('fill', theme.labelColor).text(legendTextRange[0]).call(g => {
|
|
1732
|
+
const {
|
|
1733
|
+
height
|
|
1734
|
+
} = g.node().getBoundingClientRect();
|
|
1735
|
+
g.attr('x', legendDirection === 'vertical' ? legendRectWidth + legendTextOffset : legendTextOffset);
|
|
1736
|
+
g.attr('y', legendDirection === 'vertical' ? height : height + legendRectHeight);
|
|
1737
|
+
});
|
|
1738
|
+
continuousLegendWrapper.append('text').attr('class', 'range-end').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('fill', theme.labelColor).text(legendTextRange[1]).call(g => {
|
|
1739
|
+
const {
|
|
1740
|
+
width,
|
|
1741
|
+
height
|
|
1742
|
+
} = g.node().getBoundingClientRect();
|
|
1743
|
+
g.attr('x', legendDirection === 'vertical' ? legendRectWidth + legendTextOffset : legendRectWidth - width);
|
|
1744
|
+
g.attr('y', legendDirection === 'vertical' ? legendRectHeight - legendTextOffset : height + legendRectHeight);
|
|
1745
|
+
});
|
|
1746
|
+
};
|
|
1319
1747
|
this.initLabelStroke(props === null || props === void 0 ? void 0 : props.globalTheme);
|
|
1320
1748
|
this.chartBoundingClientRect = {};
|
|
1321
|
-
this.transitionDuration =
|
|
1749
|
+
this.transitionDuration = 450;
|
|
1750
|
+
this.interactionDuration = 150;
|
|
1322
1751
|
this.areaTransitionDuration = 200;
|
|
1752
|
+
this.yAxisTickLabelGap = 4;
|
|
1753
|
+
this.axisTitleMinHeight = 20;
|
|
1754
|
+
this.enterTransitionName = 'enter';
|
|
1755
|
+
this._defs = null;
|
|
1756
|
+
this._clipMaskByRect = new Map();
|
|
1757
|
+
this.hiddenLegendGroups = new Set();
|
|
1323
1758
|
}
|
|
1324
1759
|
componentDidMount() {
|
|
1325
1760
|
window.addEventListener('resize', this.handleResize);
|
|
@@ -1332,5 +1767,4 @@ class ChartComponent extends _react.Component {
|
|
|
1332
1767
|
componentWillUnmount() {
|
|
1333
1768
|
window.removeEventListener('resize', this.handleResize);
|
|
1334
1769
|
}
|
|
1335
|
-
}
|
|
1336
|
-
exports.default = ChartComponent;
|
|
1770
|
+
}
|