@eclipse-scout/chart 22.0.41 → 23.1.1
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/LICENSE +277 -0
- package/README.md +4 -8
- package/dist/d.ts/chart/AbstractChartRenderer.d.ts +48 -0
- package/dist/d.ts/chart/AbstractChartRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/AbstractSvgChartRenderer.d.ts +65 -0
- package/dist/d.ts/chart/AbstractSvgChartRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/Chart.d.ts +162 -0
- package/dist/d.ts/chart/Chart.d.ts.map +1 -0
- package/dist/d.ts/chart/ChartAdapter.d.ts +8 -0
- package/dist/d.ts/chart/ChartAdapter.d.ts.map +1 -0
- package/dist/d.ts/chart/ChartEventMap.d.ts +16 -0
- package/dist/d.ts/chart/ChartEventMap.d.ts.map +1 -0
- package/dist/d.ts/chart/ChartJsRenderer.d.ts +299 -0
- package/dist/d.ts/chart/ChartJsRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/ChartLayout.d.ts +8 -0
- package/dist/d.ts/chart/ChartLayout.d.ts.map +1 -0
- package/dist/d.ts/chart/ChartModel.d.ts +11 -0
- package/dist/d.ts/chart/ChartModel.d.ts.map +1 -0
- package/dist/d.ts/chart/FulfillmentChartRenderer.d.ts +22 -0
- package/dist/d.ts/chart/FulfillmentChartRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/SalesfunnelChartRenderer.d.ts +61 -0
- package/dist/d.ts/chart/SalesfunnelChartRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/SpeedoChartRenderer.d.ts +90 -0
- package/dist/d.ts/chart/SpeedoChartRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/VennAsync3Calculator.d.ts +32 -0
- package/dist/d.ts/chart/VennAsync3Calculator.d.ts.map +1 -0
- package/dist/d.ts/chart/VennChartRenderer.d.ts +36 -0
- package/dist/d.ts/chart/VennChartRenderer.d.ts.map +1 -0
- package/dist/d.ts/chart/VennCircle.d.ts +20 -0
- package/dist/d.ts/chart/VennCircle.d.ts.map +1 -0
- package/dist/d.ts/chart/VennCircleHelper.d.ts +13 -0
- package/dist/d.ts/chart/VennCircleHelper.d.ts.map +1 -0
- package/dist/d.ts/form/fields/chartfield/ChartField.d.ts +11 -0
- package/dist/d.ts/form/fields/chartfield/ChartField.d.ts.map +1 -0
- package/dist/d.ts/form/fields/chartfield/ChartFieldAdapter.d.ts +4 -0
- package/dist/d.ts/form/fields/chartfield/ChartFieldAdapter.d.ts.map +1 -0
- package/dist/d.ts/form/fields/chartfield/ChartFieldModel.d.ts +6 -0
- package/dist/d.ts/form/fields/chartfield/ChartFieldModel.d.ts.map +1 -0
- package/dist/d.ts/index.d.ts +31 -0
- package/dist/d.ts/index.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableControl.d.ts +136 -0
- package/dist/d.ts/table/controls/ChartTableControl.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableControlAdapter.d.ts +5 -0
- package/dist/d.ts/table/controls/ChartTableControlAdapter.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableControlEventMap.d.ts +9 -0
- package/dist/d.ts/table/controls/ChartTableControlEventMap.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableControlLayout.d.ts +8 -0
- package/dist/d.ts/table/controls/ChartTableControlLayout.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableControlModel.d.ts +9 -0
- package/dist/d.ts/table/controls/ChartTableControlModel.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableUserFilter.d.ts +28 -0
- package/dist/d.ts/table/controls/ChartTableUserFilter.d.ts.map +1 -0
- package/dist/d.ts/table/controls/ChartTableUserFilterModel.d.ts +11 -0
- package/dist/d.ts/table/controls/ChartTableUserFilterModel.d.ts.map +1 -0
- package/dist/d.ts/tile/ChartFieldTile.d.ts +14 -0
- package/dist/d.ts/tile/ChartFieldTile.d.ts.map +1 -0
- package/dist/d.ts/tile/ChartFieldTileAdapter.d.ts +4 -0
- package/dist/d.ts/tile/ChartFieldTileAdapter.d.ts.map +1 -0
- package/dist/d.ts/tile/ChartFieldTileModel.d.ts +6 -0
- package/dist/d.ts/tile/ChartFieldTileModel.d.ts.map +1 -0
- package/dist/eclipse-scout-chart-fae6f958a044232e659c.min.js +3 -0
- package/dist/eclipse-scout-chart-fae6f958a044232e659c.min.js.map +1 -0
- package/dist/eclipse-scout-chart-theme-56ba6667e592ef147869.min.css +1 -0
- package/dist/eclipse-scout-chart-theme-dark-593955eea95984c5aa62.min.css +1 -0
- package/dist/eclipse-scout-chart-theme-dark.css +53 -59
- package/dist/eclipse-scout-chart-theme-dark.css.map +1 -1
- package/dist/eclipse-scout-chart-theme.css +41 -45
- package/dist/eclipse-scout-chart-theme.css.map +1 -1
- package/dist/eclipse-scout-chart.esm-2119cfea86a9d6f34a35.min.js +3 -0
- package/dist/eclipse-scout-chart.esm-2119cfea86a9d6f34a35.min.js.map +1 -0
- package/dist/eclipse-scout-chart.esm.js +6898 -0
- package/dist/eclipse-scout-chart.esm.js.map +1 -0
- package/dist/eclipse-scout-chart.js +737 -15226
- package/dist/eclipse-scout-chart.js.map +1 -1
- package/dist/file-list +8 -5
- package/dist/texts.json +17 -17
- package/package.json +22 -16
- package/src/chart/{AbstractChartRenderer.js → AbstractChartRenderer.ts} +36 -31
- package/src/chart/{AbstractSvgChartRenderer.js → AbstractSvgChartRenderer.ts} +82 -48
- package/src/chart/Chart.less +8 -8
- package/src/chart/{Chart.js → Chart.ts} +157 -68
- package/src/chart/ChartAdapter.ts +26 -0
- package/src/chart/ChartEventMap.ts +26 -0
- package/src/chart/{ChartJsRenderer.js → ChartJsRenderer.ts} +362 -357
- package/src/chart/{ChartLayout.js → ChartLayout.ts} +13 -13
- package/src/chart/ChartModel.ts +20 -0
- package/src/chart/{FulfillmentChartRenderer.js → FulfillmentChartRenderer.ts} +25 -23
- package/src/chart/{SalesfunnelChartRenderer.js → SalesfunnelChartRenderer.ts} +102 -66
- package/src/chart/{SpeedoChartRenderer.js → SpeedoChartRenderer.ts} +56 -43
- package/src/chart/{VennAsync3Calculator.js → VennAsync3Calculator.ts} +41 -18
- package/src/chart/{VennChartRenderer.js → VennChartRenderer.ts} +63 -40
- package/src/chart/VennCircle.ts +47 -0
- package/src/chart/{VennCircleHelper.js → VennCircleHelper.ts} +19 -14
- package/src/eclipse-scout-chart-theme-dark.less +7 -8
- package/src/eclipse-scout-chart-theme.less +7 -8
- package/src/form/fields/chartfield/ChartField.ts +44 -0
- package/src/form/fields/chartfield/ChartFieldAdapter.ts +13 -0
- package/src/form/fields/chartfield/ChartFieldModel.ts +15 -0
- package/src/index-dark.less +6 -7
- package/src/index.less +6 -7
- package/src/index.ts +45 -0
- package/src/style/colors-dark.less +7 -8
- package/src/style/colors.less +6 -7
- package/src/table/controls/ChartTableControl.less +6 -7
- package/src/table/controls/{ChartTableControl.js → ChartTableControl.ts} +164 -125
- package/src/table/controls/ChartTableControlAdapter.ts +18 -0
- package/src/table/controls/ChartTableControlEventMap.ts +18 -0
- package/src/table/controls/ChartTableControlLayout.ts +30 -0
- package/src/table/controls/ChartTableControlModel.ts +18 -0
- package/src/table/controls/ChartTableUserFilter.ts +84 -0
- package/src/table/controls/ChartTableUserFilterModel.ts +18 -0
- package/src/tile/ChartFieldTile.less +6 -7
- package/src/tile/ChartFieldTile.ts +51 -0
- package/src/tile/ChartFieldTileAdapter.ts +13 -0
- package/src/tile/ChartFieldTileModel.ts +15 -0
- package/dist/eclipse-scout-chart-8eb9461c14872058f638.min.js +0 -3
- package/dist/eclipse-scout-chart-8eb9461c14872058f638.min.js.LICENSE.txt +0 -6
- package/dist/eclipse-scout-chart-8eb9461c14872058f638.min.js.map +0 -1
- package/dist/eclipse-scout-chart-theme-79622289bda68b525e3e.min.css +0 -1
- package/dist/eclipse-scout-chart-theme-dark-1de09c03e3dc40a9529a.min.css +0 -1
- package/src/chart/ChartAdapter.js +0 -30
- package/src/chart/VennCircle.js +0 -41
- package/src/form/fields/chartfield/ChartField.js +0 -39
- package/src/form/fields/chartfield/ChartFieldAdapter.js +0 -19
- package/src/index.js +0 -36
- package/src/table/controls/ChartTableControlAdapter.js +0 -20
- package/src/table/controls/ChartTableControlLayout.js +0 -29
- package/src/table/controls/ChartTableUserFilter.js +0 -72
- package/src/tile/ChartFieldTile.js +0 -46
- package/src/tile/ChartFieldTileAdapter.js +0 -18
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2010
|
|
3
|
-
* All rights reserved. This program and the accompanying materials
|
|
4
|
-
* are made available under the terms of the Eclipse Public License v1.0
|
|
5
|
-
* which accompanies this distribution, and is available at
|
|
6
|
-
* http://www.eclipse.org/legal/epl-v10.html
|
|
2
|
+
* Copyright (c) 2010, 2023 BSI Business Systems Integration AG
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
10
9
|
*/
|
|
11
10
|
import {AbstractLayout} from '@eclipse-scout/core';
|
|
12
|
-
import {Chart} from '../index';
|
|
11
|
+
import {UpdateChartOptions, Chart} from '../index';
|
|
13
12
|
|
|
14
|
-
export
|
|
13
|
+
export class ChartLayout extends AbstractLayout {
|
|
14
|
+
chart: Chart;
|
|
15
15
|
|
|
16
|
-
constructor(chart) {
|
|
16
|
+
constructor(chart: Chart) {
|
|
17
17
|
super();
|
|
18
18
|
this.chart = chart;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
layout($container) {
|
|
22
|
-
let opts = {
|
|
21
|
+
override layout($container: JQuery) {
|
|
22
|
+
let opts: UpdateChartOptions = {
|
|
23
23
|
requestAnimation: true,
|
|
24
24
|
debounce: Chart.DEFAULT_DEBOUNCE_TIMEOUT,
|
|
25
25
|
onlyUpdateData: true
|
|
26
26
|
};
|
|
27
27
|
// Don't request animations when the session is not ready or the chart was already updated once
|
|
28
|
-
if (!this.chart.session.ready || this.chart.
|
|
28
|
+
if (!this.chart.session.ready || this.chart._updatedOnce) {
|
|
29
29
|
opts.requestAnimation = false;
|
|
30
30
|
}
|
|
31
31
|
// Don't debounce while session is not yet ready. Otherwise, it might happen that the area to layout is not
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2010, 2023 BSI Business Systems Integration AG
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
+
*/
|
|
10
|
+
import {WidgetModel} from '@eclipse-scout/core';
|
|
11
|
+
import {ChartConfig, ChartData, ClickObject} from './Chart';
|
|
12
|
+
|
|
13
|
+
export interface ChartModel extends WidgetModel {
|
|
14
|
+
data?: ChartData;
|
|
15
|
+
config?: ChartConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Default is [].
|
|
18
|
+
*/
|
|
19
|
+
checkedItems?: ClickObject[];
|
|
20
|
+
}
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2010
|
|
3
|
-
* All rights reserved. This program and the accompanying materials
|
|
4
|
-
* are made available under the terms of the Eclipse Public License v1.0
|
|
5
|
-
* which accompanies this distribution, and is available at
|
|
6
|
-
* http://www.eclipse.org/legal/epl-v10.html
|
|
2
|
+
* Copyright (c) 2010, 2023 BSI Business Systems Integration AG
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
10
9
|
*/
|
|
11
10
|
import {objects, scout} from '@eclipse-scout/core';
|
|
12
|
-
import {AbstractSvgChartRenderer} from '../index';
|
|
11
|
+
import {AbstractSvgChartRenderer, Chart} from '../index';
|
|
13
12
|
import $ from 'jquery';
|
|
13
|
+
import {UpdateChartOptions} from './Chart';
|
|
14
14
|
|
|
15
|
-
export
|
|
15
|
+
export class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
16
|
+
animationTriggered: boolean;
|
|
17
|
+
segmentSelectorForAnimation: string;
|
|
18
|
+
r: number;
|
|
19
|
+
fullR: number;
|
|
16
20
|
|
|
17
|
-
constructor(chart) {
|
|
21
|
+
constructor(chart: Chart) {
|
|
18
22
|
super(chart);
|
|
19
23
|
|
|
20
24
|
this.animationTriggered = false;
|
|
21
|
-
this.r;
|
|
22
|
-
|
|
23
25
|
this.segmentSelectorForAnimation = '.fulfillment-chart';
|
|
24
26
|
this.suppressLegendBox = true;
|
|
25
27
|
|
|
@@ -33,7 +35,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
33
35
|
chart.config = $.extend(true, {}, defaultConfig, chart.config);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
_validate() {
|
|
38
|
+
protected override _validate(): boolean {
|
|
37
39
|
let chartValueGroups = this.chart.data.chartValueGroups;
|
|
38
40
|
if (chartValueGroups.length !== 2 ||
|
|
39
41
|
chartValueGroups[0].values.length !== 1 ||
|
|
@@ -43,11 +45,11 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
43
45
|
return true;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
_renderInternal() {
|
|
48
|
+
protected override _renderInternal() {
|
|
47
49
|
// Calculate percentage
|
|
48
50
|
let chartData = this.chart.data;
|
|
49
|
-
let value = chartData.chartValueGroups[0].values[0];
|
|
50
|
-
let total = chartData.chartValueGroups[1].values[0];
|
|
51
|
+
let value = chartData.chartValueGroups[0].values[0] as number;
|
|
52
|
+
let total = chartData.chartValueGroups[1].values[0] as number;
|
|
51
53
|
|
|
52
54
|
this.fullR = (Math.min(this.chartBox.height, this.chartBox.width) / 2) - 2;
|
|
53
55
|
|
|
@@ -55,7 +57,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
55
57
|
this._renderPercentage(value, total);
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
_renderPercentage(value, total) {
|
|
60
|
+
protected _renderPercentage(value: number, total: number) {
|
|
59
61
|
// arc segment
|
|
60
62
|
let arcClass = 'fulfillment-chart',
|
|
61
63
|
color = this.chart.data.chartValueGroups[0].colorHexValue,
|
|
@@ -104,7 +106,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
104
106
|
.text(percentage + '%');
|
|
105
107
|
|
|
106
108
|
if (this.chart.config.options.clickable) {
|
|
107
|
-
$arc.on('click', this._createClickObject(null, null), this.chart.
|
|
109
|
+
$arc.on('click', this._createClickObject(null, null), e => this.chart.handleValueClick(e.data));
|
|
108
110
|
}
|
|
109
111
|
if (!this.chart.config.options.autoColor && !chartGroupCss) {
|
|
110
112
|
$arc.attr('fill', color);
|
|
@@ -124,7 +126,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
pathSegment(start, end) {
|
|
129
|
+
pathSegment(start: number, end: number): string {
|
|
128
130
|
let s = start * 2 * Math.PI,
|
|
129
131
|
e = end * 2 * Math.PI,
|
|
130
132
|
pathString = '';
|
|
@@ -138,7 +140,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
138
140
|
return pathString;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
_renderCirclePath(cssClass, id, radius) {
|
|
143
|
+
protected _renderCirclePath(cssClass: string, id: string, radius: number): JQuery<SVGElement> {
|
|
142
144
|
let chartGroupCss = this.chart.data.chartValueGroups[0].cssClass;
|
|
143
145
|
let color = this.chart.data.chartValueGroups[1].colorHexValue;
|
|
144
146
|
|
|
@@ -165,7 +167,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
165
167
|
return $path;
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
_renderInnerCircle() {
|
|
170
|
+
protected _renderInnerCircle() {
|
|
169
171
|
let radius = (this.fullR / 8) * 7.5,
|
|
170
172
|
radius2 = (this.fullR / 8) * 7.2;
|
|
171
173
|
|
|
@@ -178,7 +180,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
178
180
|
* Do not animate the removal of the chart if the chart data has been updated and the startValue option is set.
|
|
179
181
|
* If startValue is not set use default implementation.
|
|
180
182
|
*/
|
|
181
|
-
shouldAnimateRemoveOnUpdate(opts) {
|
|
183
|
+
override shouldAnimateRemoveOnUpdate(opts: UpdateChartOptions): boolean {
|
|
182
184
|
let startValue = objects.optProperty(this.chart, 'config', 'options', 'fulfillment', 'startValue');
|
|
183
185
|
if (!objects.isNullOrUndefined(startValue)) {
|
|
184
186
|
return false;
|
|
@@ -187,7 +189,7 @@ export default class FulfillmentChartRenderer extends AbstractSvgChartRenderer {
|
|
|
187
189
|
return super.shouldAnimateRemoveOnUpdate(opts);
|
|
188
190
|
}
|
|
189
191
|
|
|
190
|
-
_removeAnimated(afterRemoveFunc) {
|
|
192
|
+
protected override _removeAnimated(afterRemoveFunc: (chartAnimationStopping?: boolean) => void) {
|
|
191
193
|
if (this.animationTriggered) {
|
|
192
194
|
return;
|
|
193
195
|
}
|
|
@@ -1,32 +1,53 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2010
|
|
3
|
-
* All rights reserved. This program and the accompanying materials
|
|
4
|
-
* are made available under the terms of the Eclipse Public License v1.0
|
|
5
|
-
* which accompanies this distribution, and is available at
|
|
6
|
-
* https://www.eclipse.org/legal/epl-v10.html
|
|
2
|
+
* Copyright (c) 2010, 2023 BSI Business Systems Integration AG
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
10
9
|
*/
|
|
11
10
|
import {objects, strings} from '@eclipse-scout/core';
|
|
12
|
-
import {AbstractSvgChartRenderer} from '../index';
|
|
11
|
+
import {AbstractSvgChartRenderer, Chart} from '../index';
|
|
13
12
|
import $ from 'jquery';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
import {ChartValueGroup, ClickObject} from './Chart';
|
|
14
|
+
import {LegendPositions} from './AbstractSvgChartRenderer';
|
|
15
|
+
|
|
16
|
+
export class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
17
|
+
segmentSelectorForAnimation: string;
|
|
18
|
+
widthThresholdMedium: number;
|
|
19
|
+
widthThresholdSmall: number;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Constants for "normalized mode"
|
|
23
|
+
* Width of a bar is calculated by multiplying this value with the previous bar's width
|
|
24
|
+
*/
|
|
25
|
+
barDeltaPercentage: number;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Factor to be multiplied with the last bar's width. This will create a funnel effect, because
|
|
29
|
+
* the last bar is considerably smaller than the other bars.
|
|
30
|
+
*/
|
|
31
|
+
lastBarAdditionalPercentage: number;
|
|
32
|
+
|
|
33
|
+
/** Percentage of the total width the last bar always has (delta might get smaller due to this constraint). */
|
|
34
|
+
lastBarMinWidthPercentage: number;
|
|
35
|
+
|
|
36
|
+
paddingBetweenLabel: number;
|
|
37
|
+
dataAnalyzeResult: AnalyzedData;
|
|
38
|
+
barHeight: number;
|
|
39
|
+
barAreaWidth: number;
|
|
40
|
+
centerX: number;
|
|
41
|
+
animationTriggered: boolean;
|
|
42
|
+
|
|
43
|
+
constructor(chart: Chart) {
|
|
18
44
|
super(chart);
|
|
19
45
|
|
|
20
46
|
this.segmentSelectorForAnimation = '.salesfunnel-chart-bar';
|
|
21
47
|
this.widthThresholdMedium = 400;
|
|
22
48
|
this.widthThresholdSmall = 200;
|
|
23
|
-
// Constants for "normalized mode"
|
|
24
|
-
// Width of a bar is calculated by multiplying this value with the previous bar's width
|
|
25
49
|
this.barDeltaPercentage = 0.95;
|
|
26
|
-
// Factor to be multiplied with the last bar's width. This will create a funnel effect, because
|
|
27
|
-
// the last bar is considerably smaller than the other bars.
|
|
28
50
|
this.lastBarAdditionalPercentage = 0.7;
|
|
29
|
-
// Percentage of the total width the last bar always has (delta might get smaller due to this constraint).
|
|
30
51
|
this.lastBarMinWidthPercentage = 0.4;
|
|
31
52
|
this.suppressLegendBox = true;
|
|
32
53
|
|
|
@@ -41,7 +62,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
41
62
|
chart.config = $.extend(true, {}, defaultConfig, chart.config);
|
|
42
63
|
}
|
|
43
64
|
|
|
44
|
-
_validate() {
|
|
65
|
+
protected override _validate(): boolean {
|
|
45
66
|
let chartData = this.chart.data;
|
|
46
67
|
let chartConfig = this.chart.config;
|
|
47
68
|
if (!chartData ||
|
|
@@ -56,20 +77,19 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
56
77
|
return true;
|
|
57
78
|
}
|
|
58
79
|
|
|
59
|
-
_renderInternal() {
|
|
80
|
+
protected override _renderInternal() {
|
|
60
81
|
let chartData = this.chart.data,
|
|
61
82
|
bars = chartData.chartValueGroups.length;
|
|
62
83
|
|
|
63
|
-
|
|
64
|
-
this.dataAnalyzeResult = this._analyzeData(chartData.chartValueGroups);
|
|
84
|
+
let conversionRateWidth = this._dynamicConversionRateWidth();
|
|
65
85
|
this.paddingBetweenLabel = 20;
|
|
86
|
+
this.dataAnalyzeResult = this._analyzeData(chartData.chartValueGroups);
|
|
66
87
|
this.barHeight = this.chartBox.height / bars;
|
|
67
|
-
this.barAreaHeight = this.barHeight * bars;
|
|
68
88
|
this.barAreaWidth = this.chartBox.width -
|
|
69
89
|
this.dataAnalyzeResult.maxLengthFirstValueRow -
|
|
70
90
|
(this.paddingBetweenLabel * this.dataAnalyzeResult.labelCount) -
|
|
71
91
|
this.dataAnalyzeResult.maxLengthSecondValueRow -
|
|
72
|
-
|
|
92
|
+
conversionRateWidth;
|
|
73
93
|
this.centerX = this.barAreaWidth / 2;
|
|
74
94
|
|
|
75
95
|
if (this.chart.config.options.salesfunnel.normalized) {
|
|
@@ -81,7 +101,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
81
101
|
this._addClipping('salesfunnel-chart-bar');
|
|
82
102
|
}
|
|
83
103
|
|
|
84
|
-
_renderBarsNormalized(chartValueGroups) {
|
|
104
|
+
protected _renderBarsNormalized(chartValueGroups: ChartValueGroup[]) {
|
|
85
105
|
let barCount = chartValueGroups.length;
|
|
86
106
|
let startPointX = this.barAreaWidth +
|
|
87
107
|
this.dataAnalyzeResult.maxLengthFirstValueRow +
|
|
@@ -124,23 +144,23 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
124
144
|
}
|
|
125
145
|
|
|
126
146
|
this._renderPolygon(renderPolyOptions);
|
|
127
|
-
this._renderLabel(chartValueGroups[i].values[0], false, i);
|
|
147
|
+
this._renderLabel(chartValueGroups[i].values[0] as number, false, i);
|
|
128
148
|
this._renderBarLabel(barLabel, i, renderPolyOptions.widthBottom);
|
|
129
149
|
let labelLineWidth = this.dataAnalyzeResult.maxLengthFirstValueRow + this.paddingBetweenLabel;
|
|
130
150
|
if (chartValueGroups[i].values.length > 1) {
|
|
131
|
-
this._renderLabel(chartValueGroups[i].values[1], true, i);
|
|
151
|
+
this._renderLabel(chartValueGroups[i].values[1] as number, true, i);
|
|
132
152
|
labelLineWidth += this.dataAnalyzeResult.maxLengthSecondValueRow + this.paddingBetweenLabel;
|
|
133
153
|
}
|
|
134
154
|
if (i > 0) {
|
|
135
155
|
this._renderLabelSeparatorLine(yCoord, labelLineWidth);
|
|
136
156
|
if (this.chart.config.options.salesfunnel.calcConversionRate) {
|
|
137
|
-
this._renderConversionRate(i, startPointX, this._calcConversionRate(chartValueGroups[i - 1].values[0], chartValueGroups[i].values[0]));
|
|
157
|
+
this._renderConversionRate(i, startPointX, this._calcConversionRate(chartValueGroups[i - 1].values[0] as number, chartValueGroups[i].values[0] as number));
|
|
138
158
|
}
|
|
139
159
|
}
|
|
140
160
|
}
|
|
141
161
|
}
|
|
142
162
|
|
|
143
|
-
_renderLabel(label, secondLabel, barIndexFromTop) {
|
|
163
|
+
protected _renderLabel(label: number, secondLabel: boolean, barIndexFromTop: number) {
|
|
144
164
|
if (label === null) {
|
|
145
165
|
return;
|
|
146
166
|
}
|
|
@@ -161,12 +181,12 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
161
181
|
}
|
|
162
182
|
if (this.chart.config.options.plugins.tooltip.enabled && this.chart.data.axes.length > 0) {
|
|
163
183
|
let desc = this.chart.data.axes[barIndexFromTop][secondLabel ? 1 : 0].label,
|
|
164
|
-
textBounds = this._measureText(label, labelClass);
|
|
184
|
+
textBounds = this._measureText('' + label, labelClass);
|
|
165
185
|
this._renderWireLabels(desc, $label, x - textBounds.width / 2, y - textBounds.height);
|
|
166
186
|
}
|
|
167
187
|
}
|
|
168
188
|
|
|
169
|
-
_renderWireLabels(label, $text
|
|
189
|
+
protected _renderWireLabels(label: string, $text: JQuery<SVGElement>, x1: number, y1: number) {
|
|
170
190
|
let legendPositions = {
|
|
171
191
|
x1: x1,
|
|
172
192
|
x2: x1 - 10,
|
|
@@ -174,7 +194,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
174
194
|
y2: y1 - 10,
|
|
175
195
|
v: -1,
|
|
176
196
|
h: -1
|
|
177
|
-
};
|
|
197
|
+
} as LegendPositions;
|
|
178
198
|
// calculate opening direction
|
|
179
199
|
let labelPositionFunc = (labelWidth, labelHeight) => {
|
|
180
200
|
if (legendPositions.y2 - labelHeight < 0) {
|
|
@@ -188,15 +208,15 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
188
208
|
legendPositions.autoPosition = true;
|
|
189
209
|
legendPositions.posFunc = labelPositionFunc;
|
|
190
210
|
let
|
|
191
|
-
legend = this._renderWireLegend(label, legendPositions, 'line-chart-wire-label',
|
|
211
|
+
legend = this._renderWireLegend(label, legendPositions, 'line-chart-wire-label', true),
|
|
192
212
|
mouseIn = legend.attachFunc.bind(legend),
|
|
193
213
|
mouseOut = legend.detachFunc.bind(legend);
|
|
194
214
|
legend.detachFunc();
|
|
195
|
-
$text.mouseenter
|
|
196
|
-
.mouseleave
|
|
215
|
+
$text.on('mouseenter', mouseIn)
|
|
216
|
+
.on('mouseleave', mouseOut);
|
|
197
217
|
}
|
|
198
218
|
|
|
199
|
-
_renderBarLabel(label, barIndexFromTop, barWidth) {
|
|
219
|
+
protected _renderBarLabel(label: string, barIndexFromTop: number, barWidth: number) {
|
|
200
220
|
let y = (barIndexFromTop * this.barHeight) + (this.barHeight / 2),
|
|
201
221
|
x = this.centerX,
|
|
202
222
|
labelClass = this._dynamicCssClass('salesfunnel-bar-label');
|
|
@@ -204,7 +224,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
204
224
|
this._renderLineLabel(x, y, label, labelClass, true);
|
|
205
225
|
}
|
|
206
226
|
|
|
207
|
-
_renderConversionRate(barIndexFromTop, startPointX, conversionRate) {
|
|
227
|
+
protected _renderConversionRate(barIndexFromTop: number, startPointX: number, conversionRate: number) {
|
|
208
228
|
if (conversionRate === undefined) {
|
|
209
229
|
return;
|
|
210
230
|
}
|
|
@@ -222,13 +242,12 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
222
242
|
}
|
|
223
243
|
}
|
|
224
244
|
|
|
225
|
-
_renderPolygon(renderPolyOptions) {
|
|
245
|
+
protected _renderPolygon(renderPolyOptions: PolyOptions): JQuery<SVGElement> {
|
|
226
246
|
let that = this,
|
|
227
247
|
points = this._calcPolygonPoints(true, this.animationDuration ? 0 : 1, renderPolyOptions.xStart, renderPolyOptions.yStart, renderPolyOptions.width, renderPolyOptions.widthBottom, this.barHeight - 1);
|
|
228
248
|
|
|
229
249
|
let $poly = this.$svg.appendSVG('polygon', renderPolyOptions.cssClass, '', renderPolyOptions.id)
|
|
230
250
|
.attr('points', points)
|
|
231
|
-
.attr('opacity', renderPolyOptions.opacity)
|
|
232
251
|
.data('xStart', renderPolyOptions.xStart)
|
|
233
252
|
.data('yStart', renderPolyOptions.yStart)
|
|
234
253
|
.data('widthBar', renderPolyOptions.width)
|
|
@@ -255,7 +274,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
255
274
|
}, this._createAnimationObjectWithTabIndexRemoval(expandFunc, this.animationDuration));
|
|
256
275
|
}
|
|
257
276
|
if (this.chart.config.options.clickable) {
|
|
258
|
-
$poly.on('click', renderPolyOptions.clickObject, this.chart.
|
|
277
|
+
$poly.on('click', renderPolyOptions.clickObject, e => this.chart.handleValueClick(e.data));
|
|
259
278
|
}
|
|
260
279
|
if (renderPolyOptions.fill) {
|
|
261
280
|
$poly.attr('fill', renderPolyOptions.fill);
|
|
@@ -264,7 +283,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
264
283
|
return $poly;
|
|
265
284
|
}
|
|
266
285
|
|
|
267
|
-
_calcPolygonPoints(expand, fxPos, xStart, yStart, width, widthBottom, height) {
|
|
286
|
+
protected _calcPolygonPoints(expand: boolean, fxPos: number, xStart: number, yStart: number, width: number, widthBottom: number, height: number): string {
|
|
268
287
|
let xOffsetTop = 0,
|
|
269
288
|
xOffsetBottom = 0;
|
|
270
289
|
if (expand) {
|
|
@@ -274,28 +293,25 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
274
293
|
xOffsetTop = (width / 2) - (width / 2 * fxPos);
|
|
275
294
|
xOffsetBottom = (widthBottom / 2) - (widthBottom / 2 * fxPos);
|
|
276
295
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
x4 = xStart - xOffsetBottom,
|
|
284
|
-
y4 = y3;
|
|
285
|
-
return x1 + ',' + y1 + ' ' + x2 + ',' + y2 + ' ' + x3 + ',' + y3 + ' ' + x4 + ',' + y4 + ' ';
|
|
296
|
+
return strings.join(' ',
|
|
297
|
+
(xStart - xOffsetTop) + ',' + yStart, // x1, y1
|
|
298
|
+
(xStart + xOffsetTop) + ',' + yStart, // x2, y2
|
|
299
|
+
(xStart + xOffsetBottom) + ',' + (yStart + height), // x3, y3
|
|
300
|
+
(xStart - xOffsetBottom) + ',' + (yStart + height) // x4, y4
|
|
301
|
+
);
|
|
286
302
|
}
|
|
287
303
|
|
|
288
|
-
_renderBarsAccordingToValues(chartValueGroups) {
|
|
304
|
+
protected _renderBarsAccordingToValues(chartValueGroups: ChartValueGroup[]) {
|
|
289
305
|
let widthPerN = (this.dataAnalyzeResult.maxValue ? this.barAreaWidth * 0.8 / this.dataAnalyzeResult.maxValue : 0),
|
|
290
306
|
startPointX = this.barAreaWidth + this.dataAnalyzeResult.maxLengthFirstValueRow + this.dataAnalyzeResult.maxLengthSecondValueRow + this.paddingBetweenLabel * this.dataAnalyzeResult.labelCount + 2 * this.paddingBetweenLabel,
|
|
291
307
|
barCount = chartValueGroups.length;
|
|
292
308
|
|
|
293
309
|
for (let i = 0; i < barCount; i++) {
|
|
294
|
-
let width = chartValueGroups[i].values[0] * widthPerN + this.barAreaWidth * 0.2,
|
|
310
|
+
let width = (chartValueGroups[i].values[0] as number) * widthPerN + this.barAreaWidth * 0.2,
|
|
295
311
|
barLabel = chartValueGroups[i].groupName,
|
|
296
312
|
yCoord = i * this.barHeight;
|
|
297
313
|
|
|
298
|
-
let renderPolyOptions = {
|
|
314
|
+
let renderPolyOptions: PolyOptions = {
|
|
299
315
|
xStart: this.centerX,
|
|
300
316
|
yStart: yCoord,
|
|
301
317
|
rect: true,
|
|
@@ -314,23 +330,23 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
314
330
|
}
|
|
315
331
|
|
|
316
332
|
this._renderPolygon(renderPolyOptions);
|
|
317
|
-
this._renderLabel(chartValueGroups[i].values[0], false, i);
|
|
333
|
+
this._renderLabel(chartValueGroups[i].values[0] as number, false, i);
|
|
318
334
|
this._renderBarLabel(barLabel, i, renderPolyOptions.widthBottom);
|
|
319
335
|
let labelLineWidth = this.dataAnalyzeResult.maxLengthFirstValueRow + this.paddingBetweenLabel;
|
|
320
336
|
if (chartValueGroups[i].values.length > 1) {
|
|
321
|
-
this._renderLabel(chartValueGroups[i].values[1], true, i);
|
|
337
|
+
this._renderLabel(chartValueGroups[i].values[1] as number, true, i);
|
|
322
338
|
labelLineWidth += this.dataAnalyzeResult.maxLengthSecondValueRow + this.paddingBetweenLabel;
|
|
323
339
|
}
|
|
324
340
|
if (i > 0) {
|
|
325
341
|
this._renderLabelSeparatorLine(yCoord, labelLineWidth);
|
|
326
342
|
if (this.chart.config.options.salesfunnel.calcConversionRate) {
|
|
327
|
-
this._renderConversionRate(i, startPointX, this._calcConversionRate(chartValueGroups[i - 1].values[0], chartValueGroups[i].values[0]));
|
|
343
|
+
this._renderConversionRate(i, startPointX, this._calcConversionRate(chartValueGroups[i - 1].values[0] as number, chartValueGroups[i].values[0] as number));
|
|
328
344
|
}
|
|
329
345
|
}
|
|
330
346
|
}
|
|
331
347
|
}
|
|
332
348
|
|
|
333
|
-
_renderLabelSeparatorLine(yCoord, labelLineWidth) {
|
|
349
|
+
protected _renderLabelSeparatorLine(yCoord: number, labelLineWidth: number) {
|
|
334
350
|
let $line = this.$svg.appendSVG('line', 'label-separator')
|
|
335
351
|
.attr('x1', this.barAreaWidth + this.paddingBetweenLabel)
|
|
336
352
|
.attr('y1', yCoord)
|
|
@@ -343,15 +359,15 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
343
359
|
}
|
|
344
360
|
}
|
|
345
361
|
|
|
346
|
-
_calcConversionRate(valueBefore, value) {
|
|
362
|
+
protected _calcConversionRate(valueBefore: number, value: number): number {
|
|
347
363
|
if (objects.isNullOrUndefined(valueBefore) || objects.isNullOrUndefined(value) || valueBefore === 0) {
|
|
348
364
|
return undefined;
|
|
349
365
|
}
|
|
350
366
|
return Math.round(value / valueBefore * 100);
|
|
351
367
|
}
|
|
352
368
|
|
|
353
|
-
_analyzeData(valueGroups) {
|
|
354
|
-
let result = {
|
|
369
|
+
protected _analyzeData(valueGroups: ChartValueGroup[]): AnalyzedData {
|
|
370
|
+
let result: AnalyzedData = {
|
|
355
371
|
labelCount: 0,
|
|
356
372
|
maxValue: null,
|
|
357
373
|
maxLengthFirstValueRow: 0,
|
|
@@ -366,20 +382,20 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
366
382
|
// only first value is relevant for bar
|
|
367
383
|
if (valueGroup.values.length > 0 && valueGroup.values[0]) {
|
|
368
384
|
if (result.maxValue === null) {
|
|
369
|
-
result.maxValue = valueGroup.values[0];
|
|
385
|
+
result.maxValue = valueGroup.values[0] as number;
|
|
370
386
|
} else {
|
|
371
|
-
result.maxValue = Math.max(result.maxValue, valueGroup.values[0]);
|
|
387
|
+
result.maxValue = Math.max(result.maxValue, valueGroup.values[0] as number);
|
|
372
388
|
}
|
|
373
|
-
result.maxLengthFirstValueRow = Math.max(result.maxLengthFirstValueRow, this._measureText(this.session.locale.decimalFormat.format(valueGroup.values[0]), labelClass).width);
|
|
389
|
+
result.maxLengthFirstValueRow = Math.max(result.maxLengthFirstValueRow, this._measureText(this.session.locale.decimalFormat.format(valueGroup.values[0] as number), labelClass).width);
|
|
374
390
|
}
|
|
375
391
|
if (valueGroup.values.length > 1 && valueGroup.values[1]) {
|
|
376
|
-
result.maxLengthSecondValueRow = Math.max(result.maxLengthSecondValueRow, this._measureText(this.session.locale.decimalFormat.format(valueGroup.values[1]), labelClass).width);
|
|
392
|
+
result.maxLengthSecondValueRow = Math.max(result.maxLengthSecondValueRow, this._measureText(this.session.locale.decimalFormat.format(valueGroup.values[1] as number), labelClass).width);
|
|
377
393
|
}
|
|
378
394
|
}
|
|
379
395
|
return result;
|
|
380
396
|
}
|
|
381
397
|
|
|
382
|
-
_removeAnimated(afterRemoveFunc) {
|
|
398
|
+
protected override _removeAnimated(afterRemoveFunc: (chartAnimationStopping?: boolean) => void) {
|
|
383
399
|
if (this.animationTriggered) {
|
|
384
400
|
return;
|
|
385
401
|
}
|
|
@@ -404,7 +420,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
404
420
|
});
|
|
405
421
|
}
|
|
406
422
|
|
|
407
|
-
_dynamicCssClass(cssClass) {
|
|
423
|
+
protected _dynamicCssClass(cssClass: string): string {
|
|
408
424
|
let small = '';
|
|
409
425
|
if (this.chartBox.width <= this.widthThresholdSmall) {
|
|
410
426
|
small = 'small';
|
|
@@ -414,7 +430,7 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
414
430
|
return strings.join(' ', cssClass, small);
|
|
415
431
|
}
|
|
416
432
|
|
|
417
|
-
_dynamicConversionRateWidth() {
|
|
433
|
+
protected _dynamicConversionRateWidth(): number {
|
|
418
434
|
if (!this.chart.config.options.salesfunnel.calcConversionRate) {
|
|
419
435
|
return 0; // don't show conversion rate
|
|
420
436
|
}
|
|
@@ -427,3 +443,23 @@ export default class SalesfunnelChartRenderer extends AbstractSvgChartRenderer {
|
|
|
427
443
|
return 100;
|
|
428
444
|
}
|
|
429
445
|
}
|
|
446
|
+
|
|
447
|
+
export type AnalyzedData = {
|
|
448
|
+
labelCount: number;
|
|
449
|
+
maxValue: number;
|
|
450
|
+
maxLengthFirstValueRow: number;
|
|
451
|
+
maxLengthSecondValueRow: number;
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
export type PolyOptions = {
|
|
455
|
+
id?: string;
|
|
456
|
+
xStart: number;
|
|
457
|
+
yStart: number;
|
|
458
|
+
rect: boolean;
|
|
459
|
+
width: number;
|
|
460
|
+
widthBottom: number;
|
|
461
|
+
cssClass: string;
|
|
462
|
+
fill: string;
|
|
463
|
+
label: string;
|
|
464
|
+
clickObject: ClickObject;
|
|
465
|
+
};
|