gifted-charts-core 0.0.21 → 0.0.22
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/package.json +12 -4
- package/src/BarChart/Animated2DWithGradient.ts +80 -46
- package/src/BarChart/RenderStackBars.ts +41 -41
- package/src/BarChart/index.ts +293 -275
- package/src/BarChart/types.ts +574 -572
- package/src/LineChart/LineChartBiColor.ts +272 -265
- package/src/LineChart/index.ts +750 -766
- package/src/LineChart/types.ts +592 -584
- package/src/PieChart/index.ts +82 -51
- package/src/PieChart/main.ts +71 -71
- package/src/PieChart/types.ts +83 -83
- package/src/PopulationPyramid/index.ts +39 -39
- package/src/PopulationPyramid/types.ts +195 -196
- package/src/components/AnimatedThreeDBar/{index.tsx → index.ts} +18 -18
- package/src/components/BarAndLineChartsWrapper/getHorizSectionsVals.ts +97 -93
- package/src/components/BarAndLineChartsWrapper/index.ts +94 -90
- package/src/components/common/StripAndLabel.ts +28 -20
- package/src/components/common/types.ts +31 -0
- package/src/utils/constants.ts +90 -90
- package/src/utils/{index.tsx → index.ts} +720 -637
- package/src/utils/types.ts +352 -351
|
@@ -1,595 +1,619 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ColorValue } from 'react-native'
|
|
2
|
+
import {
|
|
3
|
+
type IDataSanitisationProps,
|
|
4
|
+
type lineDataItem
|
|
5
|
+
} from '../LineChart/types'
|
|
2
6
|
import {
|
|
3
7
|
AxesAndRulesDefaults,
|
|
4
8
|
BarDefaults,
|
|
5
9
|
RANGE_ENTER,
|
|
6
10
|
RANGE_EXIT,
|
|
7
11
|
STOP,
|
|
12
|
+
defaultCurvature,
|
|
8
13
|
defaultLineConfig,
|
|
9
|
-
loc
|
|
10
|
-
} from
|
|
14
|
+
loc
|
|
15
|
+
} from './constants'
|
|
11
16
|
import {
|
|
12
|
-
arrowConfigType,
|
|
17
|
+
type arrowConfigType,
|
|
13
18
|
CurveType,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
type HighlightedRange,
|
|
20
|
+
type LineProperties,
|
|
21
|
+
type LineSegment,
|
|
22
|
+
type secondaryYAxisType
|
|
23
|
+
} from './types'
|
|
24
|
+
import {
|
|
25
|
+
type lineConfigType,
|
|
26
|
+
type BarChartPropsType,
|
|
27
|
+
type FocusedBarConfig,
|
|
28
|
+
type barDataItem
|
|
29
|
+
} from '../BarChart/types'
|
|
30
|
+
import { type extendedLineChartPropsType } from '../LineChart'
|
|
31
|
+
import { type extendedBarChartPropsType } from '../BarChart'
|
|
32
|
+
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
34
|
+
const versionString = require('react-native/package.json').version
|
|
35
|
+
|
|
36
|
+
const versionAr = versionString?.split?.('.') ?? ''
|
|
37
|
+
const msb = Number(versionAr[0])
|
|
38
|
+
const mid = Number(versionAr[1])
|
|
39
|
+
const lsb = Number(versionAr[2])
|
|
24
40
|
|
|
25
41
|
export const rnVersion =
|
|
26
42
|
(!isNaN(msb) ? msb : 0) * 1000000 +
|
|
27
43
|
(!isNaN(mid) ? mid : 0) * 10000 +
|
|
28
|
-
(!isNaN(lsb) ? lsb : 0)
|
|
44
|
+
(!isNaN(lsb) ? lsb : 0)
|
|
29
45
|
|
|
30
46
|
export const getCumulativeWidth = (
|
|
31
47
|
data: any,
|
|
32
48
|
index: number,
|
|
33
49
|
spacing: number
|
|
34
|
-
) => {
|
|
35
|
-
let cumWidth = 0
|
|
50
|
+
): number => {
|
|
51
|
+
let cumWidth = 0
|
|
36
52
|
for (let i = 0; i < index; i++) {
|
|
37
|
-
let { barWidth } = data[i]
|
|
38
|
-
barWidth = barWidth
|
|
39
|
-
cumWidth += barWidth + (spacing ?? 20)
|
|
53
|
+
let { barWidth } = data[i]
|
|
54
|
+
barWidth = barWidth ?? 30
|
|
55
|
+
cumWidth += barWidth + (spacing ?? 20)
|
|
40
56
|
}
|
|
41
|
-
return cumWidth
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const getLighterColor = (color:
|
|
45
|
-
let r
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (color.startsWith(
|
|
57
|
+
return cumWidth
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const getLighterColor = (color: string): string => {
|
|
61
|
+
let r
|
|
62
|
+
let g
|
|
63
|
+
let b
|
|
64
|
+
let lighter = '#'
|
|
65
|
+
if (color.startsWith('#')) {
|
|
50
66
|
if (color.length < 7) {
|
|
51
|
-
r = parseInt(color[1], 16)
|
|
52
|
-
g = parseInt(color[2], 16)
|
|
53
|
-
b = parseInt(color[3], 16)
|
|
67
|
+
r = parseInt(color[1], 16)
|
|
68
|
+
g = parseInt(color[2], 16)
|
|
69
|
+
b = parseInt(color[3], 16)
|
|
54
70
|
if (r < 14) {
|
|
55
|
-
r += 2
|
|
56
|
-
lighter += r.toString(16)
|
|
71
|
+
r += 2
|
|
72
|
+
lighter += r.toString(16)
|
|
57
73
|
}
|
|
58
74
|
if (g < 14) {
|
|
59
|
-
g += 2
|
|
60
|
-
lighter += g.toString(16)
|
|
75
|
+
g += 2
|
|
76
|
+
lighter += g.toString(16)
|
|
61
77
|
}
|
|
62
78
|
if (b < 14) {
|
|
63
|
-
b += 2
|
|
64
|
-
lighter += b.toString(16)
|
|
79
|
+
b += 2
|
|
80
|
+
lighter += b.toString(16)
|
|
65
81
|
}
|
|
66
82
|
} else {
|
|
67
|
-
r = parseInt(color[1] + color[2], 16)
|
|
68
|
-
g = parseInt(color[3] + color[4], 16)
|
|
69
|
-
b = parseInt(color[5] + color[6], 16)
|
|
83
|
+
r = parseInt(color[1] + color[2], 16)
|
|
84
|
+
g = parseInt(color[3] + color[4], 16)
|
|
85
|
+
b = parseInt(color[5] + color[6], 16)
|
|
70
86
|
|
|
71
87
|
if (r < 224) {
|
|
72
|
-
r += 32
|
|
73
|
-
lighter += r.toString(16)
|
|
88
|
+
r += 32
|
|
89
|
+
lighter += r.toString(16)
|
|
74
90
|
}
|
|
75
91
|
if (g < 224) {
|
|
76
|
-
g += 32
|
|
77
|
-
lighter += g.toString(16)
|
|
92
|
+
g += 32
|
|
93
|
+
lighter += g.toString(16)
|
|
78
94
|
}
|
|
79
95
|
if (b < 224) {
|
|
80
|
-
b += 32
|
|
81
|
-
lighter += b.toString(16)
|
|
96
|
+
b += 32
|
|
97
|
+
lighter += b.toString(16)
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
100
|
}
|
|
85
|
-
return lighter
|
|
86
|
-
}
|
|
101
|
+
return lighter
|
|
102
|
+
}
|
|
87
103
|
|
|
88
|
-
export const svgQuadraticCurvePath = (points) => {
|
|
89
|
-
let path =
|
|
104
|
+
export const svgQuadraticCurvePath = (points: number[][]): string => {
|
|
105
|
+
let path = 'M' + points[0][0] + ',' + points[0][1]
|
|
90
106
|
|
|
91
107
|
for (let i = 0; i < points.length - 1; i++) {
|
|
92
|
-
const xMid = (points[i][0] + points[i + 1][0]) / 2
|
|
93
|
-
const yMid = (points[i][1] + points[i + 1][1]) / 2
|
|
94
|
-
const cpX1 = (xMid + points[i][0]) / 2
|
|
95
|
-
const cpX2 = (xMid + points[i + 1][0]) / 2
|
|
108
|
+
const xMid = (points[i][0] + points[i + 1][0]) / 2
|
|
109
|
+
const yMid = (points[i][1] + points[i + 1][1]) / 2
|
|
110
|
+
const cpX1 = (xMid + points[i][0]) / 2
|
|
111
|
+
const cpX2 = (xMid + points[i + 1][0]) / 2
|
|
96
112
|
path +=
|
|
97
|
-
|
|
113
|
+
'Q ' +
|
|
98
114
|
cpX1 +
|
|
99
|
-
|
|
115
|
+
', ' +
|
|
100
116
|
points[i][1] +
|
|
101
|
-
|
|
117
|
+
', ' +
|
|
102
118
|
xMid +
|
|
103
|
-
|
|
119
|
+
', ' +
|
|
104
120
|
yMid +
|
|
105
|
-
(
|
|
121
|
+
(' Q ' +
|
|
106
122
|
cpX2 +
|
|
107
|
-
|
|
123
|
+
', ' +
|
|
108
124
|
points[i + 1][1] +
|
|
109
|
-
|
|
125
|
+
', ' +
|
|
110
126
|
points[i + 1][0] +
|
|
111
|
-
|
|
112
|
-
points[i + 1][1])
|
|
127
|
+
', ' +
|
|
128
|
+
points[i + 1][1])
|
|
113
129
|
}
|
|
114
130
|
|
|
115
|
-
return path
|
|
116
|
-
}
|
|
131
|
+
return path
|
|
132
|
+
}
|
|
117
133
|
|
|
118
134
|
export const svgPath = (
|
|
119
|
-
points:
|
|
120
|
-
curveType
|
|
121
|
-
curvature
|
|
122
|
-
) => {
|
|
123
|
-
if (!points?.length) return
|
|
135
|
+
points: number[][],
|
|
136
|
+
curveType?: CurveType,
|
|
137
|
+
curvature?: number
|
|
138
|
+
): string => {
|
|
139
|
+
if (!points?.length) return ''
|
|
124
140
|
if (curveType === CurveType.QUADRATIC) {
|
|
125
|
-
return svgQuadraticCurvePath(points)
|
|
141
|
+
return svgQuadraticCurvePath(points)
|
|
126
142
|
}
|
|
127
143
|
// build the d attributes by looping over the points
|
|
128
144
|
const d = points.reduce(
|
|
129
145
|
(acc, point, i, a) =>
|
|
130
146
|
i === 0
|
|
131
|
-
?
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
147
|
+
? `M${point[0]},${point[1]}`
|
|
148
|
+
: `${acc} ${bezierCommand(point, i, a, curvature ?? defaultCurvature)}`,
|
|
149
|
+
''
|
|
150
|
+
)
|
|
151
|
+
return d
|
|
152
|
+
}
|
|
153
|
+
interface Iline {
|
|
154
|
+
length: number
|
|
155
|
+
angle: number
|
|
156
|
+
}
|
|
157
|
+
const line = (pointA: number[], pointB: number[]): Iline => {
|
|
158
|
+
const lengthX = pointB[0] - pointA[0]
|
|
159
|
+
const lengthY = pointB[1] - pointA[1]
|
|
143
160
|
return {
|
|
144
161
|
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
|
|
145
|
-
angle: Math.atan2(lengthY, lengthX)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
162
|
+
angle: Math.atan2(lengthY, lengthX)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
148
165
|
|
|
149
166
|
const controlPoint = (
|
|
150
167
|
curvature: number,
|
|
151
|
-
current:
|
|
152
|
-
previous:
|
|
153
|
-
next:
|
|
168
|
+
current: number[],
|
|
169
|
+
previous: number[],
|
|
170
|
+
next: number[],
|
|
154
171
|
reverse?: any
|
|
155
|
-
) => {
|
|
172
|
+
): number[] => {
|
|
156
173
|
// When 'current' is the first or last point of the array
|
|
157
174
|
// 'previous' or 'next' don't exist.
|
|
158
175
|
// Replace with 'current'
|
|
159
|
-
const p = previous
|
|
160
|
-
const n = next
|
|
176
|
+
const p = previous ?? current
|
|
177
|
+
const n = next ?? current
|
|
161
178
|
// The smoothing ratio
|
|
162
|
-
const smoothing = curvature
|
|
179
|
+
const smoothing = curvature
|
|
163
180
|
// Properties of the opposed-line
|
|
164
|
-
const o = line(p, n)
|
|
181
|
+
const o = line(p, n)
|
|
165
182
|
// If is end-control-point, add PI to the angle to go backward
|
|
166
|
-
const angle = o.angle + (reverse ? Math.PI : 0)
|
|
167
|
-
const length = o.length * smoothing
|
|
183
|
+
const angle = o.angle + (reverse ? Math.PI : 0)
|
|
184
|
+
const length = o.length * smoothing
|
|
168
185
|
// The control point position is relative to the current point
|
|
169
|
-
const x = current[0] + Math.cos(angle) * length
|
|
170
|
-
const y = current[1] + Math.sin(angle) * length
|
|
171
|
-
return [x, y]
|
|
172
|
-
}
|
|
186
|
+
const x = current[0] + Math.cos(angle) * length
|
|
187
|
+
const y = current[1] + Math.sin(angle) * length
|
|
188
|
+
return [x, y]
|
|
189
|
+
}
|
|
173
190
|
|
|
174
191
|
export const bezierCommand = (
|
|
175
|
-
point:
|
|
192
|
+
point: number[],
|
|
176
193
|
i: number,
|
|
177
|
-
a:
|
|
194
|
+
a: number[][],
|
|
178
195
|
curvature: number
|
|
179
|
-
) => {
|
|
196
|
+
): string => {
|
|
180
197
|
// start control point
|
|
181
|
-
const [cpsX, cpsY] = controlPoint(curvature, a[i - 1], a[i - 2], point)
|
|
198
|
+
const [cpsX, cpsY] = controlPoint(curvature, a[i - 1], a[i - 2], point)
|
|
182
199
|
// end control point
|
|
183
|
-
const [cpeX, cpeY] = controlPoint(curvature, point, a[i - 1], a[i + 1], true)
|
|
184
|
-
return `C${cpsX},${cpsY} ${cpeX},${cpeY} ${point[0]},${point[1]}
|
|
185
|
-
}
|
|
200
|
+
const [cpeX, cpeY] = controlPoint(curvature, point, a[i - 1], a[i + 1], true)
|
|
201
|
+
return `C${cpsX},${cpsY} ${cpeX},${cpeY} ${point[0]},${point[1]}`
|
|
202
|
+
}
|
|
186
203
|
|
|
187
204
|
export const getSegmentString = (
|
|
188
|
-
lineSegment,
|
|
189
|
-
index,
|
|
190
|
-
startDelimeter,
|
|
191
|
-
endDelimeter
|
|
192
|
-
) => {
|
|
193
|
-
const segment = lineSegment?.find((segment) => segment.startIndex === index)
|
|
194
|
-
return segment ? startDelimeter + JSON.stringify(segment) + endDelimeter :
|
|
195
|
-
}
|
|
205
|
+
lineSegment: LineSegment[] | undefined,
|
|
206
|
+
index: number,
|
|
207
|
+
startDelimeter: string,
|
|
208
|
+
endDelimeter: string
|
|
209
|
+
): string => {
|
|
210
|
+
const segment = lineSegment?.find((segment) => segment.startIndex === index)
|
|
211
|
+
return segment ? startDelimeter + JSON.stringify(segment) + endDelimeter : ''
|
|
212
|
+
}
|
|
196
213
|
|
|
197
214
|
export const getCurvePathWithSegments = (
|
|
198
215
|
path: string,
|
|
199
216
|
lineSegment: LineSegment[] | undefined,
|
|
200
|
-
startDelimeter,
|
|
201
|
-
endDelimeter
|
|
202
|
-
) => {
|
|
203
|
-
if (!lineSegment?.length) return path
|
|
204
|
-
let newPath =
|
|
205
|
-
const pathArray = path.split(
|
|
217
|
+
startDelimeter: string,
|
|
218
|
+
endDelimeter: string
|
|
219
|
+
): string => {
|
|
220
|
+
if (!lineSegment?.length) return path
|
|
221
|
+
let newPath = ''
|
|
222
|
+
const pathArray = path.split('C')
|
|
206
223
|
for (let i = 0; i < pathArray.length; i++) {
|
|
207
|
-
const segment = lineSegment?.find((segment) => segment.startIndex === i)
|
|
224
|
+
const segment = lineSegment?.find((segment) => segment.startIndex === i)
|
|
208
225
|
newPath +=
|
|
209
|
-
(pathArray[i].startsWith(
|
|
226
|
+
(pathArray[i].startsWith('M') ? '' : 'C') +
|
|
210
227
|
pathArray[i] +
|
|
211
|
-
(segment ? startDelimeter + JSON.stringify(segment) + endDelimeter :
|
|
228
|
+
(segment ? startDelimeter + JSON.stringify(segment) + endDelimeter : '')
|
|
212
229
|
}
|
|
213
|
-
return newPath
|
|
214
|
-
}
|
|
230
|
+
return newPath
|
|
231
|
+
}
|
|
215
232
|
|
|
216
|
-
export const getPreviousSegmentsLastPoint = (
|
|
233
|
+
export const getPreviousSegmentsLastPoint = (
|
|
234
|
+
isCurved: boolean,
|
|
235
|
+
previousSegment: string
|
|
236
|
+
): string => {
|
|
217
237
|
const prevSegmentLastPoint = isCurved
|
|
218
|
-
? previousSegment.substring(previousSegment.trim().lastIndexOf(
|
|
238
|
+
? previousSegment.substring(previousSegment.trim().lastIndexOf(' '))
|
|
219
239
|
: previousSegment
|
|
220
|
-
|
|
221
|
-
|
|
240
|
+
.substring(previousSegment.lastIndexOf('L'))
|
|
241
|
+
.replace('L', 'M')
|
|
222
242
|
|
|
223
243
|
return (
|
|
224
|
-
(prevSegmentLastPoint.trim()[0] ===
|
|
225
|
-
)
|
|
226
|
-
}
|
|
244
|
+
(prevSegmentLastPoint.trim()[0] === 'M' ? '' : 'M') + prevSegmentLastPoint
|
|
245
|
+
)
|
|
246
|
+
}
|
|
227
247
|
|
|
228
248
|
export const getPathWithHighlight = (
|
|
229
|
-
data,
|
|
230
|
-
i,
|
|
231
|
-
highlightedRange,
|
|
232
|
-
startIndex,
|
|
233
|
-
endIndex,
|
|
234
|
-
getX,
|
|
235
|
-
getY
|
|
236
|
-
) => {
|
|
237
|
-
let path =
|
|
238
|
-
const { from, to } = highlightedRange
|
|
249
|
+
data: lineDataItem[],
|
|
250
|
+
i: number,
|
|
251
|
+
highlightedRange: HighlightedRange,
|
|
252
|
+
startIndex: number,
|
|
253
|
+
endIndex: number,
|
|
254
|
+
getX: (i: number) => number,
|
|
255
|
+
getY: (value: number) => number
|
|
256
|
+
): string => {
|
|
257
|
+
let path = ''
|
|
258
|
+
const { from, to } = highlightedRange
|
|
239
259
|
const currentPointRegion =
|
|
240
|
-
data[i].value < from ? loc.DOWN : data[i].value > to ? loc.UP : loc.IN
|
|
260
|
+
data[i].value < from ? loc.DOWN : data[i].value > to ? loc.UP : loc.IN
|
|
241
261
|
|
|
242
262
|
if (i !== endIndex) {
|
|
243
263
|
const nextPointRegion =
|
|
244
264
|
data[i + 1].value < from
|
|
245
265
|
? loc.DOWN
|
|
246
266
|
: data[i + 1].value > to
|
|
247
|
-
|
|
248
|
-
|
|
267
|
+
? loc.UP
|
|
268
|
+
: loc.IN
|
|
249
269
|
if (
|
|
250
270
|
currentPointRegion !== nextPointRegion ||
|
|
251
271
|
(i === startIndex && currentPointRegion === loc.IN)
|
|
252
272
|
) {
|
|
253
|
-
const x1 = getX(i)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
let m = (y2 - y1) / (x2 - x1)
|
|
259
|
-
|
|
260
|
-
|
|
273
|
+
const x1 = getX(i)
|
|
274
|
+
const y1 = getY(data[i].value)
|
|
275
|
+
const x2 = getX(i + 1)
|
|
276
|
+
const y2 = getY(data[i + 1].value)
|
|
277
|
+
|
|
278
|
+
let m = (y2 - y1) / (x2 - x1)
|
|
279
|
+
let x = 0
|
|
280
|
+
let y = 0
|
|
261
281
|
if (i === startIndex && currentPointRegion === loc.IN) {
|
|
262
282
|
// If the 1st point lies IN
|
|
263
|
-
y = y1
|
|
264
|
-
x = x1
|
|
283
|
+
y = y1
|
|
284
|
+
x = x1
|
|
265
285
|
|
|
266
286
|
path +=
|
|
267
|
-
|
|
287
|
+
'L' +
|
|
268
288
|
x +
|
|
269
|
-
|
|
289
|
+
' ' +
|
|
270
290
|
y +
|
|
271
|
-
|
|
291
|
+
' ' +
|
|
272
292
|
RANGE_ENTER +
|
|
273
293
|
JSON.stringify(highlightedRange) +
|
|
274
|
-
STOP
|
|
294
|
+
STOP
|
|
275
295
|
|
|
276
296
|
if (nextPointRegion === loc.UP) {
|
|
277
|
-
y = getY(to)
|
|
278
|
-
x = (y - y1) / m + x1
|
|
297
|
+
y = getY(to)
|
|
298
|
+
x = (y - y1) / m + x1
|
|
279
299
|
|
|
280
|
-
path +=
|
|
300
|
+
path += 'L' + x + ' ' + y + ' ' + RANGE_EXIT
|
|
281
301
|
} else if (nextPointRegion === loc.DOWN) {
|
|
282
|
-
y = getY(from)
|
|
283
|
-
x = (y - y1) / m + x1
|
|
302
|
+
y = getY(from)
|
|
303
|
+
x = (y - y1) / m + x1
|
|
284
304
|
|
|
285
|
-
path +=
|
|
305
|
+
path += 'L' + x + ' ' + y + ' ' + RANGE_EXIT
|
|
286
306
|
}
|
|
287
307
|
} else if (currentPointRegion !== nextPointRegion) {
|
|
288
308
|
if (currentPointRegion === loc.DOWN && nextPointRegion === loc.UP) {
|
|
289
309
|
// if current point is in DOWN and next point is in UP, then we will add 2 points to the the path
|
|
290
|
-
y = getY(from)
|
|
291
|
-
x = (y - y1) / m + x1
|
|
310
|
+
y = getY(from)
|
|
311
|
+
x = (y - y1) / m + x1
|
|
292
312
|
|
|
293
313
|
path +=
|
|
294
|
-
|
|
314
|
+
'L' +
|
|
295
315
|
x +
|
|
296
|
-
|
|
316
|
+
' ' +
|
|
297
317
|
y +
|
|
298
|
-
|
|
318
|
+
' ' +
|
|
299
319
|
RANGE_ENTER +
|
|
300
320
|
JSON.stringify(highlightedRange) +
|
|
301
|
-
STOP
|
|
302
|
-
y = getY(to)
|
|
303
|
-
x = (y - y1) / m + x1
|
|
321
|
+
STOP
|
|
322
|
+
y = getY(to)
|
|
323
|
+
x = (y - y1) / m + x1
|
|
304
324
|
|
|
305
|
-
path +=
|
|
325
|
+
path += 'L' + x + ' ' + y + ' ' + RANGE_EXIT
|
|
306
326
|
} else if (
|
|
307
327
|
currentPointRegion === loc.UP &&
|
|
308
328
|
nextPointRegion === loc.DOWN
|
|
309
329
|
) {
|
|
310
330
|
// if current point is in UP and next point is in DOWN, then we will add 2 points to the the path
|
|
311
|
-
y = getY(to)
|
|
312
|
-
x = (y - y1) / m + x1
|
|
331
|
+
y = getY(to)
|
|
332
|
+
x = (y - y1) / m + x1
|
|
313
333
|
|
|
314
334
|
path +=
|
|
315
|
-
|
|
335
|
+
'L' +
|
|
316
336
|
x +
|
|
317
|
-
|
|
337
|
+
' ' +
|
|
318
338
|
y +
|
|
319
|
-
|
|
339
|
+
' ' +
|
|
320
340
|
RANGE_ENTER +
|
|
321
341
|
JSON.stringify(highlightedRange) +
|
|
322
|
-
STOP
|
|
323
|
-
y = getY(from)
|
|
324
|
-
x = (y - y1) / m + x1
|
|
342
|
+
STOP
|
|
343
|
+
y = getY(from)
|
|
344
|
+
x = (y - y1) / m + x1
|
|
325
345
|
|
|
326
|
-
path +=
|
|
346
|
+
path += 'L' + x + ' ' + y + ' ' + RANGE_EXIT
|
|
327
347
|
} else {
|
|
328
348
|
if (
|
|
329
349
|
(currentPointRegion === loc.UP && nextPointRegion === loc.IN) ||
|
|
330
350
|
(currentPointRegion === loc.IN && nextPointRegion === loc.UP)
|
|
331
351
|
) {
|
|
332
|
-
y = getY(to)
|
|
352
|
+
y = getY(to)
|
|
333
353
|
} else if (
|
|
334
354
|
(currentPointRegion === loc.IN && nextPointRegion === loc.DOWN) ||
|
|
335
355
|
(currentPointRegion === loc.DOWN && nextPointRegion === loc.IN)
|
|
336
356
|
) {
|
|
337
|
-
y = getY(from)
|
|
357
|
+
y = getY(from)
|
|
338
358
|
}
|
|
339
|
-
m = (y2 - y1) / (x2 - x1)
|
|
340
|
-
x = (y - y1) / m + x1
|
|
359
|
+
m = (y2 - y1) / (x2 - x1)
|
|
360
|
+
x = (y - y1) / m + x1
|
|
341
361
|
|
|
342
362
|
const prefix =
|
|
343
363
|
nextPointRegion === loc.IN
|
|
344
364
|
? RANGE_ENTER + JSON.stringify(highlightedRange) + STOP
|
|
345
|
-
: RANGE_EXIT
|
|
365
|
+
: RANGE_EXIT
|
|
346
366
|
|
|
347
|
-
path +=
|
|
367
|
+
path += 'L' + x + ' ' + y + ' ' + prefix
|
|
348
368
|
}
|
|
349
369
|
}
|
|
350
370
|
}
|
|
351
371
|
} else if (currentPointRegion === loc.IN) {
|
|
352
372
|
// If the last point lies IN, add RANGE_EXIT
|
|
353
|
-
path += RANGE_EXIT
|
|
373
|
+
path += RANGE_EXIT
|
|
354
374
|
}
|
|
355
375
|
|
|
356
|
-
return path
|
|
357
|
-
}
|
|
376
|
+
return path
|
|
377
|
+
}
|
|
358
378
|
|
|
359
379
|
export const getRegionPathObjects = (
|
|
360
|
-
points,
|
|
361
|
-
color,
|
|
362
|
-
currentLineThickness,
|
|
363
|
-
thickness,
|
|
364
|
-
strokeDashArray,
|
|
365
|
-
isCurved,
|
|
366
|
-
startDelimeter,
|
|
367
|
-
stop,
|
|
368
|
-
endDelimeter
|
|
369
|
-
) => {
|
|
370
|
-
const ar: [
|
|
371
|
-
let tempStr = points
|
|
380
|
+
points: string,
|
|
381
|
+
color: ColorValue,
|
|
382
|
+
currentLineThickness: number,
|
|
383
|
+
thickness: number,
|
|
384
|
+
strokeDashArray: number[],
|
|
385
|
+
isCurved: boolean,
|
|
386
|
+
startDelimeter: string,
|
|
387
|
+
stop: string,
|
|
388
|
+
endDelimeter: string
|
|
389
|
+
): LineProperties[] => {
|
|
390
|
+
const ar: [LineProperties] = [{ d: '', color: '', strokeWidth: 0 }]
|
|
391
|
+
let tempStr = points
|
|
372
392
|
|
|
373
393
|
if (!points.startsWith(startDelimeter)) {
|
|
374
|
-
|
|
394
|
+
/** ******************** line upto first segment *****************/
|
|
375
395
|
|
|
376
396
|
const lineSvgProps: LineProperties = {
|
|
377
397
|
d: points.substring(0, points.indexOf(startDelimeter)),
|
|
378
398
|
color,
|
|
379
|
-
strokeWidth: currentLineThickness || thickness
|
|
380
|
-
}
|
|
399
|
+
strokeWidth: currentLineThickness || thickness
|
|
400
|
+
}
|
|
381
401
|
if (strokeDashArray) {
|
|
382
|
-
lineSvgProps.strokeDashArray = strokeDashArray
|
|
402
|
+
lineSvgProps.strokeDashArray = strokeDashArray
|
|
383
403
|
}
|
|
384
|
-
ar.push(lineSvgProps)
|
|
404
|
+
ar.push(lineSvgProps)
|
|
385
405
|
}
|
|
386
406
|
|
|
387
407
|
while (tempStr.includes(startDelimeter)) {
|
|
388
|
-
const startDelimeterIndex = tempStr.indexOf(startDelimeter)
|
|
389
|
-
const stopIndex = tempStr.indexOf(stop)
|
|
390
|
-
const endDelimeterIndex = tempStr.indexOf(endDelimeter)
|
|
408
|
+
const startDelimeterIndex = tempStr.indexOf(startDelimeter)
|
|
409
|
+
const stopIndex = tempStr.indexOf(stop)
|
|
410
|
+
const endDelimeterIndex = tempStr.indexOf(endDelimeter)
|
|
391
411
|
|
|
392
412
|
const segmentConfigString = tempStr.substring(
|
|
393
413
|
startDelimeterIndex + startDelimeter.length,
|
|
394
414
|
stopIndex
|
|
395
|
-
)
|
|
415
|
+
)
|
|
396
416
|
|
|
397
|
-
const segmentConfig = JSON.parse(segmentConfigString)
|
|
417
|
+
const segmentConfig = JSON.parse(segmentConfigString)
|
|
398
418
|
|
|
399
|
-
|
|
419
|
+
const segment = tempStr.substring(
|
|
420
|
+
stopIndex + stop.length,
|
|
421
|
+
endDelimeterIndex
|
|
422
|
+
)
|
|
400
423
|
|
|
401
|
-
const previousSegment = ar[ar.length - 1].d
|
|
424
|
+
const previousSegment = ar[ar.length - 1].d
|
|
402
425
|
const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
|
|
403
426
|
isCurved,
|
|
404
427
|
previousSegment
|
|
405
|
-
)
|
|
428
|
+
)
|
|
406
429
|
|
|
407
|
-
|
|
430
|
+
/** ******************** segment line *****************/
|
|
408
431
|
|
|
409
432
|
const lineSvgProps: LineProperties = {
|
|
410
433
|
d: moveToLastPointOfPreviousSegment + segment,
|
|
411
434
|
color: segmentConfig.color ?? color,
|
|
412
435
|
strokeWidth:
|
|
413
|
-
segmentConfig.thickness ?? (currentLineThickness || thickness)
|
|
414
|
-
}
|
|
436
|
+
segmentConfig.thickness ?? (currentLineThickness || thickness)
|
|
437
|
+
}
|
|
415
438
|
if (segmentConfig.strokeDashArray) {
|
|
416
|
-
lineSvgProps.strokeDashArray = segmentConfig.strokeDashArray
|
|
439
|
+
lineSvgProps.strokeDashArray = segmentConfig.strokeDashArray
|
|
417
440
|
}
|
|
418
|
-
ar.push(lineSvgProps)
|
|
441
|
+
ar.push(lineSvgProps)
|
|
419
442
|
|
|
420
|
-
tempStr = tempStr.substring(endDelimeterIndex + endDelimeter.length)
|
|
443
|
+
tempStr = tempStr.substring(endDelimeterIndex + endDelimeter.length)
|
|
421
444
|
|
|
422
|
-
const nextDelimiterIndex = tempStr.indexOf(startDelimeter)
|
|
423
|
-
const stringUptoNextSegment = tempStr.substring(0, nextDelimiterIndex)
|
|
445
|
+
const nextDelimiterIndex = tempStr.indexOf(startDelimeter)
|
|
446
|
+
const stringUptoNextSegment = tempStr.substring(0, nextDelimiterIndex)
|
|
424
447
|
|
|
425
|
-
|
|
448
|
+
/** ******************** line upto the next segment *****************/
|
|
426
449
|
|
|
427
450
|
if (
|
|
428
451
|
nextDelimiterIndex !== -1 &&
|
|
429
|
-
stringUptoNextSegment.
|
|
452
|
+
stringUptoNextSegment.includes(isCurved ? 'C' : 'L')
|
|
430
453
|
) {
|
|
431
|
-
const previousSegment = ar[ar.length - 1].d
|
|
454
|
+
const previousSegment = ar[ar.length - 1].d
|
|
432
455
|
const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
|
|
433
456
|
isCurved,
|
|
434
457
|
previousSegment
|
|
435
|
-
)
|
|
458
|
+
)
|
|
436
459
|
const lineSvgProps: LineProperties = {
|
|
437
|
-
d: moveToLastPointOfPreviousSegment +
|
|
460
|
+
d: moveToLastPointOfPreviousSegment + ' ' + stringUptoNextSegment,
|
|
438
461
|
color,
|
|
439
|
-
strokeWidth: currentLineThickness || thickness
|
|
440
|
-
}
|
|
462
|
+
strokeWidth: currentLineThickness || thickness
|
|
463
|
+
}
|
|
441
464
|
if (strokeDashArray) {
|
|
442
|
-
lineSvgProps.strokeDashArray = strokeDashArray
|
|
465
|
+
lineSvgProps.strokeDashArray = strokeDashArray
|
|
443
466
|
}
|
|
444
|
-
ar.push(lineSvgProps)
|
|
467
|
+
ar.push(lineSvgProps)
|
|
445
468
|
}
|
|
446
469
|
}
|
|
447
470
|
|
|
448
|
-
|
|
471
|
+
/** ******************** line after the last segment *****************/
|
|
449
472
|
|
|
450
473
|
if (tempStr.length) {
|
|
451
|
-
const previousSegment = ar[ar.length - 1].d
|
|
474
|
+
const previousSegment = ar[ar.length - 1].d
|
|
452
475
|
const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
|
|
453
476
|
isCurved,
|
|
454
477
|
previousSegment
|
|
455
|
-
)
|
|
478
|
+
)
|
|
456
479
|
const lineSvgProps: LineProperties = {
|
|
457
480
|
d: moveToLastPointOfPreviousSegment + tempStr,
|
|
458
481
|
color,
|
|
459
|
-
strokeWidth: currentLineThickness || thickness
|
|
460
|
-
}
|
|
482
|
+
strokeWidth: currentLineThickness || thickness
|
|
483
|
+
}
|
|
461
484
|
if (strokeDashArray) {
|
|
462
|
-
lineSvgProps.strokeDashArray = strokeDashArray
|
|
485
|
+
lineSvgProps.strokeDashArray = strokeDashArray
|
|
463
486
|
}
|
|
464
|
-
ar.push(lineSvgProps)
|
|
487
|
+
ar.push(lineSvgProps)
|
|
465
488
|
}
|
|
466
489
|
|
|
467
|
-
ar.shift()
|
|
468
|
-
return ar
|
|
469
|
-
}
|
|
490
|
+
ar.shift()
|
|
491
|
+
return ar
|
|
492
|
+
}
|
|
470
493
|
|
|
471
494
|
export const getSegmentedPathObjects = (
|
|
472
|
-
points,
|
|
473
|
-
color,
|
|
474
|
-
currentLineThickness,
|
|
475
|
-
thickness,
|
|
476
|
-
strokeDashArray,
|
|
477
|
-
isCurved,
|
|
478
|
-
startDelimeter,
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
495
|
+
points: string,
|
|
496
|
+
color: ColorValue,
|
|
497
|
+
currentLineThickness: number,
|
|
498
|
+
thickness: number,
|
|
499
|
+
strokeDashArray: number[],
|
|
500
|
+
isCurved: boolean,
|
|
501
|
+
startDelimeter: string,
|
|
502
|
+
stop: string,
|
|
503
|
+
endDelimeter: string
|
|
504
|
+
): LineProperties[] => {
|
|
505
|
+
const ar: [LineProperties] = [{ d: '', color: '', strokeWidth: 0 }]
|
|
506
|
+
let tempStr = points
|
|
483
507
|
|
|
484
508
|
if (!points.startsWith(startDelimeter)) {
|
|
485
|
-
|
|
509
|
+
/** ******************** line upto first segment *****************/
|
|
486
510
|
|
|
487
511
|
const lineSvgProps: LineProperties = {
|
|
488
512
|
d: points.substring(0, points.indexOf(startDelimeter)),
|
|
489
513
|
color,
|
|
490
|
-
strokeWidth: currentLineThickness || thickness
|
|
491
|
-
}
|
|
514
|
+
strokeWidth: currentLineThickness || thickness
|
|
515
|
+
}
|
|
492
516
|
if (strokeDashArray) {
|
|
493
|
-
lineSvgProps.strokeDashArray = strokeDashArray
|
|
517
|
+
lineSvgProps.strokeDashArray = strokeDashArray
|
|
494
518
|
}
|
|
495
|
-
ar.push(lineSvgProps)
|
|
519
|
+
ar.push(lineSvgProps)
|
|
496
520
|
}
|
|
497
521
|
|
|
498
522
|
while (tempStr.includes(startDelimeter)) {
|
|
499
|
-
const startDelimeterIndex = tempStr.indexOf(startDelimeter)
|
|
500
|
-
const endDelimeterIndex = tempStr.indexOf(endDelimeter)
|
|
523
|
+
const startDelimeterIndex = tempStr.indexOf(startDelimeter)
|
|
524
|
+
const endDelimeterIndex = tempStr.indexOf(endDelimeter)
|
|
501
525
|
|
|
502
526
|
const segmentConfigString = tempStr.substring(
|
|
503
527
|
startDelimeterIndex + startDelimeter.length,
|
|
504
528
|
endDelimeterIndex
|
|
505
|
-
)
|
|
529
|
+
)
|
|
506
530
|
|
|
507
|
-
const segmentConfig = JSON.parse(segmentConfigString)
|
|
531
|
+
const segmentConfig = JSON.parse(segmentConfigString)
|
|
508
532
|
|
|
509
|
-
const { startIndex, endIndex } = segmentConfig
|
|
510
|
-
const segmentLength = endIndex - startIndex
|
|
511
|
-
let segment = tempStr.substring(endDelimeterIndex + endDelimeter.length)
|
|
512
|
-
let c = 0
|
|
513
|
-
|
|
514
|
-
|
|
533
|
+
const { startIndex, endIndex } = segmentConfig
|
|
534
|
+
const segmentLength = endIndex - startIndex
|
|
535
|
+
let segment = tempStr.substring(endDelimeterIndex + endDelimeter.length)
|
|
536
|
+
let c = 0
|
|
537
|
+
let s = 0
|
|
538
|
+
let i
|
|
515
539
|
for (i = 0; i < segment.length; i++) {
|
|
516
|
-
if (segment[i] === (isCurved ?
|
|
540
|
+
if (segment[i] === (isCurved ? 'C' : 'L')) c++
|
|
517
541
|
if (c === segmentLength) {
|
|
518
|
-
if (segment[i] ===
|
|
519
|
-
if (s === (isCurved ? 3 : 2)) break
|
|
542
|
+
if (segment[i] === ' ') s++
|
|
543
|
+
if (s === (isCurved ? 3 : 2)) break
|
|
520
544
|
}
|
|
521
545
|
}
|
|
522
|
-
segment = segment.substring(0, i)
|
|
546
|
+
segment = segment.substring(0, i)
|
|
523
547
|
|
|
524
|
-
const previousSegment = ar[ar.length - 1].d
|
|
548
|
+
const previousSegment = ar[ar.length - 1].d
|
|
525
549
|
const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
|
|
526
550
|
isCurved,
|
|
527
551
|
previousSegment
|
|
528
|
-
)
|
|
552
|
+
)
|
|
529
553
|
|
|
530
|
-
|
|
554
|
+
/** ******************** segment line *****************/
|
|
531
555
|
|
|
532
556
|
const lineSvgProps: LineProperties = {
|
|
533
557
|
d: moveToLastPointOfPreviousSegment + segment,
|
|
534
558
|
color: segmentConfig.color ?? color,
|
|
535
559
|
strokeWidth:
|
|
536
|
-
segmentConfig.thickness ?? (currentLineThickness || thickness)
|
|
537
|
-
}
|
|
560
|
+
segmentConfig.thickness ?? (currentLineThickness || thickness)
|
|
561
|
+
}
|
|
538
562
|
if (segmentConfig.strokeDashArray) {
|
|
539
|
-
lineSvgProps.strokeDashArray = segmentConfig.strokeDashArray
|
|
563
|
+
lineSvgProps.strokeDashArray = segmentConfig.strokeDashArray
|
|
540
564
|
}
|
|
541
|
-
ar.push(lineSvgProps)
|
|
565
|
+
ar.push(lineSvgProps)
|
|
542
566
|
|
|
543
|
-
tempStr = tempStr.substring(endDelimeterIndex + endDelimeter.length + i)
|
|
567
|
+
tempStr = tempStr.substring(endDelimeterIndex + endDelimeter.length + i)
|
|
544
568
|
|
|
545
|
-
const nextDelimiterIndex = tempStr.indexOf(startDelimeter)
|
|
546
|
-
const stringUptoNextSegment = tempStr.substring(0, nextDelimiterIndex)
|
|
569
|
+
const nextDelimiterIndex = tempStr.indexOf(startDelimeter)
|
|
570
|
+
const stringUptoNextSegment = tempStr.substring(0, nextDelimiterIndex)
|
|
547
571
|
|
|
548
|
-
|
|
572
|
+
/** ******************** line upto the next segment *****************/
|
|
549
573
|
|
|
550
574
|
if (
|
|
551
575
|
nextDelimiterIndex !== -1 &&
|
|
552
|
-
stringUptoNextSegment.
|
|
576
|
+
stringUptoNextSegment.includes(isCurved ? 'C' : 'L')
|
|
553
577
|
) {
|
|
554
|
-
const previousSegment = ar[ar.length - 1].d
|
|
578
|
+
const previousSegment = ar[ar.length - 1].d
|
|
555
579
|
const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
|
|
556
580
|
isCurved,
|
|
557
581
|
previousSegment
|
|
558
|
-
)
|
|
582
|
+
)
|
|
559
583
|
const lineSvgProps: LineProperties = {
|
|
560
|
-
d: moveToLastPointOfPreviousSegment +
|
|
584
|
+
d: moveToLastPointOfPreviousSegment + ' ' + stringUptoNextSegment,
|
|
561
585
|
color,
|
|
562
|
-
strokeWidth: currentLineThickness || thickness
|
|
563
|
-
}
|
|
586
|
+
strokeWidth: currentLineThickness || thickness
|
|
587
|
+
}
|
|
564
588
|
if (strokeDashArray) {
|
|
565
|
-
lineSvgProps.strokeDashArray = strokeDashArray
|
|
589
|
+
lineSvgProps.strokeDashArray = strokeDashArray
|
|
566
590
|
}
|
|
567
|
-
ar.push(lineSvgProps)
|
|
591
|
+
ar.push(lineSvgProps)
|
|
568
592
|
}
|
|
569
593
|
}
|
|
570
594
|
|
|
571
|
-
|
|
595
|
+
/** ******************** line after the last segment *****************/
|
|
572
596
|
|
|
573
597
|
if (tempStr.length) {
|
|
574
|
-
const previousSegment = ar[ar.length - 1].d
|
|
598
|
+
const previousSegment = ar[ar.length - 1].d
|
|
575
599
|
const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
|
|
576
600
|
isCurved,
|
|
577
601
|
previousSegment
|
|
578
|
-
)
|
|
602
|
+
)
|
|
579
603
|
const lineSvgProps: LineProperties = {
|
|
580
604
|
d: moveToLastPointOfPreviousSegment + tempStr,
|
|
581
605
|
color,
|
|
582
|
-
strokeWidth: currentLineThickness || thickness
|
|
583
|
-
}
|
|
606
|
+
strokeWidth: currentLineThickness || thickness
|
|
607
|
+
}
|
|
584
608
|
if (strokeDashArray) {
|
|
585
|
-
lineSvgProps.strokeDashArray = strokeDashArray
|
|
609
|
+
lineSvgProps.strokeDashArray = strokeDashArray
|
|
586
610
|
}
|
|
587
|
-
ar.push(lineSvgProps)
|
|
611
|
+
ar.push(lineSvgProps)
|
|
588
612
|
}
|
|
589
613
|
|
|
590
|
-
ar.shift()
|
|
591
|
-
return ar
|
|
592
|
-
}
|
|
614
|
+
ar.shift()
|
|
615
|
+
return ar
|
|
616
|
+
}
|
|
593
617
|
|
|
594
618
|
export const getArrowPoints = (
|
|
595
619
|
arrowTipX: number,
|
|
@@ -599,49 +623,52 @@ export const getArrowPoints = (
|
|
|
599
623
|
arrowLength?: number,
|
|
600
624
|
arrowWidth?: number,
|
|
601
625
|
showArrowBase?: boolean
|
|
602
|
-
) => {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
arrowTipX - Math.sqrt((d * d) / (dataLineSlope * dataLineSlope + 1))
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
let arrowBasex1, arrowBaseY1, arrowBaseX2, arrowBaseY2
|
|
626
|
+
): string => {
|
|
627
|
+
const dataLineSlope = (arrowTipY - y1) / (arrowTipX - x1)
|
|
628
|
+
const d = arrowLength ?? 0
|
|
629
|
+
const d2 = (arrowWidth ?? 0) / 2
|
|
630
|
+
const interSectionX =
|
|
631
|
+
arrowTipX - Math.sqrt((d * d) / (dataLineSlope * dataLineSlope + 1))
|
|
632
|
+
const interSectionY = arrowTipY - dataLineSlope * (arrowTipX - interSectionX)
|
|
633
|
+
|
|
634
|
+
let arrowBasex1, arrowBaseY1, arrowBaseX2, arrowBaseY2
|
|
611
635
|
if (dataLineSlope === 0) {
|
|
612
|
-
arrowBasex1 = interSectionX
|
|
613
|
-
arrowBaseY1 = interSectionY - d2
|
|
614
|
-
arrowBaseX2 = interSectionX
|
|
615
|
-
arrowBaseY2 = interSectionY + d2
|
|
636
|
+
arrowBasex1 = interSectionX
|
|
637
|
+
arrowBaseY1 = interSectionY - d2
|
|
638
|
+
arrowBaseX2 = interSectionX
|
|
639
|
+
arrowBaseY2 = interSectionY + d2
|
|
616
640
|
} else {
|
|
617
|
-
|
|
641
|
+
const arrowBaseSlope = -1 / dataLineSlope
|
|
618
642
|
arrowBasex1 =
|
|
619
643
|
interSectionX -
|
|
620
|
-
Math.sqrt((d2 * d2) / (arrowBaseSlope * arrowBaseSlope + 1))
|
|
621
|
-
arrowBaseY1 =
|
|
622
|
-
interSectionY - arrowBaseSlope * (interSectionX - arrowBasex1);
|
|
644
|
+
Math.sqrt((d2 * d2) / (arrowBaseSlope * arrowBaseSlope + 1))
|
|
645
|
+
arrowBaseY1 = interSectionY - arrowBaseSlope * (interSectionX - arrowBasex1)
|
|
623
646
|
|
|
624
647
|
arrowBaseX2 =
|
|
625
648
|
interSectionX +
|
|
626
|
-
Math.sqrt((d2 * d2) / (arrowBaseSlope * arrowBaseSlope + 1))
|
|
627
|
-
arrowBaseY2 =
|
|
628
|
-
interSectionY + arrowBaseSlope * (interSectionX - arrowBasex1);
|
|
649
|
+
Math.sqrt((d2 * d2) / (arrowBaseSlope * arrowBaseSlope + 1))
|
|
650
|
+
arrowBaseY2 = interSectionY + arrowBaseSlope * (interSectionX - arrowBasex1)
|
|
629
651
|
}
|
|
630
|
-
let arrowPoints = ` M${interSectionX} ${interSectionY}
|
|
631
|
-
arrowPoints += ` ${showArrowBase ?
|
|
632
|
-
arrowPoints += ` L${arrowTipX} ${arrowTipY}
|
|
633
|
-
arrowPoints += ` M${interSectionX} ${interSectionY}
|
|
634
|
-
arrowPoints += ` ${showArrowBase ?
|
|
635
|
-
arrowPoints += ` L${arrowTipX} ${arrowTipY}
|
|
652
|
+
let arrowPoints = ` M${interSectionX} ${interSectionY}`
|
|
653
|
+
arrowPoints += ` ${showArrowBase ? 'L' : 'M'}${arrowBasex1} ${arrowBaseY1}`
|
|
654
|
+
arrowPoints += ` L${arrowTipX} ${arrowTipY}`
|
|
655
|
+
arrowPoints += ` M${interSectionX} ${interSectionY}`
|
|
656
|
+
arrowPoints += ` ${showArrowBase ? 'L' : 'M'}${arrowBaseX2} ${arrowBaseY2}`
|
|
657
|
+
arrowPoints += ` L${arrowTipX} ${arrowTipY}`
|
|
658
|
+
|
|
659
|
+
return arrowPoints
|
|
660
|
+
}
|
|
636
661
|
|
|
637
|
-
|
|
638
|
-
|
|
662
|
+
interface IgetAxesAndRulesProps extends BarChartPropsType {
|
|
663
|
+
verticalLinesUptoDataPoint?: boolean
|
|
664
|
+
secondaryYAxis?: secondaryYAxisType
|
|
665
|
+
}
|
|
639
666
|
|
|
640
667
|
export const getAxesAndRulesProps = (
|
|
641
|
-
props:
|
|
668
|
+
props: extendedBarChartPropsType,
|
|
642
669
|
stepValue: number,
|
|
643
670
|
maxValue?: number
|
|
644
|
-
) => {
|
|
671
|
+
): IgetAxesAndRulesProps => {
|
|
645
672
|
const axesAndRulesProps = {
|
|
646
673
|
yAxisSide: props.yAxisSide,
|
|
647
674
|
yAxisLabelContainerStyle: props.yAxisLabelContainerStyle,
|
|
@@ -686,7 +713,7 @@ export const getAxesAndRulesProps = (
|
|
|
686
713
|
showReferenceLine3: props.showReferenceLine3,
|
|
687
714
|
referenceLine3Position: props.referenceLine3Position,
|
|
688
715
|
referenceLine3Config: props.referenceLine3Config,
|
|
689
|
-
referenceLinesOverChartContent: props.referenceLinesOverChartContent
|
|
716
|
+
referenceLinesOverChartContent: props.referenceLinesOverChartContent
|
|
690
717
|
},
|
|
691
718
|
|
|
692
719
|
showVerticalLines: props.showVerticalLines,
|
|
@@ -698,223 +725,263 @@ export const getAxesAndRulesProps = (
|
|
|
698
725
|
verticalLinesSpacing: props.verticalLinesSpacing,
|
|
699
726
|
noOfVerticalLines: props.noOfVerticalLines,
|
|
700
727
|
|
|
701
|
-
//specific to Line charts-
|
|
728
|
+
// specific to Line charts-
|
|
702
729
|
verticalLinesUptoDataPoint: props.verticalLinesUptoDataPoint,
|
|
703
730
|
|
|
704
731
|
roundToDigits: props.roundToDigits,
|
|
705
732
|
stepValue,
|
|
706
733
|
|
|
707
734
|
secondaryYAxis: props.secondaryYAxis,
|
|
708
|
-
formatYLabel: props.formatYLabel
|
|
709
|
-
}
|
|
735
|
+
formatYLabel: props.formatYLabel
|
|
736
|
+
}
|
|
710
737
|
if (
|
|
711
|
-
(props.secondaryYAxis
|
|
738
|
+
(props.secondaryYAxis ?? props.lineConfig?.isSecondary) &&
|
|
712
739
|
maxValue !== undefined
|
|
713
740
|
) {
|
|
714
|
-
axesAndRulesProps.secondaryYAxis = { ...props.secondaryYAxis, maxValue }
|
|
741
|
+
axesAndRulesProps.secondaryYAxis = { ...props.secondaryYAxis, maxValue }
|
|
715
742
|
}
|
|
716
743
|
|
|
717
|
-
return axesAndRulesProps
|
|
718
|
-
}
|
|
744
|
+
return axesAndRulesProps
|
|
745
|
+
}
|
|
719
746
|
|
|
720
747
|
export const getExtendedContainerHeightWithPadding = (
|
|
721
748
|
containerHeight: number,
|
|
722
749
|
overflowTop?: number
|
|
723
|
-
) => containerHeight + (overflowTop ?? 0) + 10
|
|
750
|
+
): number => containerHeight + (overflowTop ?? 0) + 10
|
|
724
751
|
|
|
725
752
|
export const getSecondaryDataWithOffsetIncluded = (
|
|
726
|
-
secondaryData?:
|
|
727
|
-
secondaryYAxis?: any,
|
|
753
|
+
secondaryData?: barDataItem[] | lineDataItem[],
|
|
754
|
+
secondaryYAxis?: any | undefined,
|
|
728
755
|
showDataPointsForMissingValues?: boolean,
|
|
729
756
|
interpolateMissingValues?: boolean,
|
|
730
757
|
onlyPositive?: boolean
|
|
731
|
-
) => {
|
|
732
|
-
if (!secondaryData) return secondaryData
|
|
758
|
+
): barDataItem[] | lineDataItem[] | undefined => {
|
|
759
|
+
if (!secondaryData) return secondaryData
|
|
733
760
|
const nullishHandledData = getInterpolatedData(
|
|
734
761
|
secondaryData,
|
|
735
762
|
showDataPointsForMissingValues,
|
|
736
763
|
interpolateMissingValues,
|
|
737
764
|
onlyPositive
|
|
738
|
-
)
|
|
765
|
+
)
|
|
739
766
|
if (secondaryYAxis?.yAxisOffset) {
|
|
740
767
|
return nullishHandledData.map((item) => {
|
|
741
|
-
item.value = item.value - (secondaryYAxis?.yAxisOffset ?? 0)
|
|
742
|
-
return item
|
|
743
|
-
})
|
|
768
|
+
item.value = item.value - (secondaryYAxis?.yAxisOffset ?? 0)
|
|
769
|
+
return item
|
|
770
|
+
})
|
|
744
771
|
}
|
|
745
|
-
return nullishHandledData
|
|
746
|
-
}
|
|
772
|
+
return nullishHandledData
|
|
773
|
+
}
|
|
747
774
|
|
|
748
775
|
export const getArrowProperty = (
|
|
749
776
|
property: string,
|
|
750
777
|
count: number,
|
|
751
|
-
props:
|
|
778
|
+
props: extendedLineChartPropsType,
|
|
752
779
|
defaultArrowConfig: arrowConfigType
|
|
753
|
-
) => {
|
|
780
|
+
): any => {
|
|
781
|
+
const arrowNumber = `arrowConfig${count}` as keyof extendedLineChartPropsType
|
|
754
782
|
return (
|
|
755
|
-
props[
|
|
756
|
-
props[
|
|
757
|
-
defaultArrowConfig[
|
|
758
|
-
)
|
|
759
|
-
}
|
|
783
|
+
props[arrowNumber]?.[property] ??
|
|
784
|
+
props['arrowConfig' as keyof extendedLineChartPropsType]?.[property] ??
|
|
785
|
+
defaultArrowConfig[property as keyof arrowConfigType]
|
|
786
|
+
)
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
interface IgetAllArrowProperties {
|
|
790
|
+
arrowLength1: number
|
|
791
|
+
arrowWidth1: number
|
|
792
|
+
arrowStrokeWidth1: number
|
|
793
|
+
arrowStrokeColor1: ColorValue
|
|
794
|
+
arrowFillColor1: ColorValue
|
|
795
|
+
showArrowBase1: boolean
|
|
796
|
+
arrowLength2: number
|
|
797
|
+
arrowWidth2: number
|
|
798
|
+
arrowStrokeWidth2: number
|
|
799
|
+
arrowStrokeColor2: ColorValue
|
|
800
|
+
arrowFillColor2: ColorValue
|
|
801
|
+
showArrowBase2: boolean
|
|
802
|
+
arrowLength3: number
|
|
803
|
+
arrowWidth3: number
|
|
804
|
+
arrowStrokeWidth3: number
|
|
805
|
+
arrowStrokeColor3: ColorValue
|
|
806
|
+
arrowFillColor3: ColorValue
|
|
807
|
+
showArrowBase3: boolean
|
|
808
|
+
arrowLength4: number
|
|
809
|
+
arrowWidth4: number
|
|
810
|
+
arrowStrokeWidth4: number
|
|
811
|
+
arrowStrokeColor4: ColorValue
|
|
812
|
+
arrowFillColor4: ColorValue
|
|
813
|
+
showArrowBase4: boolean
|
|
814
|
+
arrowLength5: number
|
|
815
|
+
arrowWidth5: number
|
|
816
|
+
arrowStrokeWidth5: number
|
|
817
|
+
arrowStrokeColor5: ColorValue
|
|
818
|
+
arrowFillColor5: ColorValue
|
|
819
|
+
showArrowBase5: boolean
|
|
820
|
+
arrowLengthsFromSet?: number[]
|
|
821
|
+
arrowWidthsFromSet?: number[]
|
|
822
|
+
arrowStrokeWidthsFromSet?: number[]
|
|
823
|
+
arrowStrokeColorsFromSet?: ColorValue[]
|
|
824
|
+
arrowFillColorsFromSet?: ColorValue[]
|
|
825
|
+
showArrowBasesFromSet?: boolean[]
|
|
826
|
+
}
|
|
760
827
|
|
|
761
828
|
export const getAllArrowProperties = (
|
|
762
|
-
props:
|
|
829
|
+
props: extendedLineChartPropsType,
|
|
763
830
|
defaultArrowConfig: arrowConfigType
|
|
764
|
-
) => {
|
|
765
|
-
const arrowLength1 = getArrowProperty(
|
|
766
|
-
const arrowWidth1 = getArrowProperty(
|
|
831
|
+
): IgetAllArrowProperties => {
|
|
832
|
+
const arrowLength1 = getArrowProperty('length', 1, props, defaultArrowConfig)
|
|
833
|
+
const arrowWidth1 = getArrowProperty('width', 1, props, defaultArrowConfig)
|
|
767
834
|
const arrowStrokeWidth1 = getArrowProperty(
|
|
768
|
-
|
|
835
|
+
'strokeWidth',
|
|
769
836
|
1,
|
|
770
837
|
props,
|
|
771
838
|
defaultArrowConfig
|
|
772
|
-
)
|
|
839
|
+
)
|
|
773
840
|
const arrowStrokeColor1 = getArrowProperty(
|
|
774
|
-
|
|
841
|
+
'strokeColor',
|
|
775
842
|
1,
|
|
776
843
|
props,
|
|
777
844
|
defaultArrowConfig
|
|
778
|
-
)
|
|
845
|
+
)
|
|
779
846
|
const arrowFillColor1 = getArrowProperty(
|
|
780
|
-
|
|
847
|
+
'fillColor',
|
|
781
848
|
1,
|
|
782
849
|
props,
|
|
783
850
|
defaultArrowConfig
|
|
784
|
-
)
|
|
851
|
+
)
|
|
785
852
|
const showArrowBase1 = getArrowProperty(
|
|
786
|
-
|
|
853
|
+
'showArrowBase',
|
|
787
854
|
1,
|
|
788
855
|
props,
|
|
789
856
|
defaultArrowConfig
|
|
790
|
-
)
|
|
857
|
+
)
|
|
791
858
|
|
|
792
|
-
const arrowLength2 = getArrowProperty(
|
|
793
|
-
const arrowWidth2 = getArrowProperty(
|
|
859
|
+
const arrowLength2 = getArrowProperty('length', 2, props, defaultArrowConfig)
|
|
860
|
+
const arrowWidth2 = getArrowProperty('width', 2, props, defaultArrowConfig)
|
|
794
861
|
const arrowStrokeWidth2 = getArrowProperty(
|
|
795
|
-
|
|
862
|
+
'strokeWidth',
|
|
796
863
|
2,
|
|
797
864
|
props,
|
|
798
865
|
defaultArrowConfig
|
|
799
|
-
)
|
|
866
|
+
)
|
|
800
867
|
const arrowStrokeColor2 = getArrowProperty(
|
|
801
|
-
|
|
868
|
+
'strokeColor',
|
|
802
869
|
2,
|
|
803
870
|
props,
|
|
804
871
|
defaultArrowConfig
|
|
805
|
-
)
|
|
872
|
+
)
|
|
806
873
|
const arrowFillColor2 = getArrowProperty(
|
|
807
|
-
|
|
874
|
+
'fillColor',
|
|
808
875
|
2,
|
|
809
876
|
props,
|
|
810
877
|
defaultArrowConfig
|
|
811
|
-
)
|
|
878
|
+
)
|
|
812
879
|
const showArrowBase2 = getArrowProperty(
|
|
813
|
-
|
|
880
|
+
'showArrowBase',
|
|
814
881
|
2,
|
|
815
882
|
props,
|
|
816
883
|
defaultArrowConfig
|
|
817
|
-
)
|
|
884
|
+
)
|
|
818
885
|
|
|
819
|
-
const arrowLength3 = getArrowProperty(
|
|
820
|
-
const arrowWidth3 = getArrowProperty(
|
|
886
|
+
const arrowLength3 = getArrowProperty('length', 3, props, defaultArrowConfig)
|
|
887
|
+
const arrowWidth3 = getArrowProperty('width', 3, props, defaultArrowConfig)
|
|
821
888
|
const arrowStrokeWidth3 = getArrowProperty(
|
|
822
|
-
|
|
889
|
+
'strokeWidth',
|
|
823
890
|
3,
|
|
824
891
|
props,
|
|
825
892
|
defaultArrowConfig
|
|
826
|
-
)
|
|
893
|
+
)
|
|
827
894
|
const arrowStrokeColor3 = getArrowProperty(
|
|
828
|
-
|
|
895
|
+
'strokeColor',
|
|
829
896
|
3,
|
|
830
897
|
props,
|
|
831
898
|
defaultArrowConfig
|
|
832
|
-
)
|
|
899
|
+
)
|
|
833
900
|
const arrowFillColor3 = getArrowProperty(
|
|
834
|
-
|
|
901
|
+
'fillColor',
|
|
835
902
|
3,
|
|
836
903
|
props,
|
|
837
904
|
defaultArrowConfig
|
|
838
|
-
)
|
|
905
|
+
)
|
|
839
906
|
const showArrowBase3 = getArrowProperty(
|
|
840
|
-
|
|
907
|
+
'showArrowBase',
|
|
841
908
|
3,
|
|
842
909
|
props,
|
|
843
910
|
defaultArrowConfig
|
|
844
|
-
)
|
|
911
|
+
)
|
|
845
912
|
|
|
846
|
-
const arrowLength4 = getArrowProperty(
|
|
847
|
-
const arrowWidth4 = getArrowProperty(
|
|
913
|
+
const arrowLength4 = getArrowProperty('length', 4, props, defaultArrowConfig)
|
|
914
|
+
const arrowWidth4 = getArrowProperty('width', 4, props, defaultArrowConfig)
|
|
848
915
|
const arrowStrokeWidth4 = getArrowProperty(
|
|
849
|
-
|
|
916
|
+
'strokeWidth',
|
|
850
917
|
4,
|
|
851
918
|
props,
|
|
852
919
|
defaultArrowConfig
|
|
853
|
-
)
|
|
920
|
+
)
|
|
854
921
|
const arrowStrokeColor4 = getArrowProperty(
|
|
855
|
-
|
|
922
|
+
'strokeColor',
|
|
856
923
|
4,
|
|
857
924
|
props,
|
|
858
925
|
defaultArrowConfig
|
|
859
|
-
)
|
|
926
|
+
)
|
|
860
927
|
const arrowFillColor4 = getArrowProperty(
|
|
861
|
-
|
|
928
|
+
'fillColor',
|
|
862
929
|
4,
|
|
863
930
|
props,
|
|
864
931
|
defaultArrowConfig
|
|
865
|
-
)
|
|
932
|
+
)
|
|
866
933
|
const showArrowBase4 = getArrowProperty(
|
|
867
|
-
|
|
934
|
+
'showArrowBase',
|
|
868
935
|
4,
|
|
869
936
|
props,
|
|
870
937
|
defaultArrowConfig
|
|
871
|
-
)
|
|
938
|
+
)
|
|
872
939
|
|
|
873
|
-
const arrowLength5 = getArrowProperty(
|
|
874
|
-
const arrowWidth5 = getArrowProperty(
|
|
940
|
+
const arrowLength5 = getArrowProperty('length', 5, props, defaultArrowConfig)
|
|
941
|
+
const arrowWidth5 = getArrowProperty('width', 5, props, defaultArrowConfig)
|
|
875
942
|
const arrowStrokeWidth5 = getArrowProperty(
|
|
876
|
-
|
|
943
|
+
'strokeWidth',
|
|
877
944
|
5,
|
|
878
945
|
props,
|
|
879
946
|
defaultArrowConfig
|
|
880
|
-
)
|
|
947
|
+
)
|
|
881
948
|
const arrowStrokeColor5 = getArrowProperty(
|
|
882
|
-
|
|
949
|
+
'strokeColor',
|
|
883
950
|
5,
|
|
884
951
|
props,
|
|
885
952
|
defaultArrowConfig
|
|
886
|
-
)
|
|
953
|
+
)
|
|
887
954
|
const arrowFillColor5 = getArrowProperty(
|
|
888
|
-
|
|
955
|
+
'fillColor',
|
|
889
956
|
5,
|
|
890
957
|
props,
|
|
891
958
|
defaultArrowConfig
|
|
892
|
-
)
|
|
959
|
+
)
|
|
893
960
|
const showArrowBase5 = getArrowProperty(
|
|
894
|
-
|
|
961
|
+
'showArrowBase',
|
|
895
962
|
5,
|
|
896
963
|
props,
|
|
897
964
|
defaultArrowConfig
|
|
898
|
-
)
|
|
965
|
+
)
|
|
899
966
|
|
|
900
967
|
const arrowLengthsFromSet = props.dataSet?.map(
|
|
901
968
|
(item) => item?.arrowConfig?.length ?? arrowLength1
|
|
902
|
-
)
|
|
969
|
+
)
|
|
903
970
|
const arrowWidthsFromSet = props.dataSet?.map(
|
|
904
|
-
(item) => item?.arrowConfig?.
|
|
905
|
-
)
|
|
971
|
+
(item) => item?.arrowConfig?.width ?? arrowWidth1
|
|
972
|
+
)
|
|
906
973
|
const arrowStrokeWidthsFromSet = props.dataSet?.map(
|
|
907
|
-
(item) => item?.arrowConfig?.
|
|
908
|
-
)
|
|
974
|
+
(item) => item?.arrowConfig?.strokeWidth ?? arrowStrokeWidth1
|
|
975
|
+
)
|
|
909
976
|
const arrowStrokeColorsFromSet = props.dataSet?.map(
|
|
910
|
-
(item) => item?.arrowConfig?.
|
|
911
|
-
)
|
|
977
|
+
(item) => item?.arrowConfig?.strokeColor ?? arrowStrokeColor1
|
|
978
|
+
)
|
|
912
979
|
const arrowFillColorsFromSet = props.dataSet?.map(
|
|
913
|
-
(item) => item?.arrowConfig?.
|
|
914
|
-
)
|
|
980
|
+
(item) => item?.arrowConfig?.fillColor ?? arrowFillColor1
|
|
981
|
+
)
|
|
915
982
|
const showArrowBasesFromSet = props.dataSet?.map(
|
|
916
983
|
(item) => item?.arrowConfig?.showArrowBase ?? showArrowBase1
|
|
917
|
-
)
|
|
984
|
+
)
|
|
918
985
|
|
|
919
986
|
return {
|
|
920
987
|
arrowLength1,
|
|
@@ -952,14 +1019,14 @@ export const getAllArrowProperties = (
|
|
|
952
1019
|
arrowStrokeWidthsFromSet,
|
|
953
1020
|
arrowStrokeColorsFromSet,
|
|
954
1021
|
arrowFillColorsFromSet,
|
|
955
|
-
showArrowBasesFromSet
|
|
956
|
-
}
|
|
957
|
-
}
|
|
1022
|
+
showArrowBasesFromSet
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
958
1025
|
|
|
959
|
-
|
|
960
|
-
maxItem: number
|
|
961
|
-
minItem: number
|
|
962
|
-
}
|
|
1026
|
+
interface MaxAndMin {
|
|
1027
|
+
maxItem: number
|
|
1028
|
+
minItem: number
|
|
1029
|
+
}
|
|
963
1030
|
|
|
964
1031
|
export const maxAndMinUtil = (
|
|
965
1032
|
maxItem: number,
|
|
@@ -967,81 +1034,78 @@ export const maxAndMinUtil = (
|
|
|
967
1034
|
roundToDigits?: number,
|
|
968
1035
|
showFractionalValues?: boolean
|
|
969
1036
|
): MaxAndMin => {
|
|
970
|
-
if (showFractionalValues
|
|
971
|
-
maxItem *= 10 * (roundToDigits
|
|
972
|
-
maxItem = maxItem + (10 - (maxItem % 10))
|
|
973
|
-
maxItem /= 10 * (roundToDigits
|
|
974
|
-
maxItem = parseFloat(maxItem.toFixed(roundToDigits
|
|
1037
|
+
if (showFractionalValues ?? roundToDigits) {
|
|
1038
|
+
maxItem *= 10 * (roundToDigits ?? 1)
|
|
1039
|
+
maxItem = maxItem + (10 - (maxItem % 10))
|
|
1040
|
+
maxItem /= 10 * (roundToDigits ?? 1)
|
|
1041
|
+
maxItem = parseFloat(maxItem.toFixed(roundToDigits ?? 1))
|
|
975
1042
|
|
|
976
1043
|
if (minItem !== 0) {
|
|
977
|
-
minItem *= 10 * (roundToDigits
|
|
978
|
-
minItem = minItem - (10 + (minItem % 10))
|
|
979
|
-
minItem /= 10 * (roundToDigits
|
|
980
|
-
minItem = parseFloat(minItem.toFixed(roundToDigits
|
|
1044
|
+
minItem *= 10 * (roundToDigits ?? 1)
|
|
1045
|
+
minItem = minItem - (10 + (minItem % 10))
|
|
1046
|
+
minItem /= 10 * (roundToDigits ?? 1)
|
|
1047
|
+
minItem = parseFloat(minItem.toFixed(roundToDigits ?? 1))
|
|
981
1048
|
}
|
|
982
1049
|
} else {
|
|
983
|
-
maxItem = maxItem + (10 - (maxItem % 10))
|
|
1050
|
+
maxItem = maxItem + (10 - (maxItem % 10))
|
|
984
1051
|
if (minItem !== 0) {
|
|
985
|
-
minItem = minItem - (10 + (minItem % 10))
|
|
1052
|
+
minItem = minItem - (10 + (minItem % 10))
|
|
986
1053
|
}
|
|
987
1054
|
}
|
|
988
1055
|
|
|
989
|
-
return { maxItem, minItem }
|
|
990
|
-
}
|
|
1056
|
+
return { maxItem, minItem }
|
|
1057
|
+
}
|
|
991
1058
|
|
|
992
1059
|
export const computeMaxAndMinItems = (
|
|
993
|
-
data: any,
|
|
1060
|
+
data: any[] | undefined,
|
|
994
1061
|
roundToDigits?: number,
|
|
995
1062
|
showFractionalValues?: boolean
|
|
996
1063
|
): MaxAndMin => {
|
|
997
1064
|
if (!data?.length) {
|
|
998
|
-
return { maxItem: 0, minItem: 0 }
|
|
1065
|
+
return { maxItem: 0, minItem: 0 }
|
|
999
1066
|
}
|
|
1000
|
-
let maxItem = 0
|
|
1001
|
-
|
|
1067
|
+
let maxItem = 0
|
|
1068
|
+
let minItem = 0
|
|
1002
1069
|
|
|
1003
1070
|
data.forEach((item: any) => {
|
|
1004
1071
|
if (item.value > maxItem) {
|
|
1005
|
-
maxItem = item.value
|
|
1072
|
+
maxItem = item.value
|
|
1006
1073
|
}
|
|
1007
1074
|
if (item.value < minItem) {
|
|
1008
|
-
minItem = item.value
|
|
1075
|
+
minItem = item.value
|
|
1009
1076
|
}
|
|
1010
|
-
})
|
|
1077
|
+
})
|
|
1011
1078
|
|
|
1012
|
-
return maxAndMinUtil(maxItem, minItem, roundToDigits, showFractionalValues)
|
|
1013
|
-
}
|
|
1079
|
+
return maxAndMinUtil(maxItem, minItem, roundToDigits, showFractionalValues)
|
|
1080
|
+
}
|
|
1014
1081
|
|
|
1015
1082
|
export const getLabelTextUtil = (
|
|
1016
|
-
val:
|
|
1083
|
+
val: string,
|
|
1017
1084
|
index: number,
|
|
1018
1085
|
showFractionalValues?: boolean,
|
|
1019
|
-
yAxisLabelTexts?:
|
|
1086
|
+
yAxisLabelTexts?: string[],
|
|
1020
1087
|
yAxisOffset?: number,
|
|
1021
1088
|
yAxisLabelPrefix?: string,
|
|
1022
1089
|
yAxisLabelSuffix?: string,
|
|
1023
1090
|
roundToDigits?: number,
|
|
1024
1091
|
formatYLabel?: (label: string) => string
|
|
1025
|
-
) => {
|
|
1026
|
-
let label =
|
|
1027
|
-
if (
|
|
1028
|
-
|
|
1029
|
-
(yAxisLabelTexts && yAxisLabelTexts[index] !== undefined)
|
|
1030
|
-
) {
|
|
1031
|
-
if (yAxisLabelTexts?.[index]) return val;
|
|
1092
|
+
): string => {
|
|
1093
|
+
let label = ''
|
|
1094
|
+
if (showFractionalValues ?? yAxisLabelTexts?.[index] !== undefined) {
|
|
1095
|
+
if (yAxisLabelTexts?.[index]) return val
|
|
1032
1096
|
if (val) {
|
|
1033
1097
|
label = isNaN(Number(val))
|
|
1034
1098
|
? val
|
|
1035
|
-
: (Number(val) + (yAxisOffset ?? 0)).toFixed(roundToDigits)
|
|
1099
|
+
: (Number(val) + (yAxisOffset ?? 0)).toFixed(roundToDigits)
|
|
1036
1100
|
} else {
|
|
1037
|
-
label = yAxisOffset?.toString() ??
|
|
1101
|
+
label = yAxisOffset?.toString() ?? '0'
|
|
1038
1102
|
}
|
|
1039
1103
|
} else {
|
|
1040
1104
|
if (val) {
|
|
1041
|
-
label = val.toString().split(
|
|
1042
|
-
label = (Number(label) + (yAxisOffset ?? 0)).toString()
|
|
1105
|
+
label = val.toString().split('.')[0]
|
|
1106
|
+
label = (Number(label) + (yAxisOffset ?? 0)).toString()
|
|
1043
1107
|
} else {
|
|
1044
|
-
label = yAxisOffset?.toString() ??
|
|
1108
|
+
label = yAxisOffset?.toString() ?? '0'
|
|
1045
1109
|
}
|
|
1046
1110
|
}
|
|
1047
1111
|
|
|
@@ -1049,8 +1113,8 @@ export const getLabelTextUtil = (
|
|
|
1049
1113
|
yAxisLabelPrefix +
|
|
1050
1114
|
(formatYLabel ? formatYLabel(label) : label) +
|
|
1051
1115
|
yAxisLabelSuffix
|
|
1052
|
-
)
|
|
1053
|
-
}
|
|
1116
|
+
)
|
|
1117
|
+
}
|
|
1054
1118
|
|
|
1055
1119
|
export const getXForLineInBar = (
|
|
1056
1120
|
index: number,
|
|
@@ -1059,75 +1123,84 @@ export const getXForLineInBar = (
|
|
|
1059
1123
|
yAxisLabelWidth: number,
|
|
1060
1124
|
lineConfig: any,
|
|
1061
1125
|
spacing: number
|
|
1062
|
-
) =>
|
|
1126
|
+
): number =>
|
|
1063
1127
|
yAxisLabelWidth +
|
|
1064
1128
|
firstBarWidth / 2 +
|
|
1065
1129
|
lineConfig.initialSpacing +
|
|
1066
1130
|
(currentBarWidth + (lineConfig.spacing ?? spacing)) * index +
|
|
1067
1131
|
lineConfig.shiftX -
|
|
1068
1132
|
lineConfig.dataPointsWidth / 2 -
|
|
1069
|
-
4
|
|
1133
|
+
4
|
|
1070
1134
|
|
|
1071
|
-
export const getYForLineInBar = (
|
|
1072
|
-
|
|
1135
|
+
export const getYForLineInBar = (
|
|
1136
|
+
value: number | undefined,
|
|
1137
|
+
shiftY: number | undefined,
|
|
1138
|
+
containerHeight: number,
|
|
1139
|
+
maxValue: number
|
|
1140
|
+
): number =>
|
|
1141
|
+
containerHeight - (shiftY ?? 0) - ((value ?? 0) * containerHeight) / maxValue
|
|
1073
1142
|
|
|
1074
|
-
export const clone = (obj) => {
|
|
1075
|
-
if (obj === null || typeof obj !==
|
|
1076
|
-
return obj
|
|
1143
|
+
export const clone = (obj: any): any => {
|
|
1144
|
+
if (obj === null || typeof obj !== 'object' || 'isActiveClone' in obj) {
|
|
1145
|
+
return obj
|
|
1146
|
+
}
|
|
1077
1147
|
|
|
1078
|
-
let temp
|
|
1079
|
-
if (obj instanceof Date) temp = new Date(obj)
|
|
1080
|
-
else temp = obj.constructor()
|
|
1148
|
+
let temp
|
|
1149
|
+
if (obj instanceof Date) temp = new Date(obj)
|
|
1150
|
+
else temp = obj.constructor()
|
|
1081
1151
|
|
|
1082
|
-
for (
|
|
1152
|
+
for (const key in obj) {
|
|
1083
1153
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
1084
|
-
obj
|
|
1085
|
-
temp[key] = clone(obj[key])
|
|
1086
|
-
delete obj
|
|
1154
|
+
obj.isActiveClone = null
|
|
1155
|
+
temp[key] = clone(obj[key])
|
|
1156
|
+
delete obj.isActiveClone
|
|
1087
1157
|
}
|
|
1088
1158
|
}
|
|
1089
|
-
return temp
|
|
1090
|
-
}
|
|
1159
|
+
return temp
|
|
1160
|
+
}
|
|
1091
1161
|
|
|
1092
|
-
export const getLineConfigForBarChart = (
|
|
1162
|
+
export const getLineConfigForBarChart = (
|
|
1163
|
+
lineConfig: lineConfigType,
|
|
1164
|
+
barInitialSpacing: number
|
|
1165
|
+
): lineConfigType => {
|
|
1093
1166
|
return {
|
|
1094
1167
|
initialSpacing:
|
|
1095
1168
|
lineConfig.initialSpacing ??
|
|
1096
1169
|
barInitialSpacing ??
|
|
1097
1170
|
defaultLineConfig.initialSpacing,
|
|
1098
1171
|
spacing: lineConfig.spacing,
|
|
1099
|
-
curved: lineConfig.curved
|
|
1172
|
+
curved: lineConfig.curved ?? defaultLineConfig.curved,
|
|
1100
1173
|
curvature: lineConfig.curvature ?? defaultLineConfig.curvature,
|
|
1101
1174
|
curveType: lineConfig.curveType ?? defaultLineConfig.curveType,
|
|
1102
|
-
isAnimated: lineConfig.isAnimated
|
|
1175
|
+
isAnimated: lineConfig.isAnimated ?? defaultLineConfig.isAnimated,
|
|
1103
1176
|
animationDuration:
|
|
1104
|
-
lineConfig.animationDuration
|
|
1105
|
-
thickness: lineConfig.thickness
|
|
1106
|
-
color: lineConfig.color
|
|
1177
|
+
lineConfig.animationDuration ?? defaultLineConfig.animationDuration,
|
|
1178
|
+
thickness: lineConfig.thickness ?? defaultLineConfig.thickness,
|
|
1179
|
+
color: lineConfig.color ?? defaultLineConfig.color,
|
|
1107
1180
|
hideDataPoints:
|
|
1108
|
-
lineConfig.hideDataPoints
|
|
1181
|
+
lineConfig.hideDataPoints ?? defaultLineConfig.hideDataPoints,
|
|
1109
1182
|
dataPointsShape:
|
|
1110
|
-
lineConfig.dataPointsShape
|
|
1183
|
+
lineConfig.dataPointsShape ?? defaultLineConfig.dataPointsShape,
|
|
1111
1184
|
dataPointsHeight:
|
|
1112
|
-
lineConfig.dataPointsHeight
|
|
1185
|
+
lineConfig.dataPointsHeight ?? defaultLineConfig.dataPointsHeight,
|
|
1113
1186
|
dataPointsWidth:
|
|
1114
|
-
lineConfig.dataPointsWidth
|
|
1187
|
+
lineConfig.dataPointsWidth ?? defaultLineConfig.dataPointsWidth,
|
|
1115
1188
|
dataPointsColor:
|
|
1116
|
-
lineConfig.dataPointsColor
|
|
1189
|
+
lineConfig.dataPointsColor ?? defaultLineConfig.dataPointsColor,
|
|
1117
1190
|
dataPointsRadius:
|
|
1118
|
-
lineConfig.dataPointsRadius
|
|
1119
|
-
textColor: lineConfig.textColor
|
|
1120
|
-
textFontSize: lineConfig.textFontSize
|
|
1121
|
-
textShiftX: lineConfig.textShiftX
|
|
1122
|
-
textShiftY: lineConfig.textShiftY
|
|
1123
|
-
shiftX: lineConfig.shiftX
|
|
1124
|
-
shiftY: lineConfig.shiftY
|
|
1125
|
-
delay: lineConfig.delay
|
|
1126
|
-
startIndex: lineConfig.startIndex
|
|
1191
|
+
lineConfig.dataPointsRadius ?? defaultLineConfig.dataPointsRadius,
|
|
1192
|
+
textColor: lineConfig.textColor ?? defaultLineConfig.textColor,
|
|
1193
|
+
textFontSize: lineConfig.textFontSize ?? defaultLineConfig.textFontSize,
|
|
1194
|
+
textShiftX: lineConfig.textShiftX ?? defaultLineConfig.textShiftX,
|
|
1195
|
+
textShiftY: lineConfig.textShiftY ?? defaultLineConfig.textShiftY,
|
|
1196
|
+
shiftX: lineConfig.shiftX ?? defaultLineConfig.shiftX,
|
|
1197
|
+
shiftY: lineConfig.shiftY ?? defaultLineConfig.shiftY,
|
|
1198
|
+
delay: lineConfig.delay ?? defaultLineConfig.delay,
|
|
1199
|
+
startIndex: lineConfig.startIndex ?? defaultLineConfig.startIndex,
|
|
1127
1200
|
endIndex:
|
|
1128
1201
|
lineConfig.endIndex === 0
|
|
1129
1202
|
? 0
|
|
1130
|
-
: lineConfig.endIndex
|
|
1203
|
+
: lineConfig.endIndex ?? defaultLineConfig.endIndex,
|
|
1131
1204
|
|
|
1132
1205
|
showArrow: lineConfig.showArrow ?? defaultLineConfig.showArrow,
|
|
1133
1206
|
arrowConfig: {
|
|
@@ -1150,79 +1223,87 @@ export const getLineConfigForBarChart = (lineConfig, barInitialSpacing) => {
|
|
|
1150
1223
|
|
|
1151
1224
|
showArrowBase:
|
|
1152
1225
|
lineConfig.arrowConfig?.showArrowBase ??
|
|
1153
|
-
defaultLineConfig.arrowConfig?.showArrowBase
|
|
1226
|
+
defaultLineConfig.arrowConfig?.showArrowBase
|
|
1154
1227
|
},
|
|
1155
1228
|
customDataPoint: lineConfig.customDataPoint,
|
|
1156
|
-
isSecondary: lineConfig.isSecondary ?? defaultLineConfig.isSecondary
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1229
|
+
isSecondary: lineConfig.isSecondary ?? defaultLineConfig.isSecondary
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1159
1232
|
|
|
1160
|
-
export const getNoOfSections = (
|
|
1233
|
+
export const getNoOfSections = (
|
|
1234
|
+
noOfSections: number | undefined,
|
|
1235
|
+
maxValue: number | undefined,
|
|
1236
|
+
stepValue: number | undefined
|
|
1237
|
+
): number =>
|
|
1161
1238
|
maxValue && stepValue
|
|
1162
1239
|
? maxValue / stepValue
|
|
1163
|
-
: noOfSections ?? AxesAndRulesDefaults.noOfSections
|
|
1240
|
+
: noOfSections ?? AxesAndRulesDefaults.noOfSections
|
|
1164
1241
|
|
|
1165
|
-
export const getMaxValue = (
|
|
1166
|
-
maxValue
|
|
1242
|
+
export const getMaxValue = (
|
|
1243
|
+
maxValue: number | undefined,
|
|
1244
|
+
stepValue: number | undefined,
|
|
1245
|
+
noOfSections: number,
|
|
1246
|
+
maxItem: number
|
|
1247
|
+
): number => maxValue ?? (stepValue ? stepValue * noOfSections : maxItem)
|
|
1167
1248
|
|
|
1168
1249
|
export const getBarFrontColor = (
|
|
1169
|
-
isFocused,
|
|
1170
|
-
focusedBarConfig,
|
|
1171
|
-
itemFrontColor,
|
|
1172
|
-
frontColor,
|
|
1173
|
-
isThreeD
|
|
1174
|
-
) => {
|
|
1250
|
+
isFocused?: boolean,
|
|
1251
|
+
focusedBarConfig?: FocusedBarConfig,
|
|
1252
|
+
itemFrontColor?: ColorValue,
|
|
1253
|
+
frontColor?: ColorValue,
|
|
1254
|
+
isThreeD?: boolean
|
|
1255
|
+
): ColorValue => {
|
|
1175
1256
|
if (isFocused) {
|
|
1176
1257
|
return (
|
|
1177
1258
|
focusedBarConfig?.color ??
|
|
1178
1259
|
(isThreeD
|
|
1179
1260
|
? BarDefaults.focusedThreeDBarFrontColor
|
|
1180
1261
|
: BarDefaults.focusedBarFrontColor)
|
|
1181
|
-
)
|
|
1262
|
+
)
|
|
1182
1263
|
}
|
|
1183
1264
|
return (
|
|
1184
|
-
itemFrontColor
|
|
1185
|
-
frontColor
|
|
1265
|
+
itemFrontColor ??
|
|
1266
|
+
frontColor ??
|
|
1186
1267
|
(isThreeD ? BarDefaults.threeDBarFrontColor : BarDefaults.frontColor)
|
|
1187
|
-
)
|
|
1188
|
-
}
|
|
1268
|
+
)
|
|
1269
|
+
}
|
|
1189
1270
|
|
|
1190
1271
|
export const getBarSideColor = (
|
|
1191
|
-
isFocused,
|
|
1192
|
-
focusedBarConfig,
|
|
1193
|
-
itemSideColor,
|
|
1194
|
-
sideColor
|
|
1195
|
-
) => {
|
|
1272
|
+
isFocused?: boolean,
|
|
1273
|
+
focusedBarConfig?: FocusedBarConfig,
|
|
1274
|
+
itemSideColor?: ColorValue,
|
|
1275
|
+
sideColor?: ColorValue
|
|
1276
|
+
): ColorValue | undefined => {
|
|
1196
1277
|
if (isFocused) {
|
|
1197
|
-
return focusedBarConfig?.sideColor ?? BarDefaults.focusedBarSideColor
|
|
1278
|
+
return focusedBarConfig?.sideColor ?? BarDefaults.focusedBarSideColor
|
|
1198
1279
|
}
|
|
1199
|
-
return itemSideColor
|
|
1200
|
-
}
|
|
1280
|
+
return itemSideColor ?? sideColor
|
|
1281
|
+
}
|
|
1201
1282
|
|
|
1202
1283
|
export const getBarTopColor = (
|
|
1203
|
-
isFocused,
|
|
1204
|
-
focusedBarConfig,
|
|
1205
|
-
itemTopColor,
|
|
1206
|
-
topColor
|
|
1207
|
-
) => {
|
|
1284
|
+
isFocused?: boolean,
|
|
1285
|
+
focusedBarConfig?: FocusedBarConfig,
|
|
1286
|
+
itemTopColor?: ColorValue,
|
|
1287
|
+
topColor?: ColorValue
|
|
1288
|
+
): ColorValue | undefined => {
|
|
1208
1289
|
if (isFocused) {
|
|
1209
|
-
return focusedBarConfig?.topColor ?? BarDefaults.focusedBarTopColor
|
|
1290
|
+
return focusedBarConfig?.topColor ?? BarDefaults.focusedBarTopColor
|
|
1210
1291
|
}
|
|
1211
|
-
return itemTopColor
|
|
1212
|
-
}
|
|
1292
|
+
return itemTopColor ?? topColor
|
|
1293
|
+
}
|
|
1213
1294
|
|
|
1214
1295
|
export const getBarWidth = (
|
|
1215
|
-
isFocused,
|
|
1216
|
-
focusedBarConfig,
|
|
1217
|
-
itemBarWidth,
|
|
1218
|
-
barWidth
|
|
1219
|
-
) => {
|
|
1220
|
-
const localBarWidth = itemBarWidth
|
|
1296
|
+
isFocused?: boolean,
|
|
1297
|
+
focusedBarConfig?: FocusedBarConfig,
|
|
1298
|
+
itemBarWidth?: number,
|
|
1299
|
+
barWidth?: number
|
|
1300
|
+
): number => {
|
|
1301
|
+
const localBarWidth = itemBarWidth ?? barWidth ?? BarDefaults.barWidth
|
|
1221
1302
|
if (isFocused) {
|
|
1222
|
-
return focusedBarConfig?.width ?? localBarWidth
|
|
1303
|
+
return focusedBarConfig?.width ?? localBarWidth
|
|
1223
1304
|
}
|
|
1224
|
-
return localBarWidth
|
|
1225
|
-
}
|
|
1305
|
+
return localBarWidth
|
|
1306
|
+
}
|
|
1226
1307
|
|
|
1227
1308
|
export const getInterpolatedData = (
|
|
1228
1309
|
dataParam: lineDataItem[],
|
|
@@ -1232,43 +1313,43 @@ export const getInterpolatedData = (
|
|
|
1232
1313
|
): lineDataItem[] => {
|
|
1233
1314
|
if (!interpolateMissingValues) {
|
|
1234
1315
|
return dataParam.map((item) => {
|
|
1235
|
-
if (typeof item.value !==
|
|
1236
|
-
if (showDataPointsForMissingValues) return { ...item, value: 0 }
|
|
1237
|
-
return { ...item, value: 0, hideDataPoint: true }
|
|
1316
|
+
if (typeof item.value !== 'number') {
|
|
1317
|
+
if (showDataPointsForMissingValues) return { ...item, value: 0 }
|
|
1318
|
+
return { ...item, value: 0, hideDataPoint: true }
|
|
1238
1319
|
}
|
|
1239
|
-
return item
|
|
1240
|
-
})
|
|
1320
|
+
return item
|
|
1321
|
+
})
|
|
1241
1322
|
}
|
|
1242
|
-
if (!interpolateMissingValues) return dataParam
|
|
1243
|
-
const data = clone(dataParam)
|
|
1244
|
-
const n = data.length
|
|
1323
|
+
if (!interpolateMissingValues) return dataParam
|
|
1324
|
+
const data: lineDataItem[] = clone(dataParam)
|
|
1325
|
+
const n = data.length
|
|
1245
1326
|
|
|
1246
|
-
|
|
1247
|
-
let numericValue
|
|
1327
|
+
/** ************ PRE-PROCESSING **************/
|
|
1328
|
+
let numericValue: number
|
|
1248
1329
|
const numericValuesLength = data.filter((item) => {
|
|
1249
|
-
const isNum = typeof item.value ===
|
|
1330
|
+
const isNum = typeof item.value === 'number'
|
|
1250
1331
|
if (isNum) {
|
|
1251
|
-
numericValue = item.value
|
|
1252
|
-
return true
|
|
1332
|
+
numericValue = item.value
|
|
1333
|
+
return true
|
|
1253
1334
|
}
|
|
1254
|
-
return false
|
|
1255
|
-
}).length
|
|
1335
|
+
return false
|
|
1336
|
+
}).length
|
|
1256
1337
|
|
|
1257
|
-
if (!numericValuesLength) return []
|
|
1338
|
+
if (!numericValuesLength) return []
|
|
1258
1339
|
|
|
1259
1340
|
if (numericValuesLength === 1) {
|
|
1260
1341
|
data.forEach((item) => {
|
|
1261
|
-
if (!showDataPointsForMissingValues && typeof item.value !==
|
|
1262
|
-
item.hideDataPoint = true
|
|
1342
|
+
if (!showDataPointsForMissingValues && typeof item.value !== 'number') {
|
|
1343
|
+
item.hideDataPoint = true
|
|
1263
1344
|
}
|
|
1264
|
-
item.value = numericValue
|
|
1265
|
-
})
|
|
1266
|
-
return data
|
|
1345
|
+
item.value = numericValue
|
|
1346
|
+
})
|
|
1347
|
+
return data
|
|
1267
1348
|
}
|
|
1268
1349
|
/**********************************************************************/
|
|
1269
1350
|
|
|
1270
1351
|
data.forEach((item, index) => {
|
|
1271
|
-
if (typeof item.value ===
|
|
1352
|
+
if (typeof item.value === 'number') return
|
|
1272
1353
|
// Cut the line in 2 halves-> pre and post
|
|
1273
1354
|
// Now there are 4 possibilities-
|
|
1274
1355
|
// 1. Both pre and post have valid values
|
|
@@ -1276,133 +1357,135 @@ export const getInterpolatedData = (
|
|
|
1276
1357
|
// 3. Only post has valid value
|
|
1277
1358
|
// 4. None has valid value -> this is already handled in preprocessing
|
|
1278
1359
|
|
|
1279
|
-
const pre = data.slice(0, index)
|
|
1280
|
-
const post = data.slice(index + 1, n)
|
|
1360
|
+
const pre = data.slice(0, index)
|
|
1361
|
+
const post = data.slice(index + 1, n)
|
|
1281
1362
|
|
|
1282
1363
|
const preValidIndex = pre.findLastIndex(
|
|
1283
|
-
(item) => typeof item.value ===
|
|
1284
|
-
)
|
|
1364
|
+
(item) => typeof item.value === 'number'
|
|
1365
|
+
)
|
|
1285
1366
|
const postValidInd = post.findIndex(
|
|
1286
|
-
(item) => typeof item.value ===
|
|
1287
|
-
)
|
|
1288
|
-
const postValidIndex = postValidInd + index + 1
|
|
1367
|
+
(item) => typeof item.value === 'number'
|
|
1368
|
+
)
|
|
1369
|
+
const postValidIndex = postValidInd + index + 1
|
|
1289
1370
|
|
|
1290
|
-
let count, step
|
|
1371
|
+
let count, step
|
|
1291
1372
|
|
|
1292
1373
|
// 1. Both pre and post have valid values
|
|
1293
1374
|
if (preValidIndex !== -1 && postValidInd !== -1) {
|
|
1294
|
-
count = postValidIndex - preValidIndex
|
|
1295
|
-
step = (data[postValidIndex].value - data[preValidIndex].value) / count
|
|
1375
|
+
count = postValidIndex - preValidIndex
|
|
1376
|
+
step = (data[postValidIndex].value - data[preValidIndex].value) / count
|
|
1296
1377
|
data[index].value =
|
|
1297
|
-
data[preValidIndex].value + step * (index - preValidIndex)
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
// 2. Only pre has valid value
|
|
1301
|
-
else if (preValidIndex !== -1 && postValidInd === -1) {
|
|
1378
|
+
data[preValidIndex].value + step * (index - preValidIndex)
|
|
1379
|
+
} else if (preValidIndex !== -1 && postValidInd === -1) {
|
|
1380
|
+
// 2. Only pre has valid value
|
|
1302
1381
|
// Now there are 2 possibilities-
|
|
1303
1382
|
// 1. There's only 1 valid value in the pre -> this is already handled in preprocessing
|
|
1304
1383
|
// 2. There are more than valid values in pre
|
|
1305
|
-
const secondPre = data.slice(0, preValidIndex)
|
|
1384
|
+
const secondPre = data.slice(0, preValidIndex)
|
|
1306
1385
|
const secondPreIndex = secondPre.findLastIndex(
|
|
1307
|
-
(item) => typeof item.value ===
|
|
1308
|
-
)
|
|
1386
|
+
(item) => typeof item.value === 'number'
|
|
1387
|
+
)
|
|
1309
1388
|
|
|
1310
|
-
count = preValidIndex - secondPreIndex
|
|
1311
|
-
step = (data[secondPreIndex].value - data[preValidIndex].value) / count
|
|
1389
|
+
count = preValidIndex - secondPreIndex
|
|
1390
|
+
step = (data[secondPreIndex].value - data[preValidIndex].value) / count
|
|
1312
1391
|
data[index].value =
|
|
1313
|
-
data[preValidIndex].value - step * (index - preValidIndex)
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
// 3. Only post has valid value
|
|
1317
|
-
else if (preValidIndex === -1 && postValidInd !== -1) {
|
|
1392
|
+
data[preValidIndex].value - step * (index - preValidIndex)
|
|
1393
|
+
} else if (preValidIndex === -1 && postValidInd !== -1) {
|
|
1394
|
+
// 3. Only post has valid value
|
|
1318
1395
|
// Now there are 2 possibilities-
|
|
1319
1396
|
// 1. There's only 1 valid value in the post -> this is already handled in preprocessing
|
|
1320
1397
|
// 2. There are more than valid values in post
|
|
1321
1398
|
|
|
1322
|
-
const secondPost = data.slice(postValidIndex + 1, n)
|
|
1399
|
+
const secondPost = data.slice(postValidIndex + 1, n)
|
|
1323
1400
|
const secondPostInd = secondPost.findIndex(
|
|
1324
|
-
(item) => typeof item.value ===
|
|
1325
|
-
)
|
|
1326
|
-
const secondPostIndex = secondPostInd + postValidIndex + 1
|
|
1401
|
+
(item) => typeof item.value === 'number'
|
|
1402
|
+
)
|
|
1403
|
+
const secondPostIndex = secondPostInd + postValidIndex + 1
|
|
1327
1404
|
|
|
1328
|
-
count = secondPostIndex - postValidIndex
|
|
1329
|
-
step = (data[secondPostIndex].value - data[postValidIndex].value) / count
|
|
1405
|
+
count = secondPostIndex - postValidIndex
|
|
1406
|
+
step = (data[secondPostIndex].value - data[postValidIndex].value) / count
|
|
1330
1407
|
data[index].value =
|
|
1331
|
-
data[postValidIndex].value - step * (postValidIndex - index)
|
|
1408
|
+
data[postValidIndex].value - step * (postValidIndex - index)
|
|
1332
1409
|
}
|
|
1333
1410
|
|
|
1334
1411
|
// hide data point (since it is interpolated)
|
|
1335
1412
|
if (!showDataPointsForMissingValues) {
|
|
1336
|
-
item.hideDataPoint = true
|
|
1413
|
+
item.hideDataPoint = true
|
|
1337
1414
|
}
|
|
1338
|
-
})
|
|
1415
|
+
})
|
|
1339
1416
|
return onlyPositive
|
|
1340
1417
|
? data.map((item) => ({ ...item, value: Math.max(item.value, 0) }))
|
|
1341
|
-
: data
|
|
1342
|
-
}
|
|
1418
|
+
: data
|
|
1419
|
+
}
|
|
1343
1420
|
|
|
1344
1421
|
export const getLineSegmentsForMissingValues = (
|
|
1345
1422
|
data?: lineDataItem[]
|
|
1346
1423
|
): LineSegment[] | undefined => {
|
|
1347
|
-
if (!data?.length) return undefined
|
|
1348
|
-
let i
|
|
1349
|
-
|
|
1424
|
+
if (!data?.length) return undefined
|
|
1425
|
+
let i
|
|
1426
|
+
const n = data.length
|
|
1350
1427
|
const numericValuesLength = data.filter(
|
|
1351
|
-
(item) => typeof item.value ===
|
|
1352
|
-
).length
|
|
1353
|
-
if (!numericValuesLength) return undefined
|
|
1354
|
-
const segments: LineSegment[] = []
|
|
1428
|
+
(item) => typeof item.value === 'number'
|
|
1429
|
+
).length
|
|
1430
|
+
if (!numericValuesLength) return undefined
|
|
1431
|
+
const segments: LineSegment[] = []
|
|
1355
1432
|
for (i = 0; i < n; i++) {
|
|
1356
|
-
if (typeof data[i].value !==
|
|
1357
|
-
const nextValidInd = data
|
|
1433
|
+
if (typeof data[i].value !== 'number') {
|
|
1434
|
+
const nextValidInd: number = data
|
|
1358
1435
|
.slice(i + 1, n)
|
|
1359
|
-
.findIndex((item) => typeof item.value ===
|
|
1436
|
+
.findIndex((item) => typeof item.value === 'number')
|
|
1360
1437
|
if (nextValidInd === -1) {
|
|
1361
1438
|
segments.push({
|
|
1362
1439
|
startIndex: Math.max(i - 1, 0),
|
|
1363
1440
|
endIndex: n,
|
|
1364
|
-
color:
|
|
1365
|
-
})
|
|
1366
|
-
break
|
|
1441
|
+
color: 'transparent'
|
|
1442
|
+
})
|
|
1443
|
+
break
|
|
1367
1444
|
}
|
|
1368
|
-
const nextValidIndex = nextValidInd + i + 1
|
|
1445
|
+
const nextValidIndex: number = nextValidInd + i + 1
|
|
1369
1446
|
segments.push({
|
|
1370
1447
|
startIndex: Math.max(i - 1, 0),
|
|
1371
1448
|
endIndex: nextValidIndex,
|
|
1372
|
-
color:
|
|
1373
|
-
})
|
|
1374
|
-
i = nextValidIndex
|
|
1449
|
+
color: 'transparent'
|
|
1450
|
+
})
|
|
1451
|
+
i = nextValidIndex
|
|
1375
1452
|
}
|
|
1376
1453
|
}
|
|
1377
|
-
return segments
|
|
1378
|
-
}
|
|
1454
|
+
return segments
|
|
1455
|
+
}
|
|
1379
1456
|
|
|
1380
1457
|
export const getTextSizeForPieLabels = (
|
|
1381
1458
|
textSize: number,
|
|
1382
1459
|
radius: number
|
|
1383
|
-
): number => (textSize ? Math.min(textSize, radius / 5) : 16)
|
|
1460
|
+
): number => (textSize ? Math.min(textSize, radius / 5) : 16)
|
|
1384
1461
|
|
|
1385
|
-
export const adjustToOffset = (
|
|
1386
|
-
data
|
|
1462
|
+
export const adjustToOffset = (
|
|
1463
|
+
data: lineDataItem[],
|
|
1464
|
+
yAxisOffset?: number
|
|
1465
|
+
): lineDataItem[] =>
|
|
1466
|
+
data.map((item) => ({ ...item, value: item.value - (yAxisOffset ?? 0) }))
|
|
1387
1467
|
|
|
1388
|
-
export const getSanitisedData = (
|
|
1468
|
+
export const getSanitisedData = (
|
|
1469
|
+
data: lineDataItem[] | undefined,
|
|
1470
|
+
dataSanitisationProps: IDataSanitisationProps
|
|
1471
|
+
): lineDataItem[] => {
|
|
1389
1472
|
if (!data) {
|
|
1390
|
-
return []
|
|
1473
|
+
return []
|
|
1391
1474
|
}
|
|
1392
1475
|
const {
|
|
1393
1476
|
showDataPointsForMissingValues,
|
|
1394
1477
|
interpolateMissingValues,
|
|
1395
1478
|
onlyPositive,
|
|
1396
|
-
yAxisOffset
|
|
1397
|
-
} = dataSanitisationProps
|
|
1479
|
+
yAxisOffset
|
|
1480
|
+
} = dataSanitisationProps
|
|
1398
1481
|
const nullishHandledData = getInterpolatedData(
|
|
1399
1482
|
data,
|
|
1400
1483
|
showDataPointsForMissingValues,
|
|
1401
1484
|
interpolateMissingValues,
|
|
1402
1485
|
onlyPositive
|
|
1403
|
-
)
|
|
1486
|
+
)
|
|
1404
1487
|
if (yAxisOffset) {
|
|
1405
|
-
return adjustToOffset(nullishHandledData, yAxisOffset)
|
|
1488
|
+
return adjustToOffset(nullishHandledData, yAxisOffset)
|
|
1406
1489
|
}
|
|
1407
|
-
return nullishHandledData
|
|
1408
|
-
}
|
|
1490
|
+
return nullishHandledData
|
|
1491
|
+
}
|