gifted-charts-core 0.0.9 → 0.0.11

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gifted-charts-core",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "Mathematical and logical utilities used by react-gifted-charts and react-native-gifted-charts",
5
5
  "main": "index.ts",
6
6
  "files": [
@@ -34,10 +34,15 @@ export const getPropsForAnimated2DWithGradient = (props) => {
34
34
  selectedIndex,
35
35
  focusBarOnPress,
36
36
  focusedBarConfig,
37
+ isThreeD,
37
38
  } = props;
38
39
 
39
40
  const isFocused = focusBarOnPress && selectedIndex === index;
40
- const localBarBorderRadius = item.barBorderRadius ?? barBorderRadius ?? 0;
41
+ const itemOrPropsBarBorderRadius =
42
+ item.barBorderRadius ?? barBorderRadius ?? 0;
43
+ const localBarBorderRadius = isFocused
44
+ ? focusedBarConfig?.borderRadius ?? itemOrPropsBarBorderRadius
45
+ : itemOrPropsBarBorderRadius;
41
46
  const localBarWidth = getBarWidth(
42
47
  isFocused,
43
48
  focusedBarConfig,
@@ -48,7 +53,8 @@ export const getPropsForAnimated2DWithGradient = (props) => {
48
53
  isFocused,
49
54
  focusedBarConfig,
50
55
  item.frontColor,
51
- frontColor
56
+ frontColor,
57
+ isThreeD,
52
58
  );
53
59
  const localGradientColor = item.gradientColor || gradientColor;
54
60
  const localOpacity = opacity || 1;
@@ -60,29 +66,23 @@ export const getPropsForAnimated2DWithGradient = (props) => {
60
66
  height: "100%",
61
67
  borderWidth: barBorderWidth ?? 0,
62
68
  borderColor: barBorderColor,
63
- borderRadius: isFocused
64
- ? focusedBarConfig?.borderRadius ?? localBarBorderRadius
65
- : localBarBorderRadius,
69
+ borderRadius: localBarBorderRadius,
66
70
  borderTopLeftRadius:
67
71
  item.barBorderTopLeftRadius ??
68
72
  barBorderTopLeftRadius ??
69
- item.barBorderRadius ??
70
- barBorderRadius,
73
+ localBarBorderRadius,
71
74
  borderTopRightRadius:
72
75
  item.barBorderTopRightRadius ??
73
76
  barBorderTopRightRadius ??
74
- item.barBorderRadius ??
75
- barBorderRadius,
77
+ localBarBorderRadius,
76
78
  borderBottomLeftRadius:
77
79
  item.barBorderBottomLeftRadius ??
78
80
  barBorderBottomLeftRadius ??
79
- item.barBorderRadius ??
80
- barBorderRadius,
81
+ localBarBorderRadius,
81
82
  borderBottomRightRadius:
82
83
  item.barBorderBottomRightRadius ??
83
84
  barBorderBottomRightRadius ??
84
- item.barBorderRadius ??
85
- barBorderRadius,
85
+ localBarBorderRadius,
86
86
  },
87
87
  ];
88
88
 
@@ -1,4 +1,4 @@
1
- import { ColorValue, GestureResponderEvent } from "react-native";
1
+ import { ColorValue, GestureResponderEvent, ViewStyle } from "react-native";
2
2
  import { yAxisSides } from "../utils/constants";
3
3
  import {
4
4
  CurveType,
@@ -305,6 +305,8 @@ export type BarChartPropsType = {
305
305
 
306
306
  export type FocusedBarConfig = {
307
307
  color?: ColorValue;
308
+ sideColor?: ColorValue;
309
+ topColor?: ColorValue;
308
310
  gradientColor?: ColorValue;
309
311
  width?: number;
310
312
  borderRadius?: number;
@@ -312,7 +314,7 @@ export type FocusedBarConfig = {
312
314
  roundedBottom?: boolean;
313
315
  opacity?: number;
314
316
  barInnerComponent?: (item?: barDataItem, index?: number) => ReactNode;
315
- }
317
+ };
316
318
 
317
319
  type lineConfigType = {
318
320
  initialSpacing?: number;
@@ -460,6 +462,8 @@ export type Animated2DWithGradientPropsType = {
460
462
  barMarginBottom?: number;
461
463
  barStyle?: object;
462
464
  barInnerComponent?: (item?: barDataItem, index?: number) => ReactNode;
465
+ commonStyleForBar?: ViewStyle[];
466
+ barStyleWithBackground?: ViewStyle[];
463
467
  };
464
468
 
465
469
  export type RenderBarsPropsType = {
@@ -540,6 +544,7 @@ export type RenderBarsPropsType = {
540
544
  barStyle?: object;
541
545
  xAxisThickness?: number;
542
546
  pointerConfig?: Pointer;
547
+ focusBarOnPress?: boolean;
543
548
  };
544
549
 
545
550
  export type trianglePropTypes = {
@@ -579,20 +584,20 @@ export type animatedBarPropTypes = {
579
584
 
580
585
  export type CommonPropsFor2Dand3DbarsType = {
581
586
  barBackgroundPattern: Function;
582
- barInnerComponent: (item?: barDataItem, index?: number) => ReactNode;
583
- patternId: String;
584
- barWidth: number;
585
- barStyle: object;
586
- item: barDataItem;
587
- index: number;
587
+ barInnerComponent: (item?: barDataItem, index?: number) => ReactNode;
588
+ patternId: String;
589
+ barWidth: number;
590
+ barStyle: object;
591
+ item: barDataItem;
592
+ index: number;
588
593
 
589
- frontColor: ColorValue;
590
- showGradient: boolean;
591
- gradientColor: ColorValue;
592
- opacity: number;
593
- height: number;
594
- intactTopLabel: boolean;
595
- showValuesAsTopLabel: boolean;
596
- topLabelContainerStyle: any;
597
- topLabelTextStyle: any;
598
- }
594
+ frontColor: ColorValue;
595
+ showGradient: boolean;
596
+ gradientColor: ColorValue;
597
+ opacity: number;
598
+ height: number;
599
+ intactTopLabel: boolean;
600
+ showValuesAsTopLabel: boolean;
601
+ topLabelContainerStyle: any;
602
+ topLabelTextStyle: any;
603
+ };
@@ -17,6 +17,8 @@ import {
17
17
  getAxesAndRulesProps,
18
18
  getCurvePathWithSegments,
19
19
  getExtendedContainerHeightWithPadding,
20
+ getInterpolatedData,
21
+ getLineSegmentsForMissingValues,
20
22
  getMaxValue,
21
23
  getNoOfSections,
22
24
  getPathWithHighlight,
@@ -32,7 +34,12 @@ interface extendedLineChartPropsType extends LineChartPropsType {
32
34
  }
33
35
 
34
36
  export const useLineChart = (props: extendedLineChartPropsType) => {
35
- const { animations } = props;
37
+ const {
38
+ animations,
39
+ showDataPointsForMissingValues,
40
+ interpolateMissingValues = true,
41
+ onlyPositive,
42
+ } = props;
36
43
  const curvature = props.curvature ?? LineDefaults.curvature;
37
44
  const curveType = props.curveType ?? LineDefaults.curveType;
38
45
  const [scrollX, setScrollX] = useState(0);
@@ -110,70 +117,114 @@ export const useLineChart = (props: extendedLineChartPropsType) => {
110
117
  if (!props.data) {
111
118
  return [];
112
119
  }
120
+ const nullishHandledData = getInterpolatedData(
121
+ props.data,
122
+ showDataPointsForMissingValues,
123
+ interpolateMissingValues,
124
+ onlyPositive
125
+ );
113
126
  if (props.yAxisOffset) {
114
- return clone(props.data).map((item) => {
127
+ return nullishHandledData.map((item) => {
115
128
  item.value = item.value - (props.yAxisOffset ?? 0);
116
129
  return item;
117
130
  });
118
131
  }
119
- return props.data;
132
+ return nullishHandledData;
120
133
  }, [props.yAxisOffset, props.data]);
121
134
  const data2 = useMemo(() => {
122
135
  if (!props.data2) {
123
136
  return [];
124
137
  }
138
+ const nullishHandledData = getInterpolatedData(
139
+ props.data2,
140
+ showDataPointsForMissingValues,
141
+ interpolateMissingValues,
142
+ onlyPositive
143
+ );
125
144
  if (props.yAxisOffset) {
126
- return clone(props.data2).map((item) => {
145
+ return nullishHandledData.map((item) => {
127
146
  item.value = item.value - (props.yAxisOffset ?? 0);
128
147
  return item;
129
148
  });
130
149
  }
131
- return props.data2;
150
+ return nullishHandledData;
132
151
  }, [props.yAxisOffset, props.data2]);
133
152
  const data3 = useMemo(() => {
134
153
  if (!props.data3) {
135
154
  return [];
136
155
  }
156
+ const nullishHandledData = getInterpolatedData(
157
+ props.data3,
158
+ showDataPointsForMissingValues,
159
+ interpolateMissingValues,
160
+ onlyPositive
161
+ );
137
162
  if (props.yAxisOffset) {
138
- return clone(props.data3).map((item) => {
163
+ return nullishHandledData.map((item) => {
139
164
  item.value = item.value - (props.yAxisOffset ?? 0);
140
165
  return item;
141
166
  });
142
167
  }
143
- return props.data3;
168
+ return nullishHandledData;
144
169
  }, [props.yAxisOffset, props.data3]);
145
170
  const data4 = useMemo(() => {
146
171
  if (!props.data4) {
147
172
  return [];
148
173
  }
174
+ const nullishHandledData = getInterpolatedData(
175
+ props.data4,
176
+ showDataPointsForMissingValues,
177
+ interpolateMissingValues,
178
+ onlyPositive
179
+ );
149
180
  if (props.yAxisOffset) {
150
- return clone(props.data4).map((item) => {
181
+ return nullishHandledData.map((item) => {
151
182
  item.value = item.value - (props.yAxisOffset ?? 0);
152
183
  return item;
153
184
  });
154
185
  }
155
- return props.data4;
186
+ return nullishHandledData;
156
187
  }, [props.yAxisOffset, props.data4]);
157
188
  const data5 = useMemo(() => {
158
189
  if (!props.data5) {
159
190
  return [];
160
191
  }
192
+ const nullishHandledData = getInterpolatedData(
193
+ props.data5,
194
+ showDataPointsForMissingValues,
195
+ interpolateMissingValues,
196
+ onlyPositive
197
+ );
161
198
  if (props.yAxisOffset) {
162
- return clone(props.data5).map((item) => {
199
+ return nullishHandledData.map((item) => {
163
200
  item.value = item.value - (props.yAxisOffset ?? 0);
164
201
  return item;
165
202
  });
166
203
  }
167
- return props.data5;
204
+ return nullishHandledData;
168
205
  }, [props.yAxisOffset, props.data5]);
169
206
 
170
207
  const secondaryData =
171
208
  getSecondaryDataWithOffsetIncluded(
172
209
  props.secondaryData,
173
- props.secondaryYAxis
210
+ props.secondaryYAxis,
211
+ showDataPointsForMissingValues,
212
+ interpolateMissingValues,
213
+ onlyPositive
174
214
  ) || [];
175
215
 
176
- const dataSet = props.dataSet;
216
+ let dataSet = props.dataSet;
217
+ if (dataSet?.length) {
218
+ dataSet = dataSet.map((dataSetItem) => ({
219
+ ...dataSetItem,
220
+ data: getInterpolatedData(
221
+ dataSetItem.data,
222
+ showDataPointsForMissingValues,
223
+ interpolateMissingValues,
224
+ onlyPositive
225
+ ),
226
+ }));
227
+ }
177
228
  const data0 = useMemo(() => {
178
229
  if (props.yAxisOffset) {
179
230
  return dataSet?.[0]?.data;
@@ -224,7 +275,9 @@ export const useLineChart = (props: extendedLineChartPropsType) => {
224
275
  const startIndex5 = props.startIndex5 || 0;
225
276
  const endIndex5 = props.endIndex5 ?? data5.length - 1;
226
277
 
227
- const lineSegments = props.lineSegments;
278
+ const lineSegments = !interpolateMissingValues
279
+ ? getLineSegmentsForMissingValues(data)
280
+ : props.lineSegments;
228
281
  const lineSegments2 = props.lineSegments2;
229
282
  const lineSegments3 = props.lineSegments3;
230
283
  const lineSegments4 = props.lineSegments4;
@@ -242,7 +295,7 @@ export const useLineChart = (props: extendedLineChartPropsType) => {
242
295
  const endSpacing =
243
296
  props.endSpacing ?? (adjustToWidth ? 0 : LineDefaults.endSpacing);
244
297
 
245
- const thickness = props.thickness || LineDefaults.thickness;
298
+ const thickness = props.thickness ?? LineDefaults.thickness;
246
299
 
247
300
  const yAxisLabelWidth =
248
301
  props.yAxisLabelWidth ??
@@ -693,24 +746,27 @@ export const useLineChart = (props: extendedLineChartPropsType) => {
693
746
  );
694
747
  };
695
748
 
696
- const getNextPoint = (data, index, around) => {
749
+ const getNextPoint = (data, index, around, before) => {
697
750
  const isLast = index === data.length - 1;
698
- return isLast && !around
751
+ return isLast && !(around || before)
699
752
  ? " "
700
753
  : " L" +
701
- (getX(index) + (around ? (isLast ? 0 : spacing / 2) : spacing)) +
754
+ (getX(index) +
755
+ (around ? (isLast ? 0 : spacing / 2) : before ? 0 : spacing)) +
702
756
  " " +
703
757
  getY(data[index].value) +
704
758
  " ";
705
759
  };
706
760
  const getStepPath = (data, i) => {
707
761
  const around = edgePosition === EdgePosition.AROUND_DATA_POINT;
762
+ const before = edgePosition === EdgePosition.BEFORE_DATA_POINT;
708
763
  return (
709
764
  "L" +
710
- (getX(i) - (around && i > 0 ? spacing / 2 : 0)) +
765
+ (getX(i) -
766
+ (around && i > 0 ? spacing / 2 : before && i > 0 ? spacing : 0)) +
711
767
  " " +
712
768
  getY(data[i].value) +
713
- getNextPoint(data, i, around)
769
+ getNextPoint(data, i, around, before)
714
770
  );
715
771
  };
716
772
 
@@ -319,6 +319,10 @@ export type LineChartPropsType = {
319
319
  onEndReached?: () => void;
320
320
  onStartReached?: () => void;
321
321
  endReachedOffset?: number;
322
+
323
+ showDataPointsForMissingValues?: boolean;
324
+ interpolateMissingValues?: boolean;
325
+ onlyPositive?: boolean;
322
326
  };
323
327
 
324
328
  export type lineDataItem = {
@@ -323,8 +323,12 @@ export const useBarAndLineChartsWrapper = (
323
323
  );
324
324
  };
325
325
 
326
- const isCloseToStart = ({ layoutMeasurement, contentOffset }) => {
327
- return layoutMeasurement.width + contentOffset.x <= initialSpacing;
326
+ // const isCloseToStart = ({ layoutMeasurement, contentOffset }) => {
327
+ // return layoutMeasurement.width + contentOffset.x <= initialSpacing;
328
+ // };
329
+
330
+ const isCloseToStart = ({ contentOffset }) => {
331
+ return contentOffset.x <= initialSpacing;
328
332
  };
329
333
 
330
334
  useEffect(() => {
@@ -146,12 +146,14 @@ export const BarDefaults = {
146
146
  animationDuration: 800,
147
147
  opacity: 1,
148
148
  isThreeD: false,
149
+ frontColor: "black",
149
150
  threeDBarGradientColor: "white",
150
151
  threeDBarFrontColor: "#C0CA3A",
151
152
  threeDBarSideColor: "#887A24",
152
153
  threeDBarTopColor: "#D9E676",
153
154
  endReachedOffset: defaultEndReachedOffset,
154
155
  focusedBarFrontColor: 'lightgreen',
156
+ focusedThreeDBarFrontColor: '#B0B929',
155
157
  focusedBarSideColor: '#776913',
156
158
  focusedBarTopColor: '#C8D565',
157
159
  };
@@ -232,7 +234,7 @@ export const LineDefaults = {
232
234
  stripWidth: 2,
233
235
  unFocusOnPressOut: true,
234
236
  delayBeforeUnFocus: 300,
235
- edgePosition: EdgePosition.AT_DATA_POINT,
237
+ edgePosition: EdgePosition.AFTER_DATA_POINT,
236
238
  endReachedOffset: defaultEndReachedOffset,
237
239
  };
238
240
 
@@ -1,3 +1,4 @@
1
+ import { lineDataItem } from "../LineChart/types";
1
2
  import {
2
3
  AxesAndRulesDefaults,
3
4
  BarDefaults,
@@ -720,15 +721,25 @@ export const getExtendedContainerHeightWithPadding = (
720
721
 
721
722
  export const getSecondaryDataWithOffsetIncluded = (
722
723
  secondaryData?: any,
723
- secondaryYAxis?: any
724
+ secondaryYAxis?: any,
725
+ showDataPointsForMissingValues?: boolean,
726
+ interpolateMissingValues?: boolean,
727
+ onlyPositive?: boolean
724
728
  ) => {
725
- if (secondaryData && secondaryYAxis?.yAxisOffset) {
726
- return secondaryData?.map((item) => {
729
+ if (!secondaryData) return secondaryData;
730
+ const nullishHandledData = getInterpolatedData(
731
+ secondaryData,
732
+ showDataPointsForMissingValues,
733
+ interpolateMissingValues,
734
+ onlyPositive
735
+ );
736
+ if (secondaryYAxis?.yAxisOffset) {
737
+ return nullishHandledData.map((item) => {
727
738
  item.value = item.value - (secondaryYAxis?.yAxisOffset ?? 0);
728
739
  return item;
729
740
  });
730
741
  }
731
- return secondaryData;
742
+ return nullishHandledData;
732
743
  };
733
744
 
734
745
  export const getArrowProperty = (
@@ -1155,12 +1166,22 @@ export const getBarFrontColor = (
1155
1166
  isFocused,
1156
1167
  focusedBarConfig,
1157
1168
  itemFrontColor,
1158
- frontColor
1169
+ frontColor,
1170
+ isThreeD
1159
1171
  ) => {
1160
1172
  if (isFocused) {
1161
- return focusedBarConfig?.frontColor ?? BarDefaults.focusedBarFrontColor;
1173
+ return (
1174
+ focusedBarConfig?.color ??
1175
+ (isThreeD
1176
+ ? BarDefaults.focusedThreeDBarFrontColor
1177
+ : BarDefaults.focusedBarFrontColor)
1178
+ );
1162
1179
  }
1163
- return itemFrontColor || frontColor || "";
1180
+ return (
1181
+ itemFrontColor ||
1182
+ frontColor ||
1183
+ (isThreeD ? BarDefaults.threeDBarFrontColor : BarDefaults.frontColor)
1184
+ );
1164
1185
  };
1165
1186
 
1166
1187
  export const getBarSideColor = (
@@ -1199,3 +1220,155 @@ export const getBarWidth = (
1199
1220
  }
1200
1221
  return localBarWidth;
1201
1222
  };
1223
+
1224
+ export const getInterpolatedData = (
1225
+ dataParam: lineDataItem[],
1226
+ showDataPointsForMissingValues?: boolean,
1227
+ interpolateMissingValues?: boolean,
1228
+ onlyPositive?: boolean
1229
+ ): lineDataItem[] => {
1230
+ if (!interpolateMissingValues) {
1231
+ return dataParam.map((item) => {
1232
+ if (typeof item.value !== "number") {
1233
+ if (showDataPointsForMissingValues) return { ...item, value: 0 };
1234
+ return { ...item, value: 0, hideDataPoint: true };
1235
+ }
1236
+ return item;
1237
+ });
1238
+ }
1239
+ if (!interpolateMissingValues) return dataParam;
1240
+ const data = clone(dataParam);
1241
+ const n = data.length;
1242
+
1243
+ /************** PRE-PROCESSING **************/
1244
+ let numericValue;
1245
+ const numericValuesLength = data.filter((item) => {
1246
+ const isNum = typeof item.value === "number";
1247
+ if (isNum) {
1248
+ numericValue = item.value;
1249
+ return true;
1250
+ }
1251
+ return false;
1252
+ }).length;
1253
+
1254
+ if (!numericValuesLength) return [];
1255
+
1256
+ if (numericValuesLength === 1) {
1257
+ data.forEach((item) => {
1258
+ if (!showDataPointsForMissingValues && typeof item.value !== "number") {
1259
+ item.hideDataPoint = true;
1260
+ }
1261
+ item.value = numericValue;
1262
+ });
1263
+ return data;
1264
+ }
1265
+ /**********************************************************************/
1266
+
1267
+ data.forEach((item, index) => {
1268
+ if (typeof item.value === "number") return;
1269
+ // Cut the line in 2 halves-> pre and post
1270
+ // Now there are 4 possibilities-
1271
+ // 1. Both pre and post have valid values
1272
+ // 2. Only pre has valid value
1273
+ // 3. Only post has valid value
1274
+ // 4. None has valid value -> this is already handled in preprocessing
1275
+
1276
+ const pre = data.slice(0, index);
1277
+ const post = data.slice(index + 1, n);
1278
+
1279
+ const preValidIndex = pre.findLastIndex(
1280
+ (item) => typeof item.value === "number"
1281
+ );
1282
+ const postValidInd = post.findIndex(
1283
+ (item) => typeof item.value === "number"
1284
+ );
1285
+ const postValidIndex = postValidInd + index + 1;
1286
+
1287
+ let count, step;
1288
+
1289
+ // 1. Both pre and post have valid values
1290
+ if (preValidIndex !== -1 && postValidInd !== -1) {
1291
+ count = postValidIndex - preValidIndex;
1292
+ step = (data[postValidIndex].value - data[preValidIndex].value) / count;
1293
+ data[index].value =
1294
+ data[preValidIndex].value + step * (index - preValidIndex);
1295
+ }
1296
+
1297
+ // 2. Only pre has valid value
1298
+ else if (preValidIndex !== -1 && postValidInd === -1) {
1299
+ // Now there are 2 possibilities-
1300
+ // 1. There's only 1 valid value in the pre -> this is already handled in preprocessing
1301
+ // 2. There are more than valid values in pre
1302
+ const secondPre = data.slice(0, preValidIndex);
1303
+ const secondPreIndex = secondPre.findLastIndex(
1304
+ (item) => typeof item.value === "number"
1305
+ );
1306
+
1307
+ count = preValidIndex - secondPreIndex;
1308
+ step = (data[secondPreIndex].value - data[preValidIndex].value) / count;
1309
+ data[index].value =
1310
+ data[preValidIndex].value - step * (index - preValidIndex);
1311
+ }
1312
+
1313
+ // 3. Only post has valid value
1314
+ else if (preValidIndex === -1 && postValidInd !== -1) {
1315
+ // Now there are 2 possibilities-
1316
+ // 1. There's only 1 valid value in the post -> this is already handled in preprocessing
1317
+ // 2. There are more than valid values in post
1318
+
1319
+ const secondPost = data.slice(postValidIndex + 1, n);
1320
+ const secondPostInd = secondPost.findIndex(
1321
+ (item) => typeof item.value === "number"
1322
+ );
1323
+ const secondPostIndex = secondPostInd + postValidIndex + 1;
1324
+
1325
+ count = secondPostIndex - postValidIndex;
1326
+ step = (data[secondPostIndex].value - data[postValidIndex].value) / count;
1327
+ data[index].value =
1328
+ data[postValidIndex].value - step * (postValidIndex - index);
1329
+ }
1330
+
1331
+ // hide data point (since it is interpolated)
1332
+ if (!showDataPointsForMissingValues) {
1333
+ item.hideDataPoint = true;
1334
+ }
1335
+ });
1336
+ return onlyPositive
1337
+ ? data.map((item) => ({ ...item, value: Math.max(item.value, 0) }))
1338
+ : data;
1339
+ };
1340
+
1341
+ export const getLineSegmentsForMissingValues = (
1342
+ data: lineDataItem[]
1343
+ ): LineSegment[] => {
1344
+ let i,
1345
+ n = data.length;
1346
+ const numericValuesLength = data.filter(
1347
+ (item) => typeof item.value === "number"
1348
+ ).length;
1349
+ if (!numericValuesLength) return [];
1350
+ const segments: LineSegment[] = [];
1351
+ for (i = 0; i < n; i++) {
1352
+ if (typeof data[i].value !== "number") {
1353
+ const nextValidInd = data
1354
+ .slice(i + 1, n)
1355
+ .findIndex((item) => typeof item.value === "number");
1356
+ if (nextValidInd === -1) {
1357
+ segments.push({
1358
+ startIndex: Math.max(i - 1, 0),
1359
+ endIndex: n,
1360
+ color: "transparent",
1361
+ });
1362
+ break;
1363
+ }
1364
+ const nextValidIndex = nextValidInd + i + 1;
1365
+ segments.push({
1366
+ startIndex: Math.max(i - 1, 0),
1367
+ endIndex: nextValidIndex,
1368
+ color: "transparent",
1369
+ });
1370
+ i = nextValidIndex;
1371
+ }
1372
+ }
1373
+ return segments;
1374
+ };
@@ -16,8 +16,9 @@ export enum CurveType {
16
16
  }
17
17
 
18
18
  export enum EdgePosition {
19
- AT_DATA_POINT,
19
+ AFTER_DATA_POINT,
20
20
  AROUND_DATA_POINT,
21
+ BEFORE_DATA_POINT,
21
22
  }
22
23
 
23
24
  export type RulesConfig = {