react-native-gifted-charts 1.3.17 → 1.3.18

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": "react-native-gifted-charts",
3
- "version": "1.3.17",
3
+ "version": "1.3.18",
4
4
  "description": "The most complete library for Bar, Line, Area, Pie, Donut and Stacked Bar charts in React Native. Allows 2D, 3D, gradient, animations and live data updates.",
5
5
  "main": "src/index.tsx",
6
6
  "files": [
@@ -6,6 +6,7 @@ import {
6
6
  getArrowPoints,
7
7
  getAxesAndRulesProps,
8
8
  getExtendedContainerHeightWithPadding,
9
+ getLineConfigForBarChart,
9
10
  getSecondaryDataWithOffsetIncluded,
10
11
  getXForLineInBar,
11
12
  getYForLineInBar,
@@ -29,6 +30,7 @@ import {Pointer} from '../Components/common/Pointer';
29
30
  export const BarChart = (props: BarChartPropsType) => {
30
31
  const scrollRef = props.scrollRef ?? useRef(null);
31
32
  const [points, setPoints] = useState('');
33
+ const [points2, setPoints2] = useState('');
32
34
  const [arrowPoints, setArrowPoints] = useState('');
33
35
  const [selectedIndex, setSelectedIndex] = useState(-1);
34
36
  const showLine = props.showLine || BarDefaults.showLine;
@@ -81,6 +83,8 @@ export const BarChart = (props: BarChartPropsType) => {
81
83
  return props.lineData;
82
84
  }, [props.yAxisOffset, props.lineData, data, props.stackData]);
83
85
 
86
+ const lineData2 = props.lineData2;
87
+
84
88
  const lineBehindBars = props.lineBehindBars || BarDefaults.lineBehindBars;
85
89
 
86
90
  defaultLineConfig.initialSpacing = initialSpacing;
@@ -88,75 +92,10 @@ export const BarChart = (props: BarChartPropsType) => {
88
92
  defaultLineConfig.animationDuration = animationDuration;
89
93
 
90
94
  const lineConfig = props.lineConfig
91
- ? {
92
- initialSpacing:
93
- props.lineConfig.initialSpacing ?? defaultLineConfig.initialSpacing,
94
- curved: props.lineConfig.curved || defaultLineConfig.curved,
95
- curvature: props.lineConfig.curvature ?? defaultLineConfig.curvature,
96
- curveType: props.lineConfig.curveType ?? defaultLineConfig.curveType,
97
- isAnimated: props.lineConfig.isAnimated || defaultLineConfig.isAnimated,
98
- animationDuration:
99
- props.lineConfig.animationDuration ||
100
- defaultLineConfig.animationDuration,
101
- thickness: props.lineConfig.thickness || defaultLineConfig.thickness,
102
- color: props.lineConfig.color || defaultLineConfig.color,
103
- hideDataPoints:
104
- props.lineConfig.hideDataPoints || defaultLineConfig.hideDataPoints,
105
- dataPointsShape:
106
- props.lineConfig.dataPointsShape || defaultLineConfig.dataPointsShape,
107
- dataPointsHeight:
108
- props.lineConfig.dataPointsHeight ||
109
- defaultLineConfig.dataPointsHeight,
110
- dataPointsWidth:
111
- props.lineConfig.dataPointsWidth || defaultLineConfig.dataPointsWidth,
112
- dataPointsColor:
113
- props.lineConfig.dataPointsColor || defaultLineConfig.dataPointsColor,
114
- dataPointsRadius:
115
- props.lineConfig.dataPointsRadius ||
116
- defaultLineConfig.dataPointsRadius,
117
- textColor: props.lineConfig.textColor || defaultLineConfig.textColor,
118
- textFontSize:
119
- props.lineConfig.textFontSize || defaultLineConfig.textFontSize,
120
- textShiftX: props.lineConfig.textShiftX || defaultLineConfig.textShiftX,
121
- textShiftY: props.lineConfig.textShiftY || defaultLineConfig.textShiftY,
122
- shiftX: props.lineConfig.shiftX || defaultLineConfig.shiftX,
123
- shiftY: props.lineConfig.shiftY || defaultLineConfig.shiftY,
124
- delay: props.lineConfig.delay || defaultLineConfig.delay,
125
- startIndex: props.lineConfig.startIndex || defaultLineConfig.startIndex,
126
- endIndex:
127
- props.lineConfig.endIndex === 0
128
- ? 0
129
- : props.lineConfig.endIndex || defaultLineConfig.endIndex,
130
-
131
- showArrow: props.lineConfig.showArrow ?? defaultLineConfig.showArrow,
132
- arrowConfig: {
133
- length:
134
- props.lineConfig.arrowConfig?.length ??
135
- defaultLineConfig.arrowConfig?.length,
136
- width:
137
- props.lineConfig.arrowConfig?.width ??
138
- defaultLineConfig.arrowConfig?.width,
139
-
140
- strokeWidth:
141
- props.lineConfig.arrowConfig?.strokeWidth ??
142
- defaultLineConfig.arrowConfig?.strokeWidth,
143
-
144
- strokeColor:
145
- props.lineConfig.arrowConfig?.strokeColor ??
146
- defaultLineConfig.arrowConfig?.strokeColor,
147
-
148
- fillColor:
149
- props.lineConfig.arrowConfig?.fillColor ??
150
- defaultLineConfig.arrowConfig?.fillColor,
151
-
152
- showArrowBase:
153
- props.lineConfig.arrowConfig?.showArrowBase ??
154
- defaultLineConfig.arrowConfig?.showArrowBase,
155
- },
156
- customDataPoint: props.lineConfig.customDataPoint,
157
- isSecondary:
158
- props.lineConfig.isSecondary ?? defaultLineConfig.isSecondary,
159
- }
95
+ ? getLineConfigForBarChart(props.lineConfig)
96
+ : defaultLineConfig;
97
+ const lineConfig2 = props.lineConfig2
98
+ ? getLineConfigForBarChart(props.lineConfig2)
160
99
  : defaultLineConfig;
161
100
  const noOfSections = props.noOfSections ?? AxesAndRulesDefaults.noOfSections;
162
101
  const containerHeight =
@@ -397,7 +336,8 @@ export const BarChart = (props: BarChartPropsType) => {
397
336
 
398
337
  useEffect(() => {
399
338
  if (showLine) {
400
- let pp = '';
339
+ let pp = '',
340
+ pp2 = '';
401
341
  const firstBarWidth =
402
342
  (props.stackData ?? data)?.[0].barWidth ?? props.barWidth ?? 30;
403
343
  if (!lineConfig.curved) {
@@ -488,6 +428,67 @@ export const BarChart = (props: BarChartPropsType) => {
488
428
  setPoints(xx);
489
429
  }
490
430
  }
431
+ if (lineData2?.length) {
432
+ if (!lineConfig2?.curved) {
433
+ for (let i = 0; i < lineData2.length; i++) {
434
+ if (i < lineConfig2.startIndex || i > lineConfig2.endIndex)
435
+ continue;
436
+ const currentBarWidth =
437
+ data?.[i]?.barWidth ?? props.barWidth ?? BarDefaults.barWidth;
438
+ const currentValue = lineData2[i].value;
439
+ pp2 +=
440
+ 'L' +
441
+ getXForLineInBar(
442
+ i,
443
+ firstBarWidth,
444
+ currentBarWidth,
445
+ yAxisLabelWidth,
446
+ lineConfig2,
447
+ spacing,
448
+ ) +
449
+ ' ' +
450
+ getYForLineInBar(
451
+ currentValue,
452
+ lineConfig2.shiftY,
453
+ containerHeight,
454
+ lineConfig2.isSecondary ? secondaryMaxValue : maxValue,
455
+ ) +
456
+ ' ';
457
+ }
458
+ setPoints2(pp2.replace('L', 'M'));
459
+ } else {
460
+ let p2Array: Array<Array<number>> = [];
461
+ for (let i = 0; i < lineData2.length; i++) {
462
+ if (i < lineConfig2.startIndex || i > lineConfig2.endIndex)
463
+ continue;
464
+ const currentBarWidth =
465
+ data?.[i]?.barWidth ?? props.barWidth ?? BarDefaults.barWidth;
466
+ const currentValue = lineData2[i].value;
467
+ p2Array.push([
468
+ getXForLineInBar(
469
+ i,
470
+ firstBarWidth,
471
+ currentBarWidth,
472
+ yAxisLabelWidth,
473
+ lineConfig2,
474
+ spacing,
475
+ ),
476
+ getYForLineInBar(
477
+ currentValue,
478
+ lineConfig2.shiftY,
479
+ containerHeight,
480
+ lineConfig2.isSecondary ? secondaryMaxValue : maxValue,
481
+ ),
482
+ ]);
483
+ let xx = svgPath(
484
+ p2Array,
485
+ lineConfig2.curveType,
486
+ lineConfig2.curvature,
487
+ );
488
+ setPoints2(xx);
489
+ }
490
+ }
491
+ }
491
492
  if (lineConfig.isAnimated) {
492
493
  setTimeout(() => decreaseWidth(), lineConfig.delay || 0);
493
494
  }
@@ -866,11 +867,14 @@ export const BarChart = (props: BarChartPropsType) => {
866
867
  spacing,
867
868
  showLine,
868
869
  lineConfig,
870
+ lineConfig2,
869
871
  maxValue,
870
872
  lineData,
873
+ lineData2,
871
874
  animatedWidth,
872
875
  lineBehindBars,
873
876
  points,
877
+ points2,
874
878
  arrowPoints,
875
879
  renderChartContent,
876
880
  remainingScrollViewProps,
@@ -53,7 +53,9 @@ export type BarChartPropsType = {
53
53
  sideWidth?: number;
54
54
  showLine?: boolean;
55
55
  lineData?: any;
56
+ lineData2?: any;
56
57
  lineConfig?: lineConfigType;
58
+ lineConfig2?: lineConfigType;
57
59
  lineBehindBars?: boolean;
58
60
 
59
61
  cappedBars?: boolean;
@@ -44,11 +44,14 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
44
44
  spacing,
45
45
  showLine,
46
46
  lineConfig,
47
+ lineConfig2,
47
48
  maxValue,
48
49
  lineData,
50
+ lineData2,
49
51
  animatedWidth,
50
52
  lineBehindBars,
51
53
  points,
54
+ points2,
52
55
  arrowPoints,
53
56
  renderChartContent,
54
57
  remainingScrollViewProps,
@@ -114,7 +117,8 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
114
117
  axesAndRulesProps.rulesThickness ?? AxesAndRulesDefaults.rulesThickness;
115
118
  const rulesColor =
116
119
  axesAndRulesProps.rulesColor ?? AxesAndRulesDefaults.rulesColor;
117
- const rulesConfigArray = axesAndRulesProps.rulesConfigArray ?? AxesAndRulesDefaults.rulesConfigArray;
120
+ const rulesConfigArray =
121
+ axesAndRulesProps.rulesConfigArray ?? AxesAndRulesDefaults.rulesConfigArray;
118
122
  const showYAxisIndices = axesAndRulesProps.showYAxisIndices ?? false;
119
123
  const yAxisIndicesHeight =
120
124
  axesAndRulesProps.yAxisIndicesHeight ??
@@ -250,6 +254,12 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
250
254
  scrollEventThrottle,
251
255
  xAxisLabelsVerticalShift,
252
256
  };
257
+ const lineInBarChartProps2 = {
258
+ ...lineInBarChartProps,
259
+ lineConfig: lineConfig2,
260
+ points: points2,
261
+ data: lineData2,
262
+ };
253
263
  const extendedContainerHeight = containerHeight + 10;
254
264
  const containerHeightIncludingBelowXAxis =
255
265
  extendedContainerHeight + noOfSectionsBelowXAxis * stepHeight;
@@ -356,8 +366,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
356
366
  ? 0
357
367
  : yAxisLabelWidth + yAxisThickness,
358
368
  position: 'absolute',
359
- bottom:
360
- (chartType === chartTypes.LINE_BI_COLOR ? 0 : xAxisThickness),
369
+ bottom: chartType === chartTypes.LINE_BI_COLOR ? 0 : xAxisThickness,
361
370
  },
362
371
  !!props.width && {width: props.width},
363
372
  horizontal && {
@@ -404,6 +413,12 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
404
413
  // Only For Bar Charts-
405
414
  showLine ? <RenderLineInBarChart {...lineInBarChartProps} /> : null
406
415
  }
416
+ {
417
+ // Only For Bar Charts-
418
+ showLine && points2?.length ? (
419
+ <RenderLineInBarChart {...lineInBarChartProps2} />
420
+ ) : null
421
+ }
407
422
  {
408
423
  // Only For Line Charts-
409
424
  chartType === chartTypes.LINE &&
@@ -1344,12 +1344,15 @@ export const LineChartBicolor = (props: propTypes) => {
1344
1344
  setSelectedIndex,
1345
1345
  spacing,
1346
1346
  showLine: false,
1347
- lineConfig: null,
1347
+ lineConfig: null, // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
1348
+ lineConfig2: null, // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
1348
1349
  maxValue,
1349
1350
  lineData: [], // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
1351
+ lineData2: [], // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
1350
1352
  animatedWidth,
1351
1353
  lineBehindBars: false,
1352
1354
  points: pointsArray,
1355
+ points2: '', // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
1353
1356
  arrowPoints: [], // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
1354
1357
  renderChartContent,
1355
1358
  remainingScrollViewProps: {},
@@ -35,6 +35,9 @@ import {
35
35
  getAllArrowProperties,
36
36
  computeMaxAndMinItems,
37
37
  clone,
38
+ getCurvePathWithSegments,
39
+ getSegmentedPathObjects,
40
+ getSegmentString,
38
41
  } from '../utils';
39
42
  import {
40
43
  AxesAndRulesDefaults,
@@ -46,7 +49,11 @@ import {
46
49
  } from '../utils/constants';
47
50
  import BarAndLineChartsWrapper from '../Components/BarAndLineChartsWrapper';
48
51
  import {LineChartPropsType, itemType} from './types';
49
- import {BarAndLineChartsWrapperTypes} from '../utils/types';
52
+ import {
53
+ BarAndLineChartsWrapperTypes,
54
+ EdgePosition,
55
+ LineSvgProps,
56
+ } from '../utils/types';
50
57
  import {StripAndLabel} from '../Components/common/StripAndLabel';
51
58
  import {Pointer} from '../Components/common/Pointer';
52
59
 
@@ -228,6 +235,12 @@ export const LineChart = (props: LineChartPropsType) => {
228
235
  const startIndex5 = props.startIndex5 || 0;
229
236
  const endIndex5 = props.endIndex5 ?? data5.length - 1;
230
237
 
238
+ const lineSegments = props.lineSegments;
239
+ const lineSegments2 = props.lineSegments2;
240
+ const lineSegments3 = props.lineSegments3;
241
+ const lineSegments4 = props.lineSegments4;
242
+ const lineSegments5 = props.lineSegments5;
243
+
231
244
  if (!initialData) {
232
245
  initialData = [...data];
233
246
  animations = initialData.map(item => new Animated.Value(item.value));
@@ -387,6 +400,8 @@ export const LineChart = (props: LineChartPropsType) => {
387
400
  const stepChart4 = props.stepChart4 ?? false;
388
401
  const stepChart5 = props.stepChart5 ?? false;
389
402
 
403
+ const edgePosition = props.edgePosition ?? LineDefaults.edgePosition;
404
+
390
405
  const textFontSize1 =
391
406
  props.textFontSize1 ?? props.textFontSize ?? LineDefaults.textFontSize;
392
407
  const textFontSize2 =
@@ -792,6 +807,35 @@ export const LineChart = (props: LineChartPropsType) => {
792
807
  ' '
793
808
  );
794
809
  };
810
+
811
+ const getNextPoint = (data, index, around) => {
812
+ const isLast = index === data.length - 1;
813
+ return isLast && !around
814
+ ? ' '
815
+ : ' L' +
816
+ (getX(index) + (around ? (isLast ? 0 : spacing / 2) : spacing)) +
817
+ ' ' +
818
+ getY(data[index].value) +
819
+ ' ';
820
+ };
821
+ const getStepPath = (data, i) => {
822
+ const around = edgePosition === EdgePosition.AROUND_DATA_POINT;
823
+ return (
824
+ 'L' +
825
+ (getX(i) - (around && i > 0 ? spacing / 2 : 0)) +
826
+ ' ' +
827
+ getY(data[i].value) +
828
+ getNextPoint(data, i, around)
829
+ );
830
+ };
831
+ const getSegmentPath = (data, i, lineSegment) =>
832
+ 'L' +
833
+ getX(i) +
834
+ ' ' +
835
+ getY(data[i].value) +
836
+ ' ' +
837
+ getSegmentString(lineSegment, i);
838
+
795
839
  useEffect(() => {
796
840
  let pp = '',
797
841
  pp2 = '',
@@ -802,82 +846,38 @@ export const LineChart = (props: LineChartPropsType) => {
802
846
  for (let i = 0; i < data.length; i++) {
803
847
  if (i >= startIndex1 && i <= endIndex1 && !animateOnDataChange) {
804
848
  if (stepChart || stepChart1) {
805
- pp +=
806
- 'L' +
807
- (getX(i) - spacing / 2) +
808
- ' ' +
809
- getY(data[i].value) +
810
- ' L' +
811
- (getX(i) + spacing / 2) +
812
- ' ' +
813
- getY(data[i].value) +
814
- ' ';
849
+ pp += getStepPath(data, i);
815
850
  } else {
816
- pp += 'L' + getX(i) + ' ' + getY(data[i].value) + ' ';
851
+ pp += getSegmentPath(data, i, lineSegments);
817
852
  }
818
853
  }
819
854
  if (data2.length && i >= startIndex2 && i <= endIndex2) {
820
855
  if (stepChart || stepChart2) {
821
- pp2 +=
822
- 'L' +
823
- (getX(i) - spacing / 2) +
824
- ' ' +
825
- getY(data2[i].value) +
826
- ' L' +
827
- (getX(i) + spacing / 2) +
828
- ' ' +
829
- getY(data2[i].value) +
830
- ' ';
856
+ pp2 += getStepPath(data2, i);
857
+ (' ');
831
858
  } else {
832
- pp2 += 'L' + getX(i) + ' ' + getY(data2[i].value) + ' ';
859
+ pp2 += getSegmentPath(data2, i, lineSegments2);
833
860
  }
834
861
  }
835
862
  if (data3.length && i >= startIndex3 && i <= endIndex3) {
836
863
  if (stepChart || stepChart3) {
837
- pp3 +=
838
- 'L' +
839
- (getX(i) - spacing / 2) +
840
- ' ' +
841
- getY(data3[i].value) +
842
- ' L' +
843
- (getX(i) + spacing / 2) +
844
- ' ' +
845
- getY(data3[i].value) +
846
- ' ';
864
+ pp3 += getStepPath(data3, i);
847
865
  } else {
848
- pp3 += 'L' + getX(i) + ' ' + getY(data3[i].value) + ' ';
866
+ pp3 += getSegmentPath(data2, i, lineSegments2);
849
867
  }
850
868
  }
851
869
  if (data4.length && i >= startIndex4 && i <= endIndex4) {
852
870
  if (stepChart || stepChart4) {
853
- pp4 +=
854
- 'L' +
855
- (getX(i) - spacing / 2) +
856
- ' ' +
857
- getY(data4[i].value) +
858
- ' L' +
859
- (getX(i) + spacing / 2) +
860
- ' ' +
861
- getY(data4[i].value) +
862
- ' ';
871
+ pp4 += getStepPath(data4, i);
863
872
  } else {
864
- pp4 += 'L' + getX(i) + ' ' + getY(data4[i].value) + ' ';
873
+ pp4 += getSegmentPath(data4, i, lineSegments4);
865
874
  }
866
875
  }
867
876
  if (data5.length && i >= startIndex5 && i <= endIndex5) {
868
877
  if (stepChart || stepChart5) {
869
- pp5 +=
870
- 'L' +
871
- (getX(i) - spacing / 2) +
872
- ' ' +
873
- getY(data5[i].value) +
874
- ' L' +
875
- (getX(i) + spacing / 2) +
876
- ' ' +
877
- getY(data5[i].value) +
878
- ' ';
878
+ pp5 += getStepPath(data5, i);
879
879
  } else {
880
- pp5 += 'L' + getX(i) + ' ' + getY(data5[i].value) + ' ';
880
+ pp5 += getSegmentPath(data5, i, lineSegments5);
881
881
  }
882
882
  }
883
883
  }
@@ -1087,11 +1087,11 @@ export const LineChart = (props: LineChartPropsType) => {
1087
1087
  let xx4 = svgPath(p4Array, curveType, curvature);
1088
1088
  let xx5 = svgPath(p5Array, curveType, curvature);
1089
1089
 
1090
- setPoints(xx);
1091
- setPoints2(xx2);
1092
- setPoints3(xx3);
1093
- setPoints4(xx4);
1094
- setPoints5(xx5);
1090
+ setPoints(getCurvePathWithSegments(xx, lineSegments));
1091
+ setPoints2(getCurvePathWithSegments(xx2, lineSegments2));
1092
+ setPoints3(getCurvePathWithSegments(xx3, lineSegments3));
1093
+ setPoints4(getCurvePathWithSegments(xx4, lineSegments4));
1094
+ setPoints5(getCurvePathWithSegments(xx5, lineSegments5));
1095
1095
 
1096
1096
  if (data.length > 1 && (props.showArrow1 || props.showArrows)) {
1097
1097
  let arrowTipY = p1Array[p1Array.length - 1][1];
@@ -2167,39 +2167,63 @@ export const LineChart = (props: LineChartPropsType) => {
2167
2167
  arrowStrokeColor,
2168
2168
  arrowFillColor,
2169
2169
  ) => {
2170
+ const isCurved = points.includes('C');
2171
+ let ar: [any] = [{}];
2172
+ if (points.includes('segmentStart')) {
2173
+ ar = getSegmentedPathObjects(
2174
+ points,
2175
+ color,
2176
+ currentLineThickness,
2177
+ thickness,
2178
+ strokeDashArray,
2179
+ isCurved,
2180
+ );
2181
+ }
2182
+ const lineSvgPropsOuter: LineSvgProps = {
2183
+ d: points,
2184
+ fill: 'none',
2185
+ stroke: lineGradient
2186
+ ? props.lineGradientId
2187
+ ? `url(#${props.lineGradientId})`
2188
+ : `url(#lineGradient)`
2189
+ : color,
2190
+ strokeWidth: currentLineThickness || thickness,
2191
+ };
2192
+ if (
2193
+ strokeDashArray &&
2194
+ strokeDashArray.length === 2 &&
2195
+ typeof strokeDashArray[0] === 'number' &&
2196
+ typeof strokeDashArray[1] === 'number'
2197
+ ) {
2198
+ lineSvgPropsOuter.strokeDasharray = strokeDashArray;
2199
+ }
2170
2200
  return (
2171
2201
  <Svg>
2172
2202
  {lineGradient && getLineGradientComponent()}
2173
- {strokeDashArray &&
2174
- strokeDashArray.length === 2 &&
2175
- typeof strokeDashArray[0] === 'number' &&
2176
- typeof strokeDashArray[1] === 'number' ? (
2177
- <Path
2178
- d={points}
2179
- fill="none"
2180
- stroke={
2181
- lineGradient
2203
+ {points.includes('segmentStart') ? (
2204
+ ar.map((item, index) => {
2205
+ const lineSvgProps: LineSvgProps = {
2206
+ d: item.d,
2207
+ fill: 'none',
2208
+ stroke: lineGradient
2182
2209
  ? props.lineGradientId
2183
2210
  ? `url(#${props.lineGradientId})`
2184
2211
  : `url(#lineGradient)`
2185
- : color
2212
+ : item.color,
2213
+ strokeWidth: item.strokeWidth,
2214
+ };
2215
+ if (
2216
+ item.strokeDashArray &&
2217
+ item.strokeDashArray.length === 2 &&
2218
+ typeof item.strokeDashArray[0] === 'number' &&
2219
+ typeof item.strokeDashArray[1] === 'number'
2220
+ ) {
2221
+ lineSvgProps.strokeDasharray = item.strokeDashArray;
2186
2222
  }
2187
- strokeWidth={currentLineThickness || thickness}
2188
- strokeDasharray={strokeDashArray}
2189
- />
2223
+ return <Path key={index} {...lineSvgProps} />;
2224
+ })
2190
2225
  ) : (
2191
- <Path
2192
- d={points}
2193
- fill="none"
2194
- stroke={
2195
- lineGradient
2196
- ? props.lineGradientId
2197
- ? `url(#${props.lineGradientId})`
2198
- : `url(#lineGradient)`
2199
- : color
2200
- }
2201
- strokeWidth={currentLineThickness || thickness}
2202
- />
2226
+ <Path {...lineSvgPropsOuter} />
2203
2227
  )}
2204
2228
 
2205
2229
  {/*********************** For Area Chart ************/}
@@ -3198,12 +3222,15 @@ export const LineChart = (props: LineChartPropsType) => {
3198
3222
  setSelectedIndex,
3199
3223
  spacing,
3200
3224
  showLine: false,
3201
- lineConfig: null,
3225
+ lineConfig: null, // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
3226
+ lineConfig2: null, // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
3202
3227
  maxValue,
3203
3228
  lineData: [], // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
3229
+ lineData2: [], // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
3204
3230
  animatedWidth,
3205
3231
  lineBehindBars: false,
3206
3232
  points,
3233
+ points2: '', // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
3207
3234
  arrowPoints: [], // Not needed but passing this prop to maintain consistency (between LineChart and BarChart props)
3208
3235
  renderChartContent,
3209
3236
  remainingScrollViewProps,
@@ -2,6 +2,8 @@ import {ColorValue} from 'react-native';
2
2
  import {yAxisSides} from '../utils/constants';
3
3
  import {
4
4
  CurveType,
5
+ EdgePosition,
6
+ LineSegment,
5
7
  Pointer,
6
8
  RuleType,
7
9
  RulesConfig,
@@ -110,6 +112,7 @@ export type LineChartPropsType = {
110
112
  stepChart3?: boolean;
111
113
  stepChart4?: boolean;
112
114
  stepChart5?: boolean;
115
+ edgePosition?: EdgePosition;
113
116
 
114
117
  disableScroll?: boolean;
115
118
  pointerConfig?: Pointer;
@@ -300,6 +303,11 @@ export type LineChartPropsType = {
300
303
  lineGradientDirection?: string;
301
304
  lineGradientStartColor?: string;
302
305
  lineGradientEndColor?: string;
306
+ lineSegments?: Array<LineSegment>;
307
+ lineSegments2?: Array<LineSegment>;
308
+ lineSegments3?: Array<LineSegment>;
309
+ lineSegments4?: Array<LineSegment>;
310
+ lineSegments5?: Array<LineSegment>;
303
311
  };
304
312
 
305
313
  type referenceConfigType = {
package/src/index.tsx CHANGED
@@ -3,4 +3,4 @@ export {PieChart} from './PieChart';
3
3
  export {LineChart} from './LineChart';
4
4
  export {LineChartBicolor} from './LineChart/LineChartBicolor';
5
5
  export {chartTypes, yAxisSides, ruleTypes} from './utils/constants';
6
- export {CurveType} from './utils/types';
6
+ export {CurveType, EdgePosition} from './utils/types';
@@ -1,5 +1,5 @@
1
1
  import {defaultLineConfigType} from '../BarChart/types';
2
- import {CurveType, RuleTypes} from './types';
2
+ import {CurveType, EdgePosition, RuleTypes} from './types';
3
3
  import {Dimensions} from 'react-native';
4
4
 
5
5
  // Global
@@ -205,6 +205,7 @@ export const LineDefaults = {
205
205
  stripWidth: 2,
206
206
  unFocusOnPressOut: true,
207
207
  delayBeforeUnFocus: 300,
208
+ edgePosition: EdgePosition.AT_DATA_POINT,
208
209
  };
209
210
 
210
211
  export const defaultPointerConfig = {
@@ -1,4 +1,5 @@
1
- import {arrowConfigType, CurveType} from './types';
1
+ import {defaultLineConfig} from './constants';
2
+ import {arrowConfigType, CurveType, LineProperties, LineSegment} from './types';
2
3
 
3
4
  export const getCumulativeWidth = (
4
5
  data: any,
@@ -110,7 +111,7 @@ export const svgPath = (
110
111
  (acc, point, i, a) =>
111
112
  i === 0
112
113
  ? // if first point
113
- `M ${point[0]},${point[1]}`
114
+ `M${point[0]},${point[1]}`
114
115
  : // else
115
116
  `${acc} ${bezierCommand(point, i, a, curvature)}`,
116
117
  '',
@@ -162,7 +163,153 @@ export const bezierCommand = (
162
163
  const [cpsX, cpsY] = controlPoint(curvature, a[i - 1], a[i - 2], point);
163
164
  // end control point
164
165
  const [cpeX, cpeY] = controlPoint(curvature, point, a[i - 1], a[i + 1], true);
165
- return `C ${cpsX},${cpsY} ${cpeX},${cpeY} ${point[0]},${point[1]}`;
166
+ return `C${cpsX},${cpsY} ${cpeX},${cpeY} ${point[0]},${point[1]}`;
167
+ };
168
+
169
+ export const getSegmentString = (lineSegment, index) => {
170
+ const segment = lineSegment?.find(segment => segment.startIndex === index);
171
+ return segment ? 'segmentStart' + JSON.stringify(segment) + 'segmentEnd' : '';
172
+ };
173
+
174
+ export const getCurvePathWithSegments = (
175
+ path: string,
176
+ lineSegment: LineSegment[] | undefined,
177
+ ) => {
178
+ if (!lineSegment?.length) return path;
179
+ let newPath = '';
180
+ const pathArray = path.split('C');
181
+ for (let i = 0; i < pathArray.length; i++) {
182
+ const segment = lineSegment?.find(segment => segment.startIndex === i);
183
+ newPath +=
184
+ (pathArray[i].startsWith('M') ? '' : 'C') +
185
+ pathArray[i] +
186
+ (segment ? 'segmentStart' + JSON.stringify(segment) + 'segmentEnd' : '');
187
+ }
188
+ return newPath;
189
+ };
190
+
191
+ export const getPreviousSegmentsLastPoint = (isCurved, previousSegment) => {
192
+ const prevSegmentLastPoint = isCurved
193
+ ? previousSegment.substring(previousSegment.trim().lastIndexOf(' '))
194
+ : previousSegment
195
+ .substring(previousSegment.lastIndexOf('L'))
196
+ .replace('L', 'M');
197
+
198
+ return (
199
+ (prevSegmentLastPoint.trim()[0] === 'M' ? '' : 'M') + prevSegmentLastPoint
200
+ );
201
+ };
202
+
203
+ export const getSegmentedPathObjects = (
204
+ points,
205
+ color,
206
+ currentLineThickness,
207
+ thickness,
208
+ strokeDashArray,
209
+ isCurved,
210
+ ) => {
211
+ const ar: [any] = [{}];
212
+ let tempStr = points;
213
+
214
+ if (!points.startsWith('segmentStart')) {
215
+ const lineSvgProps: LineProperties = {
216
+ d: points.substring(0, points.indexOf('segmentStart')),
217
+ color,
218
+ strokeWidth: currentLineThickness || thickness,
219
+ };
220
+ if (strokeDashArray) {
221
+ lineSvgProps.strokeDashArray = strokeDashArray;
222
+ }
223
+ ar.push(lineSvgProps);
224
+ }
225
+
226
+ while (tempStr.includes('segmentStart')) {
227
+ const startDelimeterIndex = tempStr.indexOf('segmentStart');
228
+ const endDelimeterIndex = tempStr.indexOf('segmentEnd');
229
+
230
+ const segmentConfig = JSON.parse(
231
+ tempStr.substring(
232
+ startDelimeterIndex + 'segmentStart'.length,
233
+ endDelimeterIndex,
234
+ ),
235
+ );
236
+
237
+ const {startIndex, endIndex} = segmentConfig;
238
+ const segmentLength = endIndex - startIndex;
239
+ let segment = tempStr.substring(endDelimeterIndex + 'segmentEnd'.length);
240
+ let c = 0,
241
+ s = 0,
242
+ i;
243
+ for (i = 0; i < segment.length; i++) {
244
+ if (segment[i] === (isCurved ? 'C' : 'L')) c++;
245
+ if (c === segmentLength) {
246
+ if (segment[i] === ' ') s++;
247
+ if (s === (isCurved ? 3 : 2)) break;
248
+ }
249
+ }
250
+ segment = segment.substring(0, i);
251
+
252
+ const previousSegment = ar[ar.length - 1].d;
253
+ const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
254
+ isCurved,
255
+ previousSegment,
256
+ );
257
+
258
+ const lineSvgProps: LineProperties = {
259
+ d: moveToLastPointOfPreviousSegment + segment,
260
+ color: segmentConfig.color ?? color,
261
+ strokeWidth:
262
+ segmentConfig.thickness ?? (currentLineThickness || thickness),
263
+ };
264
+ if (segmentConfig.strokeDashArray) {
265
+ lineSvgProps.strokeDashArray = segmentConfig.strokeDashArray;
266
+ }
267
+ ar.push(lineSvgProps);
268
+
269
+ tempStr = tempStr.substring(endDelimeterIndex + 'segmentEnd'.length + i);
270
+
271
+ const nextDelimiterIndex = tempStr.indexOf('segmentStart');
272
+ const stringUptoNextSegment = tempStr.substring(0, nextDelimiterIndex);
273
+ if (
274
+ nextDelimiterIndex !== -1 &&
275
+ stringUptoNextSegment.indexOf('C') !== -1
276
+ ) {
277
+ const previousSegment = ar[ar.length - 1].d;
278
+ const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
279
+ isCurved,
280
+ previousSegment,
281
+ );
282
+ const lineSvgProps: LineProperties = {
283
+ d: moveToLastPointOfPreviousSegment + ' ' + stringUptoNextSegment,
284
+ color,
285
+ strokeWidth: currentLineThickness || thickness,
286
+ };
287
+ if (strokeDashArray) {
288
+ lineSvgProps.strokeDashArray = strokeDashArray;
289
+ }
290
+ ar.push(lineSvgProps);
291
+ }
292
+ }
293
+
294
+ if (tempStr.length) {
295
+ const previousSegment = ar[ar.length - 1].d;
296
+ const moveToLastPointOfPreviousSegment = getPreviousSegmentsLastPoint(
297
+ isCurved,
298
+ previousSegment,
299
+ );
300
+ const lineSvgProps: LineProperties = {
301
+ d: moveToLastPointOfPreviousSegment + tempStr,
302
+ color,
303
+ strokeWidth: currentLineThickness || thickness,
304
+ };
305
+ if (strokeDashArray) {
306
+ lineSvgProps.strokeDashArray = strokeDashArray;
307
+ }
308
+ ar.push(lineSvgProps);
309
+ }
310
+
311
+ ar.shift();
312
+ return ar;
166
313
  };
167
314
 
168
315
  export const getArrowPoints = (
@@ -619,3 +766,68 @@ export const clone = obj => {
619
766
  }
620
767
  return temp;
621
768
  };
769
+
770
+ export const getLineConfigForBarChart = lineConfig => {
771
+ return {
772
+ initialSpacing:
773
+ lineConfig.initialSpacing ?? defaultLineConfig.initialSpacing,
774
+ curved: lineConfig.curved || defaultLineConfig.curved,
775
+ curvature: lineConfig.curvature ?? defaultLineConfig.curvature,
776
+ curveType: lineConfig.curveType ?? defaultLineConfig.curveType,
777
+ isAnimated: lineConfig.isAnimated || defaultLineConfig.isAnimated,
778
+ animationDuration:
779
+ lineConfig.animationDuration || defaultLineConfig.animationDuration,
780
+ thickness: lineConfig.thickness || defaultLineConfig.thickness,
781
+ color: lineConfig.color || defaultLineConfig.color,
782
+ hideDataPoints:
783
+ lineConfig.hideDataPoints || defaultLineConfig.hideDataPoints,
784
+ dataPointsShape:
785
+ lineConfig.dataPointsShape || defaultLineConfig.dataPointsShape,
786
+ dataPointsHeight:
787
+ lineConfig.dataPointsHeight || defaultLineConfig.dataPointsHeight,
788
+ dataPointsWidth:
789
+ lineConfig.dataPointsWidth || defaultLineConfig.dataPointsWidth,
790
+ dataPointsColor:
791
+ lineConfig.dataPointsColor || defaultLineConfig.dataPointsColor,
792
+ dataPointsRadius:
793
+ lineConfig.dataPointsRadius || defaultLineConfig.dataPointsRadius,
794
+ textColor: lineConfig.textColor || defaultLineConfig.textColor,
795
+ textFontSize: lineConfig.textFontSize || defaultLineConfig.textFontSize,
796
+ textShiftX: lineConfig.textShiftX || defaultLineConfig.textShiftX,
797
+ textShiftY: lineConfig.textShiftY || defaultLineConfig.textShiftY,
798
+ shiftX: lineConfig.shiftX || defaultLineConfig.shiftX,
799
+ shiftY: lineConfig.shiftY || defaultLineConfig.shiftY,
800
+ delay: lineConfig.delay || defaultLineConfig.delay,
801
+ startIndex: lineConfig.startIndex || defaultLineConfig.startIndex,
802
+ endIndex:
803
+ lineConfig.endIndex === 0
804
+ ? 0
805
+ : lineConfig.endIndex || defaultLineConfig.endIndex,
806
+
807
+ showArrow: lineConfig.showArrow ?? defaultLineConfig.showArrow,
808
+ arrowConfig: {
809
+ length:
810
+ lineConfig.arrowConfig?.length ?? defaultLineConfig.arrowConfig?.length,
811
+ width:
812
+ lineConfig.arrowConfig?.width ?? defaultLineConfig.arrowConfig?.width,
813
+
814
+ strokeWidth:
815
+ lineConfig.arrowConfig?.strokeWidth ??
816
+ defaultLineConfig.arrowConfig?.strokeWidth,
817
+
818
+ strokeColor:
819
+ lineConfig.arrowConfig?.strokeColor ??
820
+ defaultLineConfig.arrowConfig?.strokeColor,
821
+
822
+ fillColor:
823
+ lineConfig.arrowConfig?.fillColor ??
824
+ defaultLineConfig.arrowConfig?.fillColor,
825
+
826
+ showArrowBase:
827
+ lineConfig.arrowConfig?.showArrowBase ??
828
+ defaultLineConfig.arrowConfig?.showArrowBase,
829
+ },
830
+ customDataPoint: lineConfig.customDataPoint,
831
+ isSecondary: lineConfig.isSecondary ?? defaultLineConfig.isSecondary,
832
+ };
833
+ };
@@ -14,6 +14,11 @@ export enum CurveType {
14
14
  QUADRATIC,
15
15
  }
16
16
 
17
+ export enum EdgePosition {
18
+ AT_DATA_POINT,
19
+ AROUND_DATA_POINT,
20
+ }
21
+
17
22
  export type RulesConfig = {
18
23
  rulesLength?: number;
19
24
  rulesColor?: ColorValue;
@@ -21,7 +26,7 @@ export type RulesConfig = {
21
26
  rulesType?: RuleType;
22
27
  dashWidth?: number;
23
28
  dashGap?: number;
24
- }
29
+ };
25
30
 
26
31
  export type secondaryYAxisType = {
27
32
  noOfSections?: number;
@@ -190,11 +195,14 @@ export type BarAndLineChartsWrapperTypes = {
190
195
  spacing: number;
191
196
  showLine: boolean;
192
197
  lineConfig: any;
198
+ lineConfig2: any;
193
199
  maxValue: number;
194
200
  lineData: Array<any>;
201
+ lineData2: Array<any>;
195
202
  animatedWidth: any;
196
203
  lineBehindBars: boolean;
197
204
  points: string | Array<any>;
205
+ points2: string | Array<any>;
198
206
  arrowPoints: any;
199
207
  renderChartContent: any;
200
208
  remainingScrollViewProps: any;
@@ -265,3 +273,26 @@ export type Pointer = {
265
273
  strokeDashArray?: Array<number>;
266
274
  barTouchable?: boolean;
267
275
  };
276
+
277
+ export type LineSegment = {
278
+ startIndex: number;
279
+ endIndex: number;
280
+ color?: string | ColorValue;
281
+ thickness?: number;
282
+ strokeDashArray?: Array<number>;
283
+ };
284
+
285
+ export type LineSvgProps = {
286
+ d: string;
287
+ fill: string;
288
+ stroke: string | ColorValue;
289
+ strokeWidth: number;
290
+ strokeDasharray?: Array<number>;
291
+ };
292
+
293
+ export type LineProperties = {
294
+ d: string;
295
+ color: string | ColorValue;
296
+ strokeWidth: number;
297
+ strokeDashArray?: Array<number>;
298
+ };