@unovis/ts 1.6.0-pre.1 → 1.6.0
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/components/area/index.js +2 -1
- package/components/area/index.js.map +1 -1
- package/components/axis/config.d.ts +4 -0
- package/components/axis/config.js +2 -2
- package/components/axis/config.js.map +1 -1
- package/components/axis/index.d.ts +0 -1
- package/components/axis/index.js +51 -19
- package/components/axis/index.js.map +1 -1
- package/components/axis/style.d.ts +40 -1
- package/components/axis/style.js +34 -35
- package/components/axis/style.js.map +1 -1
- package/components/brush/config.d.ts +1 -1
- package/components/brush/config.js.map +1 -1
- package/components/bullet-legend/config.d.ts +2 -0
- package/components/bullet-legend/config.js +1 -0
- package/components/bullet-legend/config.js.map +1 -1
- package/components/bullet-legend/index.js +10 -2
- package/components/bullet-legend/index.js.map +1 -1
- package/components/bullet-legend/modules/shape.d.ts +1 -0
- package/components/bullet-legend/modules/shape.js +61 -41
- package/components/bullet-legend/modules/shape.js.map +1 -1
- package/components/bullet-legend/types.d.ts +1 -1
- package/components/bullet-legend/types.js.map +1 -1
- package/components/crosshair/config.d.ts +20 -7
- package/components/crosshair/config.js +1 -1
- package/components/crosshair/config.js.map +1 -1
- package/components/crosshair/index.d.ts +8 -7
- package/components/crosshair/index.js +144 -72
- package/components/crosshair/index.js.map +1 -1
- package/components/graph/config.d.ts +8 -0
- package/components/graph/config.js +1 -1
- package/components/graph/config.js.map +1 -1
- package/components/graph/index.d.ts +1 -0
- package/components/graph/index.js +14 -9
- package/components/graph/index.js.map +1 -1
- package/components/graph/modules/layout.js +33 -31
- package/components/graph/modules/layout.js.map +1 -1
- package/components/graph/modules/link/index.js +1 -1
- package/components/graph/modules/link/index.js.map +1 -1
- package/components/graph/types.d.ts +2 -1
- package/components/graph/types.js.map +1 -1
- package/components/nested-donut/config.d.ts +1 -1
- package/components/nested-donut/config.js.map +1 -1
- package/components/plotband/config.d.ts +59 -0
- package/components/plotband/config.js +9 -0
- package/components/plotband/config.js.map +1 -0
- package/components/plotband/constants.d.ts +5 -0
- package/components/plotband/constants.js +413 -0
- package/components/plotband/constants.js.map +1 -0
- package/components/plotband/index.d.ts +15 -0
- package/components/plotband/index.js +92 -0
- package/components/plotband/index.js.map +1 -0
- package/components/plotband/style.d.ts +4 -0
- package/components/plotband/style.js +38 -0
- package/components/plotband/style.js.map +1 -0
- package/components/plotband/types.d.ts +51 -0
- package/components/plotband/types.js +27 -0
- package/components/plotband/types.js.map +1 -0
- package/components/plotline/config.d.ts +91 -0
- package/components/plotline/config.js +9 -0
- package/components/plotline/config.js.map +1 -0
- package/components/plotline/constants.d.ts +6 -0
- package/components/plotline/constants.js +58 -0
- package/components/plotline/constants.js.map +1 -0
- package/components/plotline/index.d.ts +14 -0
- package/components/plotline/index.js +102 -0
- package/components/plotline/index.js.map +1 -0
- package/components/plotline/style.d.ts +4 -0
- package/components/plotline/style.js +42 -0
- package/components/plotline/style.js.map +1 -0
- package/components/plotline/types.d.ts +53 -0
- package/components/plotline/types.js +33 -0
- package/components/plotline/types.js.map +1 -0
- package/components/rolling-pin-legend/config.d.ts +19 -0
- package/components/rolling-pin-legend/config.js +11 -0
- package/components/rolling-pin-legend/config.js.map +1 -0
- package/components/rolling-pin-legend/index.d.ts +16 -0
- package/components/rolling-pin-legend/index.js +69 -0
- package/components/rolling-pin-legend/index.js.map +1 -0
- package/components/rolling-pin-legend/style.d.ts +22 -0
- package/components/rolling-pin-legend/style.js +39 -0
- package/components/rolling-pin-legend/style.js.map +1 -0
- package/components/rolling-pin-legend/types.d.ts +1 -0
- package/components/rolling-pin-legend/types.js +2 -0
- package/components/rolling-pin-legend/types.js.map +1 -0
- package/components/scatter/index.d.ts +1 -0
- package/components/scatter/index.js +11 -1
- package/components/scatter/index.js.map +1 -1
- package/components/timeline/config.d.ts +65 -14
- package/components/timeline/config.js +15 -1
- package/components/timeline/config.js.map +1 -1
- package/components/timeline/constants.d.ts +3 -0
- package/components/timeline/constants.js +6 -0
- package/components/timeline/constants.js.map +1 -0
- package/components/timeline/index.d.ts +21 -10
- package/components/timeline/index.js +380 -95
- package/components/timeline/index.js.map +1 -1
- package/components/timeline/style.d.ts +7 -0
- package/components/timeline/style.js +40 -1
- package/components/timeline/style.js.map +1 -1
- package/components/timeline/types.d.ts +62 -0
- package/components/timeline/types.js +2 -0
- package/components/timeline/types.js.map +1 -0
- package/components/timeline/utils.d.ts +2 -0
- package/components/timeline/utils.js +16 -0
- package/components/timeline/utils.js.map +1 -0
- package/components/tooltip/index.js +4 -3
- package/components/tooltip/index.js.map +1 -1
- package/components/treemap/config.d.ts +52 -0
- package/components/treemap/config.js +6 -0
- package/components/treemap/config.js.map +1 -0
- package/components/treemap/index.d.ts +18 -0
- package/components/treemap/index.js +274 -0
- package/components/treemap/index.js.map +1 -0
- package/components/treemap/style.d.ts +25 -0
- package/components/treemap/style.js +69 -0
- package/components/treemap/style.js.map +1 -0
- package/components/treemap/types.d.ts +11 -0
- package/components/treemap/types.js +2 -0
- package/components/treemap/types.js.map +1 -0
- package/components/xy-labels/index.js +1 -1
- package/components/xy-labels/index.js.map +1 -1
- package/components.d.ts +10 -2
- package/components.js +4 -0
- package/components.js.map +1 -1
- package/containers/single-container/index.js +3 -1
- package/containers/single-container/index.js.map +1 -1
- package/containers/xy-container/config.d.ts +2 -0
- package/containers/xy-container/config.js +1 -1
- package/containers/xy-container/config.js.map +1 -1
- package/containers/xy-container/index.js +17 -7
- package/containers/xy-container/index.js.map +1 -1
- package/core/component/index.d.ts +4 -0
- package/core/component/index.js +6 -0
- package/core/component/index.js.map +1 -1
- package/core/xy-component/index.d.ts +1 -0
- package/core/xy-component/index.js +3 -1
- package/core/xy-component/index.js.map +1 -1
- package/data-models/graph.js +7 -1
- package/data-models/graph.js.map +1 -1
- package/index.js +10 -3
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/styles/index.js +1 -0
- package/styles/index.js.map +1 -1
- package/types/data.d.ts +5 -0
- package/types/data.js +7 -0
- package/types/data.js.map +1 -1
- package/types/position.d.ts +2 -1
- package/types/position.js +1 -0
- package/types/position.js.map +1 -1
- package/types/text.d.ts +1 -1
- package/types/text.js.map +1 -1
- package/types.d.ts +5 -0
- package/types.js +6 -1
- package/types.js.map +1 -1
- package/utils/color.d.ts +7 -0
- package/utils/color.js +14 -2
- package/utils/color.js.map +1 -1
- package/utils/data.d.ts +4 -4
- package/utils/data.js +41 -10
- package/utils/data.js.map +1 -1
- package/utils/index.js +3 -3
- package/utils/path.d.ts +8 -0
- package/utils/path.js +109 -1
- package/utils/path.js.map +1 -1
- package/utils/text.d.ts +3 -2
- package/utils/text.js +22 -10
- package/utils/text.js.map +1 -1
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { select } from 'd3-selection';
|
|
2
|
+
import { max, min, minIndex } from 'd3-array';
|
|
2
3
|
import { scaleOrdinal } from 'd3-scale';
|
|
3
4
|
import { drag } from 'd3-drag';
|
|
4
|
-
import { max } from 'd3-array';
|
|
5
5
|
import { XYComponentCore } from '../../core/xy-component/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getNumber, isNumber, arrayOfIndices, getValue, isPlainObject, isFunction, getString, groupBy, getMin, getMax } from '../../utils/data.js';
|
|
7
7
|
import { smartTransition } from '../../utils/d3.js';
|
|
8
8
|
import { getColor } from '../../utils/color.js';
|
|
9
|
-
import { trimSVGText } from '../../utils/text.js';
|
|
9
|
+
import { trimSVGText, textAlignToAnchor } from '../../utils/text.js';
|
|
10
|
+
import { arrowPolylinePath } from '../../utils/path.js';
|
|
11
|
+
import { guid } from '../../utils/misc.js';
|
|
12
|
+
import '../../types.js';
|
|
10
13
|
import { TimelineDefaultConfig } from './config.js';
|
|
11
14
|
import * as style from './style.js';
|
|
12
|
-
import { background, rows, lines, labels, scrollbar, scrollbarBackground, scrollbarHandle, label, row, rowOdd, line } from './style.js';
|
|
15
|
+
import { background, rows, arrows, lines, labels, rowIcons, scrollbar, scrollbarBackground, scrollbarHandle, label, rowIcon, row, rowOdd, lineGroup, line, lineStartIcon, lineEndIcon, arrow } from './style.js';
|
|
16
|
+
import { TIMELINE_DEFAULT_ARROW_HEAD_LENGTH, TIMELINE_DEFAULT_ARROW_HEAD_WIDTH, TIMELINE_DEFAULT_ARROW_MARGIN } from './constants.js';
|
|
17
|
+
import { getIconBleed } from './utils.js';
|
|
18
|
+
import { TextAlign } from '../../types/text.js';
|
|
19
|
+
import { Arrangement } from '../../types/position.js';
|
|
13
20
|
|
|
14
21
|
class Timeline extends XYComponentCore {
|
|
15
22
|
constructor(config) {
|
|
@@ -17,6 +24,12 @@ class Timeline extends XYComponentCore {
|
|
|
17
24
|
this._defaultConfig = TimelineDefaultConfig;
|
|
18
25
|
this.config = this._defaultConfig;
|
|
19
26
|
this.events = {
|
|
27
|
+
[Timeline.selectors.background]: {
|
|
28
|
+
wheel: this._onMouseWheel.bind(this),
|
|
29
|
+
},
|
|
30
|
+
[Timeline.selectors.label]: {
|
|
31
|
+
wheel: this._onMouseWheel.bind(this),
|
|
32
|
+
},
|
|
20
33
|
[Timeline.selectors.rows]: {
|
|
21
34
|
wheel: this._onMouseWheel.bind(this),
|
|
22
35
|
},
|
|
@@ -30,14 +43,29 @@ class Timeline extends XYComponentCore {
|
|
|
30
43
|
this._maxScroll = 0;
|
|
31
44
|
this._scrollbarHeight = 0;
|
|
32
45
|
this._labelMargin = 5;
|
|
46
|
+
this._labelWidth = 0; // Will be overridden in `get bleed ()`
|
|
47
|
+
this._rowIconBleed = [0, 0];
|
|
48
|
+
this._lineBleed = [0, 0];
|
|
49
|
+
/** We define a dedicated clipping path for this component because it needs to behave
|
|
50
|
+
* differently than the regular XYContainer's clipPath */
|
|
51
|
+
this._clipPathId = guid();
|
|
33
52
|
if (config)
|
|
34
53
|
this.setConfig(config);
|
|
35
54
|
// Invisible background rect to track events
|
|
36
55
|
this._background = this.g.append('rect').attr('class', background);
|
|
56
|
+
// Clip path
|
|
57
|
+
this._clipPath = this.g.append('clipPath')
|
|
58
|
+
.attr('id', this._clipPathId);
|
|
59
|
+
this._clipPath.append('rect');
|
|
37
60
|
// Group for content
|
|
38
|
-
this._rowsGroup = this.g.append('g').attr('class', rows)
|
|
39
|
-
|
|
61
|
+
this._rowsGroup = this.g.append('g').attr('class', rows)
|
|
62
|
+
.style('clip-path', `url(#${this._clipPathId})`);
|
|
63
|
+
this._arrowsGroup = this.g.append('g').attr('class', arrows)
|
|
64
|
+
.style('clip-path', `url(#${this._clipPathId})`);
|
|
65
|
+
this._linesGroup = this.g.append('g').attr('class', lines)
|
|
66
|
+
.style('clip-path', `url(#${this._clipPathId})`);
|
|
40
67
|
this._labelsGroup = this.g.append('g').attr('class', labels);
|
|
68
|
+
this._rowIconsGroup = this.g.append('g').attr('class', rowIcons);
|
|
41
69
|
this._scrollBarGroup = this.g.append('g').attr('class', scrollbar);
|
|
42
70
|
// Scroll bar
|
|
43
71
|
this._scrollBarBackground = this._scrollBarGroup.append('rect')
|
|
@@ -49,35 +77,80 @@ class Timeline extends XYComponentCore {
|
|
|
49
77
|
.on('drag', this._onScrollbarDrag.bind(this));
|
|
50
78
|
this._scrollBarHandle.call(dragBehaviour);
|
|
51
79
|
}
|
|
80
|
+
setConfig(config) {
|
|
81
|
+
super.setConfig(config);
|
|
82
|
+
}
|
|
83
|
+
setData(data) {
|
|
84
|
+
super.setData(data);
|
|
85
|
+
}
|
|
52
86
|
get bleed() {
|
|
87
|
+
var _a, _b, _c, _d;
|
|
53
88
|
const { config, datamodel: { data } } = this;
|
|
89
|
+
const rowLabels = this._getRowLabels(data);
|
|
90
|
+
const rowHeight = config.rowHeight || (this._height / (rowLabels.length || 1));
|
|
91
|
+
const hasIcons = rowLabels.some(l => l.iconHref);
|
|
92
|
+
const maxIconSize = max(rowLabels.map(l => l.iconSize || 0));
|
|
54
93
|
// We calculate the longest label width to set the bleed values accordingly
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
labelsBleed = config.labelWidth + this._labelMargin;
|
|
94
|
+
if ((_a = config.showRowLabels) !== null && _a !== void 0 ? _a : config.showLabels) {
|
|
95
|
+
if ((_b = config.rowLabelWidth) !== null && _b !== void 0 ? _b : config.labelWidth)
|
|
96
|
+
this._labelWidth = ((_c = config.rowLabelWidth) !== null && _c !== void 0 ? _c : config.labelWidth) + this._labelMargin;
|
|
59
97
|
else {
|
|
60
|
-
const
|
|
61
|
-
const longestLabel = recordLabels.reduce((acc, val) => acc.length > val.length ? acc : val, '');
|
|
98
|
+
const longestLabel = rowLabels.reduce((longestLabel, l) => longestLabel.formattedLabel.length > l.formattedLabel.length ? longestLabel : l, rowLabels[0]);
|
|
62
99
|
const label$1 = this._labelsGroup.append('text')
|
|
63
100
|
.attr('class', label)
|
|
64
|
-
.text(longestLabel)
|
|
65
|
-
.call(trimSVGText, config.maxLabelWidth);
|
|
101
|
+
.text((longestLabel === null || longestLabel === void 0 ? void 0 : longestLabel.formattedLabel) || '')
|
|
102
|
+
.call(trimSVGText, (_d = config.rowMaxLabelWidth) !== null && _d !== void 0 ? _d : config.maxLabelWidth);
|
|
66
103
|
const labelWidth = label$1.node().getBBox().width;
|
|
67
|
-
|
|
104
|
+
label$1.remove();
|
|
68
105
|
const tolerance = 1.15; // Some characters are wider than others so we add a little of extra space to take that into account
|
|
69
|
-
|
|
106
|
+
this._labelWidth = labelWidth ? tolerance * labelWidth + this._labelMargin : 0;
|
|
70
107
|
}
|
|
71
108
|
}
|
|
72
|
-
|
|
109
|
+
// There can be multiple start / end items with the same timestamp, so we need to find the shortest one
|
|
110
|
+
const minTimestamp = min(data, (d, i) => getNumber(d, config.x, i));
|
|
111
|
+
const dataMin = data.filter((d, i) => getNumber(d, config.x, i) === minTimestamp);
|
|
112
|
+
const dataMinShortestItemIdx = minIndex(dataMin, (d, i) => this._getLineDuration(d, i));
|
|
113
|
+
const firstItemIdx = data.findIndex(d => d === dataMin[dataMinShortestItemIdx]);
|
|
114
|
+
const firstItem = data[firstItemIdx];
|
|
115
|
+
const maxTimestamp = max(data, (d, i) => getNumber(d, config.x, i) + this._getLineDuration(d, i));
|
|
116
|
+
const dataMax = data.filter((d, i) => getNumber(d, config.x, i) + this._getLineDuration(d, i) === maxTimestamp);
|
|
117
|
+
const dataMaxShortestItemIdx = minIndex(dataMax, (d, i) => this._getLineDuration(d, i));
|
|
118
|
+
const lastItemIdx = data.findIndex(d => d === dataMax[dataMaxShortestItemIdx]);
|
|
119
|
+
const lastItem = data[lastItemIdx];
|
|
120
|
+
// Small segments bleed
|
|
121
|
+
const lineBleed = [1, 1];
|
|
122
|
+
if (config.showEmptySegments && config.lineCap && firstItem && lastItem) {
|
|
123
|
+
const firstItemStart = getNumber(firstItem, config.x, firstItemIdx);
|
|
124
|
+
const firstItemEnd = getNumber(firstItem, config.x, firstItemIdx) + this._getLineDuration(firstItem, firstItemIdx);
|
|
125
|
+
const lastItemStart = getNumber(lastItem, config.x, lastItemIdx);
|
|
126
|
+
const lastItemEnd = getNumber(lastItem, config.x, lastItemIdx) + this._getLineDuration(lastItem, lastItemIdx);
|
|
127
|
+
const fullTimeRange = lastItemEnd - firstItemStart;
|
|
128
|
+
const firstItemHeight = this._getLineWidth(firstItem, firstItemIdx, rowHeight);
|
|
129
|
+
const lastItemHeight = this._getLineWidth(lastItem, lastItemIdx, rowHeight);
|
|
130
|
+
if ((firstItemEnd - firstItemStart) / fullTimeRange * this._width < firstItemHeight)
|
|
131
|
+
lineBleed[0] = firstItemHeight / 2;
|
|
132
|
+
if ((lastItemEnd - lastItemStart) / fullTimeRange * this._width < lastItemHeight)
|
|
133
|
+
lineBleed[1] = lastItemHeight / 2;
|
|
134
|
+
}
|
|
135
|
+
this._lineBleed = lineBleed;
|
|
136
|
+
// Icon bleed
|
|
137
|
+
const iconBleed = [0, 0];
|
|
138
|
+
if (config.lineStartIcon) {
|
|
139
|
+
iconBleed[0] = max(data, (d, i) => getIconBleed(d, i, config.lineStartIcon, config.lineStartIconSize, config.lineStartIconArrangement, rowHeight)) || 0;
|
|
140
|
+
}
|
|
141
|
+
if (config.lineEndIcon) {
|
|
142
|
+
iconBleed[1] = max(data, (d, i) => getIconBleed(d, i, config.lineEndIcon, config.lineEndIconSize, config.lineEndIconArrangement, rowHeight)) || 0;
|
|
143
|
+
}
|
|
144
|
+
this._rowIconBleed = iconBleed;
|
|
73
145
|
return {
|
|
74
146
|
top: 0,
|
|
75
147
|
bottom: 0,
|
|
76
|
-
left:
|
|
77
|
-
right:
|
|
148
|
+
left: this._labelWidth + iconBleed[0] + (hasIcons ? maxIconSize : 0) + lineBleed[0],
|
|
149
|
+
right: this._scrollBarWidth + this._scrollBarMargin + iconBleed[1] + lineBleed[1],
|
|
78
150
|
};
|
|
79
151
|
}
|
|
80
152
|
_render(customDuration) {
|
|
153
|
+
var _a;
|
|
81
154
|
super._render(customDuration);
|
|
82
155
|
const { config, datamodel: { data } } = this;
|
|
83
156
|
const duration = isNumber(customDuration) ? customDuration : config.duration;
|
|
@@ -85,76 +158,189 @@ class Timeline extends XYComponentCore {
|
|
|
85
158
|
const yRange = this.yScale.range();
|
|
86
159
|
const yStart = Math.min(...yRange);
|
|
87
160
|
const yHeight = Math.abs(yRange[1] - yRange[0]);
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
161
|
+
const rowLabels = this._getRowLabels(data);
|
|
162
|
+
const numRowLabels = rowLabels.length;
|
|
163
|
+
const rowHeight = config.rowHeight || (yHeight / (numRowLabels || 1));
|
|
164
|
+
const yOrdinalScale = scaleOrdinal()
|
|
165
|
+
.range(arrayOfIndices(numRowLabels))
|
|
166
|
+
.domain(rowLabels.map(l => l.label));
|
|
167
|
+
const lineDataPrepared = this._prepareLinesData(data, yOrdinalScale, rowHeight);
|
|
95
168
|
// Invisible Background rect to track events
|
|
96
169
|
this._background
|
|
97
170
|
.attr('width', this._width)
|
|
98
171
|
.attr('height', this._height)
|
|
99
172
|
.attr('opacity', 0);
|
|
173
|
+
// Row Icons
|
|
174
|
+
const rowIcons = this._rowIconsGroup.selectAll(`.${rowIcon}`)
|
|
175
|
+
.data(rowLabels.filter(d => d.iconSize), l => l === null || l === void 0 ? void 0 : l.label);
|
|
176
|
+
const rowIconsEnter = rowIcons.enter().append('use')
|
|
177
|
+
.attr('class', rowIcon)
|
|
178
|
+
.attr('x', 0)
|
|
179
|
+
.attr('width', l => l.iconSize)
|
|
180
|
+
.attr('height', l => l.iconSize)
|
|
181
|
+
.attr('y', l => yStart + (yOrdinalScale(l.label) + 0.5) * rowHeight - l.iconSize / 2)
|
|
182
|
+
.style('opacity', 0);
|
|
183
|
+
smartTransition(rowIconsEnter.merge(rowIcons), duration)
|
|
184
|
+
.attr('href', l => l.iconHref)
|
|
185
|
+
.attr('x', 0)
|
|
186
|
+
.attr('y', l => yStart + (yOrdinalScale(l.label) + 0.5) * rowHeight - l.iconSize / 2)
|
|
187
|
+
.attr('width', l => l.iconSize)
|
|
188
|
+
.attr('height', l => l.iconSize)
|
|
189
|
+
.style('color', l => l.iconColor)
|
|
190
|
+
.style('opacity', 1);
|
|
191
|
+
smartTransition(rowIcons.exit(), duration)
|
|
192
|
+
.style('opacity', 0)
|
|
193
|
+
.remove();
|
|
100
194
|
// Labels
|
|
101
195
|
const labels = this._labelsGroup.selectAll(`.${label}`)
|
|
102
|
-
.data(config.showLabels ?
|
|
196
|
+
.data(((_a = config.showRowLabels) !== null && _a !== void 0 ? _a : config.showLabels) ? rowLabels : [], l => l === null || l === void 0 ? void 0 : l.label);
|
|
197
|
+
const labelOffset = config.rowLabelTextAlign === TextAlign.Center ? this._labelWidth / 2
|
|
198
|
+
: config.rowLabelTextAlign === TextAlign.Left ? this._labelWidth
|
|
199
|
+
: this._labelMargin;
|
|
200
|
+
const xStart = xRange[0] - this._rowIconBleed[0] - this._lineBleed[0];
|
|
201
|
+
const labelXStart = xStart - labelOffset;
|
|
103
202
|
const labelsEnter = labels.enter().append('text')
|
|
104
|
-
.attr('class', label)
|
|
105
|
-
|
|
106
|
-
.attr('
|
|
107
|
-
.
|
|
108
|
-
|
|
203
|
+
.attr('class', label)
|
|
204
|
+
.attr('x', labelXStart)
|
|
205
|
+
.attr('y', l => yStart + (yOrdinalScale(l.label) + 0.5) * rowHeight)
|
|
206
|
+
.style('opacity', 0);
|
|
207
|
+
const labelsMerged = labelsEnter.merge(labels)
|
|
208
|
+
.text(l => l.formattedLabel)
|
|
109
209
|
.each((label, i, els) => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
210
|
+
var _a, _b;
|
|
211
|
+
const labelSelection = select(els[i]);
|
|
212
|
+
trimSVGText(labelSelection, ((_a = config.rowLabelWidth) !== null && _a !== void 0 ? _a : config.labelWidth) || ((_b = config.rowMaxLabelWidth) !== null && _b !== void 0 ? _b : config.maxLabelWidth));
|
|
213
|
+
// Apply custom label style if it has been provided
|
|
214
|
+
const customStyle = getValue(label, config.rowLabelStyle);
|
|
215
|
+
if (!isPlainObject(customStyle))
|
|
216
|
+
return;
|
|
217
|
+
for (const [prop, value] of Object.entries(customStyle)) {
|
|
218
|
+
labelSelection.style(prop, value);
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
.style('text-anchor', textAlignToAnchor(config.rowLabelTextAlign));
|
|
222
|
+
smartTransition(labelsMerged, duration)
|
|
223
|
+
.attr('x', labelXStart)
|
|
224
|
+
.attr('y', l => yStart + (yOrdinalScale(l.label) + 0.5) * rowHeight)
|
|
225
|
+
.style('opacity', 1);
|
|
226
|
+
smartTransition(labels.exit(), duration)
|
|
227
|
+
.style('opacity', 0)
|
|
228
|
+
.remove();
|
|
113
229
|
// Row background rects
|
|
114
|
-
const
|
|
115
|
-
const numRows = Math.max(Math.floor(yHeight /
|
|
116
|
-
const recordTypes = Array(numRows).fill(null).map((_, i) =>
|
|
230
|
+
const timelineWidth = xRange[1] - xRange[0] + this._rowIconBleed[0] + this._rowIconBleed[1] + this._lineBleed[0] + this._lineBleed[1];
|
|
231
|
+
const numRows = Math.max(Math.floor(yHeight / rowHeight), numRowLabels);
|
|
232
|
+
const recordTypes = Array(numRows).fill(null).map((_, i) => rowLabels[i]);
|
|
117
233
|
const rects = this._rowsGroup.selectAll(`.${row}`)
|
|
118
234
|
.data(recordTypes);
|
|
119
235
|
const rectsEnter = rects.enter().append('rect')
|
|
120
|
-
.attr('class', row)
|
|
121
|
-
|
|
122
|
-
.
|
|
123
|
-
.attr('
|
|
124
|
-
.attr('
|
|
125
|
-
.
|
|
126
|
-
|
|
127
|
-
|
|
236
|
+
.attr('class', row)
|
|
237
|
+
.attr('x', xStart)
|
|
238
|
+
.attr('width', timelineWidth)
|
|
239
|
+
.attr('y', (_, i) => yStart + i * rowHeight)
|
|
240
|
+
.attr('height', rowHeight)
|
|
241
|
+
.style('opacity', 0);
|
|
242
|
+
const rectsMerged = rectsEnter.merge(rects)
|
|
243
|
+
.classed(rowOdd, config.alternatingRowColors ? (_, i) => !(i % 2) : null);
|
|
244
|
+
smartTransition(rectsMerged, duration)
|
|
245
|
+
.attr('x', xStart)
|
|
246
|
+
.attr('width', timelineWidth)
|
|
247
|
+
.attr('y', (_, i) => yStart + i * rowHeight)
|
|
248
|
+
.attr('height', rowHeight)
|
|
249
|
+
.style('opacity', 1);
|
|
250
|
+
smartTransition(rects.exit(), duration)
|
|
251
|
+
.style('opacity', 0)
|
|
252
|
+
.remove();
|
|
128
253
|
// Lines
|
|
129
|
-
const lines = this._linesGroup.selectAll(`.${
|
|
130
|
-
.data(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
254
|
+
const lines = this._linesGroup.selectAll(`.${lineGroup}`)
|
|
255
|
+
.data(lineDataPrepared, (d) => d._id);
|
|
256
|
+
const linesEnter = lines.enter().append('g')
|
|
257
|
+
.attr('class', lineGroup)
|
|
258
|
+
.style('opacity', 0)
|
|
259
|
+
.attr('transform', (d, i) => {
|
|
260
|
+
var _a, _b;
|
|
261
|
+
const configuredPos = isFunction(config.animationLineEnterPosition)
|
|
262
|
+
? config.animationLineEnterPosition(d, i, lineDataPrepared)
|
|
263
|
+
: config.animationLineEnterPosition;
|
|
264
|
+
const [x, y] = [(_a = configuredPos === null || configuredPos === void 0 ? void 0 : configuredPos[0]) !== null && _a !== void 0 ? _a : d._xPx, (_b = configuredPos === null || configuredPos === void 0 ? void 0 : configuredPos[1]) !== null && _b !== void 0 ? _b : d._yPx];
|
|
265
|
+
return `translate(${x}, ${y})`;
|
|
135
266
|
});
|
|
136
|
-
|
|
267
|
+
linesEnter.append('rect')
|
|
137
268
|
.attr('class', line)
|
|
138
|
-
.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
.attr('transform', 'translate(0, 10)')
|
|
144
|
-
.style('opacity', 0);
|
|
145
|
-
const linesMerged = linesEnter.merge(lines)
|
|
146
|
-
.style('fill', (d, i) => getColor(d, config.color, ordinalScale(this._getRecordType(d, i))))
|
|
147
|
-
.style('cursor', (d, i) => getString(d, config.cursor, i))
|
|
148
|
-
.call(this._positionLines.bind(this), ordinalScale);
|
|
269
|
+
.style('fill', (d, i) => getColor(d, config.color, yOrdinalScale(this._getRecordKey(d, i))))
|
|
270
|
+
.call(this._renderLines.bind(this), rowHeight);
|
|
271
|
+
linesEnter.append('use').attr('class', lineStartIcon);
|
|
272
|
+
linesEnter.append('use').attr('class', lineEndIcon);
|
|
273
|
+
const linesMerged = linesEnter.merge(lines);
|
|
149
274
|
smartTransition(linesMerged, duration)
|
|
150
|
-
.attr('transform',
|
|
275
|
+
.attr('transform', d => `translate(${d._xPx + d._xOffsetPx}, ${d._yPx})`)
|
|
151
276
|
.style('opacity', 1);
|
|
152
|
-
|
|
277
|
+
const lineRectElementsSelection = linesMerged.selectAll(`.${line}`)
|
|
278
|
+
.data(d => [d]);
|
|
279
|
+
smartTransition(lineRectElementsSelection, duration)
|
|
280
|
+
.style('fill', (d, i) => getColor(d, config.color, yOrdinalScale(this._getRecordKey(d, i))))
|
|
281
|
+
.style('cursor', (d, i) => { var _a; return getString(d, (_a = config.lineCursor) !== null && _a !== void 0 ? _a : config.cursor, i); })
|
|
282
|
+
.call(this._renderLines.bind(this), rowHeight);
|
|
283
|
+
linesMerged.selectAll(`.${lineStartIcon}`)
|
|
284
|
+
.data(d => [d])
|
|
285
|
+
.attr('href', (d, i) => getString(d, config.lineStartIcon, i))
|
|
286
|
+
.attr('x', (d, i) => {
|
|
287
|
+
const iconSize = d._startIconSize;
|
|
288
|
+
const iconArrangement = d._startIconArrangement;
|
|
289
|
+
const offset = iconArrangement === Arrangement.Inside ? 0
|
|
290
|
+
: iconArrangement === Arrangement.Center ? -iconSize / 2
|
|
291
|
+
: -iconSize;
|
|
292
|
+
return offset;
|
|
293
|
+
})
|
|
294
|
+
.attr('y', d => (-(d._startIconSize - d._height) / 2) || 0)
|
|
295
|
+
.attr('width', d => d._startIconSize)
|
|
296
|
+
.attr('height', d => d._startIconSize)
|
|
297
|
+
.style('color', d => d._startIconColor);
|
|
298
|
+
linesMerged.selectAll(`.${lineEndIcon}`)
|
|
299
|
+
.data(d => [d])
|
|
300
|
+
.attr('href', (d, i) => getString(d, config.lineEndIcon, i))
|
|
301
|
+
.attr('x', (d, i) => {
|
|
302
|
+
const lineLength = d._lengthCorrected;
|
|
303
|
+
const iconSize = d._endIconSize;
|
|
304
|
+
const iconArrangement = d._endIconArrangement;
|
|
305
|
+
const offset = iconArrangement === Arrangement.Inside ? -iconSize
|
|
306
|
+
: iconArrangement === Arrangement.Center ? -iconSize / 2
|
|
307
|
+
: 0;
|
|
308
|
+
return lineLength + offset;
|
|
309
|
+
})
|
|
310
|
+
.attr('y', d => -((d._endIconSize - d._height) / 2) || 0)
|
|
311
|
+
.attr('width', d => d._endIconSize)
|
|
312
|
+
.attr('height', d => d._endIconSize)
|
|
313
|
+
.style('color', d => d._endIconColor);
|
|
314
|
+
const linesExit = lines.exit();
|
|
315
|
+
smartTransition(linesExit, duration)
|
|
316
|
+
.style('opacity', 0)
|
|
317
|
+
.attr('transform', (d, i) => {
|
|
318
|
+
var _a, _b;
|
|
319
|
+
const configuredPos = isFunction(config.animationLineExitPosition)
|
|
320
|
+
? config.animationLineExitPosition(d, i, lineDataPrepared)
|
|
321
|
+
: config.animationLineExitPosition;
|
|
322
|
+
const [x, y] = [(_a = configuredPos === null || configuredPos === void 0 ? void 0 : configuredPos[0]) !== null && _a !== void 0 ? _a : d._xPx, (_b = configuredPos === null || configuredPos === void 0 ? void 0 : configuredPos[1]) !== null && _b !== void 0 ? _b : d._yPx];
|
|
323
|
+
return `translate(${x}, ${y})`;
|
|
324
|
+
})
|
|
325
|
+
.remove();
|
|
326
|
+
// Arrows
|
|
327
|
+
const arrowsData = this._prepareArrowsData(data, yOrdinalScale, rowHeight);
|
|
328
|
+
const arrows = this._arrowsGroup.selectAll(`.${arrow}`)
|
|
329
|
+
.data(arrowsData !== null && arrowsData !== void 0 ? arrowsData : [], d => d.id);
|
|
330
|
+
const arrowsEnter = arrows.enter().append('path')
|
|
331
|
+
.attr('class', arrow)
|
|
332
|
+
.style('opacity', 0);
|
|
333
|
+
smartTransition(arrowsEnter.merge(arrows), duration)
|
|
334
|
+
.attr('d', (d) => {
|
|
335
|
+
var _a, _b;
|
|
336
|
+
return arrowPolylinePath(d._points, (_a = d.arrowHeadLength) !== null && _a !== void 0 ? _a : TIMELINE_DEFAULT_ARROW_HEAD_LENGTH, (_b = d.arrowHeadWidth) !== null && _b !== void 0 ? _b : TIMELINE_DEFAULT_ARROW_HEAD_WIDTH);
|
|
337
|
+
})
|
|
338
|
+
.style('opacity', 1);
|
|
339
|
+
smartTransition(arrows.exit(), duration)
|
|
153
340
|
.style('opacity', 0)
|
|
154
341
|
.remove();
|
|
155
342
|
// Scroll Bar
|
|
156
|
-
const
|
|
157
|
-
const absoluteContentHeight = contentBBox.height;
|
|
343
|
+
const absoluteContentHeight = recordTypes.length * rowHeight;
|
|
158
344
|
this._scrollbarHeight = yHeight * yHeight / absoluteContentHeight || 0;
|
|
159
345
|
this._maxScroll = Math.max(absoluteContentHeight - yHeight, 0);
|
|
160
346
|
this._scrollBarGroup
|
|
@@ -171,32 +357,119 @@ class Timeline extends XYComponentCore {
|
|
|
171
357
|
.attr('rx', this._scrollBarWidth / 2)
|
|
172
358
|
.attr('ry', this._scrollBarWidth / 2);
|
|
173
359
|
this._updateScrollPosition(0);
|
|
360
|
+
// Clip path
|
|
361
|
+
const clipPathRect = this._clipPath.select('rect');
|
|
362
|
+
smartTransition(clipPathRect, clipPathRect.attr('width') ? duration : 0)
|
|
363
|
+
.attr('x', xStart)
|
|
364
|
+
.attr('width', timelineWidth)
|
|
365
|
+
.attr('height', this._height);
|
|
366
|
+
}
|
|
367
|
+
_getLineLength(d, i) {
|
|
368
|
+
var _a, _b;
|
|
369
|
+
const { config, xScale } = this;
|
|
370
|
+
const x = getNumber(d, config.x, i);
|
|
371
|
+
const length = (_b = getNumber(d, (_a = config.lineDuration) !== null && _a !== void 0 ? _a : config.length, i)) !== null && _b !== void 0 ? _b : 0;
|
|
372
|
+
const lineLength = xScale(x + length) - xScale(x);
|
|
373
|
+
return lineLength;
|
|
174
374
|
}
|
|
175
|
-
|
|
375
|
+
_getLineWidth(d, i, rowHeight) {
|
|
376
|
+
var _a;
|
|
377
|
+
const { config } = this;
|
|
378
|
+
return (_a = getNumber(d, config.lineWidth, i)) !== null && _a !== void 0 ? _a : Math.max(Math.floor(rowHeight / 2), 1);
|
|
379
|
+
}
|
|
380
|
+
_getLineDuration(d, i) {
|
|
381
|
+
var _a, _b;
|
|
382
|
+
const { config } = this;
|
|
383
|
+
return (_b = getNumber(d, (_a = config.lineDuration) !== null && _a !== void 0 ? _a : config.length, i)) !== null && _b !== void 0 ? _b : 0;
|
|
384
|
+
}
|
|
385
|
+
_prepareLinesData(data, rowOrdinalScale, rowHeight) {
|
|
176
386
|
const { config, xScale, yScale } = this;
|
|
177
387
|
const yRange = yScale.range();
|
|
178
388
|
const yStart = Math.min(...yRange);
|
|
179
|
-
|
|
180
|
-
var _a;
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
if (width < 0) {
|
|
389
|
+
return data.map((d, i) => {
|
|
390
|
+
var _a, _b, _c, _d, _e;
|
|
391
|
+
const id = (_a = getString(d, config.id, i)) !== null && _a !== void 0 ? _a : [
|
|
392
|
+
this._getRecordKey(d, i), getNumber(d, config.x, i),
|
|
393
|
+
].join('-');
|
|
394
|
+
const lineWidth = this._getLineWidth(d, i, rowHeight);
|
|
395
|
+
const lineLength = this._getLineLength(d, i);
|
|
396
|
+
if (lineLength < 0) {
|
|
188
397
|
console.warn('Unovis | Timeline: Line segments should not have negative lengths. Setting to 0.');
|
|
189
398
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
.
|
|
193
|
-
.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
399
|
+
const isLineTooShort = config.showEmptySegments && config.lineCap && (lineLength < lineWidth);
|
|
400
|
+
const lineLengthCorrected = config.showEmptySegments
|
|
401
|
+
? Math.max(config.lineCap ? lineWidth : 1, lineLength)
|
|
402
|
+
: Math.max(0, lineLength);
|
|
403
|
+
const x = xScale(getNumber(d, config.x, i));
|
|
404
|
+
const y = yStart + rowOrdinalScale(this._getRecordKey(d, i)) * rowHeight + (rowHeight - lineWidth) / 2;
|
|
405
|
+
const xOffset = isLineTooShort ? -(lineLengthCorrected - lineLength) / 2 : 0;
|
|
406
|
+
return Object.assign(Object.assign({}, d), { _id: id, _xPx: x, _yPx: y, _xOffsetPx: xOffset, _length: lineLength, _height: lineWidth, _lengthCorrected: lineLengthCorrected, _startIconSize: (_b = getNumber(d, config.lineStartIconSize, i)) !== null && _b !== void 0 ? _b : lineWidth, _endIconSize: (_c = getNumber(d, config.lineEndIconSize, i)) !== null && _c !== void 0 ? _c : lineWidth, _startIconColor: getString(d, config.lineStartIconColor, i), _endIconColor: getString(d, config.lineEndIconColor, i), _startIconArrangement: (_d = getValue(d, config.lineStartIconArrangement, i)) !== null && _d !== void 0 ? _d : Arrangement.Outside, _endIconArrangement: (_e = getValue(d, config.lineEndIconArrangement, i)) !== null && _e !== void 0 ? _e : Arrangement.Outside });
|
|
198
407
|
});
|
|
199
408
|
}
|
|
409
|
+
_prepareArrowsData(data, rowOrdinalScale, rowHeight) {
|
|
410
|
+
var _a;
|
|
411
|
+
const { config } = this;
|
|
412
|
+
const arrowsData = (_a = config.arrows) === null || _a === void 0 ? void 0 : _a.map(a => {
|
|
413
|
+
var _a, _b, _c, _d, _e;
|
|
414
|
+
const sourceLineIndex = data.findIndex((d, i) => getString(d, config.id, i) === a.lineSourceId);
|
|
415
|
+
const targetLineIndex = data.findIndex((d, i) => getString(d, config.id, i) === a.lineTargetId);
|
|
416
|
+
const sourceLine = data[sourceLineIndex];
|
|
417
|
+
const targetLine = data[targetLineIndex];
|
|
418
|
+
if (!sourceLine || !targetLine) {
|
|
419
|
+
console.warn('Unovis | Timeline: Arrow references a non-existent line. Skipping...', a);
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
const sourceLineY = rowOrdinalScale(this._getRecordKey(sourceLine, sourceLineIndex)) * rowHeight + rowHeight / 2;
|
|
423
|
+
const targetLineY = rowOrdinalScale(this._getRecordKey(targetLine, targetLineIndex)) * rowHeight + rowHeight / 2;
|
|
424
|
+
const sourceLineWidth = this._getLineWidth(sourceLine, sourceLineIndex, rowHeight);
|
|
425
|
+
const targetLineWidth = this._getLineWidth(targetLine, targetLineIndex, rowHeight);
|
|
426
|
+
const x1 = (a.xSource
|
|
427
|
+
? this.xScale(a.xSource)
|
|
428
|
+
: this.xScale(getNumber(sourceLine, config.x, sourceLineIndex)) + this._getLineLength(sourceLine, sourceLineIndex)) + ((_a = a.xSourceOffsetPx) !== null && _a !== void 0 ? _a : 0);
|
|
429
|
+
const targetLineLength = this._getLineLength(targetLine, targetLineIndex);
|
|
430
|
+
const isTargetLineTooShort = config.showEmptySegments && config.lineCap && (targetLineLength < targetLineWidth);
|
|
431
|
+
const targetLineStart = this.xScale(getNumber(targetLine, config.x, targetLineIndex)) + (isTargetLineTooShort ? -targetLineWidth / 2 : 0);
|
|
432
|
+
const x2 = (a.xTarget ? this.xScale(a.xTarget) : targetLineStart) + ((_b = a.xTargetOffsetPx) !== null && _b !== void 0 ? _b : 0);
|
|
433
|
+
const isX2OutsideTargetLineStart = (x2 < targetLineStart) || (x2 > targetLineStart);
|
|
434
|
+
// Points array
|
|
435
|
+
const sourceMargin = (_c = a.lineSourceMarginPx) !== null && _c !== void 0 ? _c : TIMELINE_DEFAULT_ARROW_MARGIN;
|
|
436
|
+
const targetMargin = (_d = a.lineTargetMarginPx) !== null && _d !== void 0 ? _d : TIMELINE_DEFAULT_ARROW_MARGIN;
|
|
437
|
+
const y1 = sourceLineY < targetLineY ? sourceLineY + sourceLineWidth / 2 + sourceMargin : sourceLineY - sourceLineWidth / 2 - sourceMargin;
|
|
438
|
+
const y2 = sourceLineY < targetLineY ? targetLineY - targetLineWidth / 2 - targetMargin : targetLineY + targetLineWidth / 2 + targetMargin;
|
|
439
|
+
const arrowHeadLength = (_e = a.arrowHeadLength) !== null && _e !== void 0 ? _e : TIMELINE_DEFAULT_ARROW_HEAD_LENGTH;
|
|
440
|
+
const isForwardArrow = x1 < x2 && !isX2OutsideTargetLineStart;
|
|
441
|
+
const threshold = arrowHeadLength + (isForwardArrow ? targetMargin : 0);
|
|
442
|
+
const points = [[x1, y1]];
|
|
443
|
+
if (Math.abs(x2 - x1) > threshold) {
|
|
444
|
+
if (isForwardArrow) {
|
|
445
|
+
points.push([x1, (y1 + targetLineY) / 2]); // A dummy point to enable smooth transitions when arrows change
|
|
446
|
+
points.push([x1, targetLineY]);
|
|
447
|
+
points.push([x2 - targetMargin, targetLineY]);
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
const verticalOffset = Math.sign(targetLineY - sourceLineY) * (rowHeight / 4);
|
|
451
|
+
points.push([x1, y2 - verticalOffset]);
|
|
452
|
+
points.push([x2, y2 - verticalOffset]);
|
|
453
|
+
points.push([x2, y2]);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
const quarterOffset = (y2 - y1) / 4;
|
|
458
|
+
points.push([x1, y1 + quarterOffset]); // A dummy point to enable smooth transitions
|
|
459
|
+
points.push([x1, y1 + 3 * quarterOffset]); // A dummy point to enable smooth transitions
|
|
460
|
+
points.push([x1, y2]);
|
|
461
|
+
}
|
|
462
|
+
return Object.assign(Object.assign({}, a), { _points: points });
|
|
463
|
+
}).filter(Boolean);
|
|
464
|
+
return arrowsData;
|
|
465
|
+
}
|
|
466
|
+
_renderLines(selection) {
|
|
467
|
+
const { config } = this;
|
|
468
|
+
selection
|
|
469
|
+
.attr('width', d => d._lengthCorrected)
|
|
470
|
+
.attr('height', d => d._height)
|
|
471
|
+
.attr('rx', d => config.lineCap ? d._height / 2 : null);
|
|
472
|
+
}
|
|
200
473
|
_onScrollbarDrag(event) {
|
|
201
474
|
const yRange = this.yScale.range();
|
|
202
475
|
const yHeight = Math.abs(yRange[1] - yRange[0]);
|
|
@@ -219,28 +492,40 @@ class Timeline extends XYComponentCore {
|
|
|
219
492
|
this._scrollDistance += diff;
|
|
220
493
|
this._scrollDistance = Math.max(0, this._scrollDistance);
|
|
221
494
|
this._scrollDistance = Math.min(this._maxScroll, this._scrollDistance);
|
|
495
|
+
this._clipPath.attr('transform', `translate(0,${this._scrollDistance})`);
|
|
222
496
|
this._linesGroup.attr('transform', `translate(0,${-this._scrollDistance})`);
|
|
223
497
|
this._rowsGroup.attr('transform', `translate(0,${-this._scrollDistance})`);
|
|
224
498
|
this._labelsGroup.attr('transform', `translate(0,${-this._scrollDistance})`);
|
|
499
|
+
this._rowIconsGroup.attr('transform', `translate(0,${-this._scrollDistance})`);
|
|
500
|
+
this._arrowsGroup.attr('transform', `translate(0,${-this._scrollDistance})`);
|
|
225
501
|
const scrollBarPosition = (this._scrollDistance / this._maxScroll * (yHeight - this._scrollbarHeight)) || 0;
|
|
226
502
|
this._scrollBarHandle.attr('y', scrollBarPosition);
|
|
227
503
|
}
|
|
228
|
-
|
|
504
|
+
_getRecordKey(d, i) {
|
|
229
505
|
var _a;
|
|
230
|
-
|
|
231
|
-
return (_a = max(data, (d, i) => getNumber(d, config.lineWidth, i))) !== null && _a !== void 0 ? _a : 0;
|
|
232
|
-
}
|
|
233
|
-
_getRecordType(d, i) {
|
|
234
|
-
return getString(d, this.config.type) || `__${i}`;
|
|
506
|
+
return getString(d, (_a = this.config.lineRow) !== null && _a !== void 0 ? _a : this.config.type) || `__${i}`;
|
|
235
507
|
}
|
|
236
|
-
|
|
237
|
-
|
|
508
|
+
_getRowLabels(data) {
|
|
509
|
+
const grouped = groupBy(data, (d, i) => { var _a; return getString(d, (_a = this.config.lineRow) !== null && _a !== void 0 ? _a : this.config.type) || `${i + 1}`; });
|
|
510
|
+
const rowLabels = Object.entries(grouped).map(([key, items], i) => {
|
|
511
|
+
var _a, _b, _c, _d, _e;
|
|
512
|
+
const icon = (_b = (_a = this.config).rowIcon) === null || _b === void 0 ? void 0 : _b.call(_a, key, items, i);
|
|
513
|
+
return {
|
|
514
|
+
label: key,
|
|
515
|
+
formattedLabel: (_e = (_d = (_c = this.config).rowLabelFormatter) === null || _d === void 0 ? void 0 : _d.call(_c, key, items, i)) !== null && _e !== void 0 ? _e : key,
|
|
516
|
+
iconHref: icon === null || icon === void 0 ? void 0 : icon.href,
|
|
517
|
+
iconSize: icon === null || icon === void 0 ? void 0 : icon.size,
|
|
518
|
+
iconColor: icon === null || icon === void 0 ? void 0 : icon.color,
|
|
519
|
+
data: items,
|
|
520
|
+
};
|
|
521
|
+
});
|
|
522
|
+
return rowLabels;
|
|
238
523
|
}
|
|
239
524
|
// Override the default XYComponent getXDataExtent method to take into account line lengths
|
|
240
525
|
getXDataExtent() {
|
|
241
526
|
const { config, datamodel } = this;
|
|
242
527
|
const min = getMin(datamodel.data, config.x);
|
|
243
|
-
const max = getMax(datamodel.data, (d, i) => { var _a; return getNumber(d, config.x, i) + ((
|
|
528
|
+
const max = getMax(datamodel.data, (d, i) => { var _a, _b; return getNumber(d, config.x, i) + ((_b = getNumber(d, (_a = config.lineDuration) !== null && _a !== void 0 ? _a : config.length, i)) !== null && _b !== void 0 ? _b : 0); });
|
|
244
529
|
return [min, max];
|
|
245
530
|
}
|
|
246
531
|
}
|