react-native-gifted-charts 1.3.15 → 1.3.17

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.15",
3
+ "version": "1.3.17",
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": [
@@ -70,6 +70,8 @@ type Props = {
70
70
  barMarginBottom?: number;
71
71
  onPress?: Function;
72
72
  xAxisTextNumberOfLines: number;
73
+ xAxisLabelsHeight?: number;
74
+ xAxisLabelsVerticalShift: number;
73
75
  renderTooltip: Function | undefined;
74
76
  leftShiftForTooltip?: number;
75
77
  leftShiftForLastIndexTooltip: number;
@@ -109,6 +111,7 @@ const RenderBars = (props: Props) => {
109
111
  label,
110
112
  labelTextStyle,
111
113
  xAxisTextNumberOfLines,
114
+ xAxisLabelsVerticalShift,
112
115
  renderTooltip,
113
116
  leftShiftForTooltip,
114
117
  leftShiftForLastIndexTooltip,
@@ -139,7 +142,12 @@ const RenderBars = (props: Props) => {
139
142
  30) + spacing,
140
143
  left: spacing / -2,
141
144
  position: 'absolute',
142
- bottom: (rotateLabel ? -40 : -25) - barMarginBottom,
145
+ height: props.xAxisLabelsHeight ?? xAxisTextNumberOfLines * 18,
146
+ bottom:
147
+ (rotateLabel
148
+ ? -40
149
+ : -6 - xAxisTextNumberOfLines * 18 - xAxisLabelsVerticalShift) -
150
+ barMarginBottom,
143
151
  },
144
152
  rotateLabel
145
153
  ? horizontal
@@ -196,7 +204,12 @@ const RenderBars = (props: Props) => {
196
204
  30) + spacing,
197
205
  left: spacing / -2,
198
206
  position: 'absolute',
199
- bottom: (rotateLabel ? -40 : -25) - barMarginBottom,
207
+ height: props.xAxisLabelsHeight ?? xAxisTextNumberOfLines * 18,
208
+ bottom:
209
+ (rotateLabel
210
+ ? -40
211
+ : -6 - xAxisTextNumberOfLines * 18 - xAxisLabelsVerticalShift) -
212
+ barMarginBottom,
200
213
  opacity: appearingOpacity,
201
214
  },
202
215
  value < 0 && {transform: [{rotate: '180deg'}]},
@@ -344,7 +357,7 @@ const RenderBars = (props: Props) => {
344
357
  const barWrapperStyle = [
345
358
  {
346
359
  // overflow: 'visible',
347
- marginBottom: 60 + barMarginBottom,
360
+ marginBottom: 60 + barMarginBottom + xAxisLabelsVerticalShift,
348
361
  width: item.barWidth || props.barWidth || 30,
349
362
  height: barHeight,
350
363
  marginRight: spacing,
@@ -364,7 +377,9 @@ const RenderBars = (props: Props) => {
364
377
  ? {
365
378
  transform: [
366
379
  {
367
- translateY: (containerHeight || 200) - (barHeight - 10),
380
+ translateY:
381
+ (containerHeight || 200) -
382
+ (barHeight - 10 + xAxisLabelsVerticalShift),
368
383
  },
369
384
  ],
370
385
  }
@@ -52,6 +52,8 @@ type Props = {
52
52
  barBackgroundPattern?: Function;
53
53
  patternId?: String;
54
54
  xAxisTextNumberOfLines: number;
55
+ xAxisLabelsHeight?: number;
56
+ xAxisLabelsVerticalShift: number;
55
57
  renderTooltip: Function | undefined;
56
58
  leftShiftForTooltip?: number;
57
59
  leftShiftForLastIndexTooltip: number;
@@ -118,6 +120,7 @@ const RenderStackBars = (props: Props) => {
118
120
  label,
119
121
  labelTextStyle,
120
122
  xAxisTextNumberOfLines,
123
+ xAxisLabelsVerticalShift,
121
124
  renderTooltip,
122
125
  leftShiftForTooltip,
123
126
  leftShiftForLastIndexTooltip,
@@ -147,7 +150,7 @@ const RenderStackBars = (props: Props) => {
147
150
  width:
148
151
  (item.stacks[0].barWidth || props.barWidth || 30) + spacing / 2,
149
152
  position: 'absolute',
150
- bottom: rotateLabel ? -40 : -25,
153
+ bottom: rotateLabel ? -40 : -6 - xAxisTextNumberOfLines * 18,
151
154
  },
152
155
  rotateLabel
153
156
  ? props.horizontal
@@ -365,7 +368,7 @@ const RenderStackBars = (props: Props) => {
365
368
  style={[
366
369
  {
367
370
  // overflow: 'visible',
368
- marginBottom: 60,
371
+ marginBottom: 60 + xAxisLabelsVerticalShift,
369
372
  width: item.stacks[0].barWidth || props.barWidth || 30,
370
373
  height: totalHeight,
371
374
  marginRight: spacing,
@@ -265,6 +265,9 @@ export const BarChart = (props: BarChartPropsType) => {
265
265
 
266
266
  const xAxisTextNumberOfLines =
267
267
  props.xAxisTextNumberOfLines ?? AxesAndRulesDefaults.xAxisTextNumberOfLines;
268
+ const xAxisLabelsVerticalShift =
269
+ props.xAxisLabelsVerticalShift ??
270
+ AxesAndRulesDefaults.xAxisLabelsVerticalShift;
268
271
  const horizontalRulesStyle = props.horizontalRulesStyle;
269
272
  const yAxisLabelWidth =
270
273
  props.yAxisLabelWidth ??
@@ -277,6 +280,8 @@ export const BarChart = (props: BarChartPropsType) => {
277
280
  const widthValue = useMemo(() => new Animated.Value(0), []);
278
281
  const autoShiftLabels = props.autoShiftLabels ?? false;
279
282
 
283
+ const barWidth = props.barWidth || BarDefaults.barWidth;
284
+
280
285
  const extendedContainerHeight = getExtendedContainerHeightWithPadding(
281
286
  containerHeight,
282
287
  0,
@@ -347,6 +352,16 @@ export const BarChart = (props: BarChartPropsType) => {
347
352
  const activatePointersDelay =
348
353
  pointerConfig?.activatePointersDelay ??
349
354
  defaultPointerConfig.activatePointersDelay;
355
+ const initialPointerIndex =
356
+ pointerConfig?.initialPointerIndex ??
357
+ defaultPointerConfig.initialPointerIndex;
358
+ const initialPointerAppearDelay =
359
+ pointerConfig?.initialPointerAppearDelay ??
360
+ (isAnimated
361
+ ? animationDuration
362
+ : defaultPointerConfig.initialPointerAppearDelay);
363
+ const persistPointer =
364
+ pointerConfig?.persistPointer ?? defaultPointerConfig.persistPointer;
350
365
  const hidePointer1 =
351
366
  pointerConfig?.hidePointer1 ?? defaultPointerConfig.hidePointer1;
352
367
 
@@ -505,6 +520,36 @@ export const BarChart = (props: BarChartPropsType) => {
505
520
  lineConfig.arrowConfig.showArrowBase,
506
521
  ]);
507
522
 
523
+ useEffect(() => {
524
+ if (initialPointerIndex !== -1) {
525
+ const item = data[initialPointerIndex];
526
+ const x =
527
+ initialSpacing +
528
+ (spacing + barWidth) * initialPointerIndex -
529
+ (pointerRadius || pointerWidth / 2) +
530
+ barWidth / 2;
531
+ const y =
532
+ containerHeight -
533
+ (item.value * containerHeight) / maxValue -
534
+ (pointerRadius || pointerHeight / 2) +
535
+ 10;
536
+ if (initialPointerAppearDelay) {
537
+ setTimeout(() => {
538
+ setPointerConfig(initialPointerIndex, item, x, y);
539
+ }, initialPointerAppearDelay);
540
+ } else {
541
+ setPointerConfig(initialPointerIndex, item, x, y);
542
+ }
543
+ }
544
+ }, []);
545
+
546
+ const setPointerConfig = (initialPointerIndex, item, x, y) => {
547
+ setPointerIndex(initialPointerIndex);
548
+ setPointerItem(item);
549
+ setPointerX(x);
550
+ setPointerY(y);
551
+ };
552
+
508
553
  const animatedHeight = heightValue.interpolate({
509
554
  inputRange: [0, 1],
510
555
  outputRange: ['0%', '100%'],
@@ -571,7 +616,6 @@ export const BarChart = (props: BarChartPropsType) => {
571
616
 
572
617
  const renderChartContent = () => {
573
618
  if (pointerConfig) {
574
- const barWidth = props.barWidth || BarDefaults.barWidth;
575
619
  return (
576
620
  <View
577
621
  onStartShouldSetResponder={evt => (pointerConfig ? true : false)}
@@ -652,7 +696,8 @@ export const BarChart = (props: BarChartPropsType) => {
652
696
  setResponderStartTime(0);
653
697
  setPointerIndex(-1);
654
698
  setResponderActive(false);
655
- setTimeout(() => setPointerX(0), pointerVanishDelay);
699
+ if (!persistPointer)
700
+ setTimeout(() => setPointerX(0), pointerVanishDelay);
656
701
  }}
657
702
  onResponderTerminationRequest={evt => false}
658
703
  style={{
@@ -671,7 +716,7 @@ export const BarChart = (props: BarChartPropsType) => {
671
716
  position: 'absolute',
672
717
  height:
673
718
  extendedContainerHeight + noOfSectionsBelowXAxis * stepHeight,
674
- bottom: 0 + labelsExtraHeight,
719
+ bottom: xAxisLabelsVerticalShift + labelsExtraHeight,
675
720
  width: totalWidth,
676
721
  zIndex: 20,
677
722
  }}>
@@ -721,6 +766,8 @@ export const BarChart = (props: BarChartPropsType) => {
721
766
  patternId: props.patternId,
722
767
  onPress: props.onPress,
723
768
  xAxisTextNumberOfLines: xAxisTextNumberOfLines,
769
+ xAxisLabelsHeight: props.xAxisLabelsHeight,
770
+ xAxisLabelsVerticalShift,
724
771
  renderTooltip: props.renderTooltip,
725
772
  leftShiftForTooltip: props.leftShiftForTooltip || 0,
726
773
  initialSpacing: initialSpacing,
@@ -1,7 +1,13 @@
1
1
  import {ColorValue, View} from 'react-native';
2
2
  import {stackItemType} from '../BarChart/RenderStackBars';
3
3
  import {yAxisSides} from '../utils/constants';
4
- import {CurveType, Pointer, RuleType, secondaryYAxisType} from '../utils/types';
4
+ import {
5
+ CurveType,
6
+ Pointer,
7
+ RuleType,
8
+ RulesConfig,
9
+ secondaryYAxisType,
10
+ } from '../utils/types';
5
11
 
6
12
  export type BarChartPropsType = {
7
13
  width?: number;
@@ -34,6 +40,8 @@ export type BarChartPropsType = {
34
40
  yAxisTextStyle?: any;
35
41
  yAxisTextNumberOfLines?: number;
36
42
  xAxisTextNumberOfLines?: number;
43
+ xAxisLabelsHeight?: number;
44
+ xAxisLabelsVerticalShift?: number;
37
45
  yAxisLabelWidth?: number;
38
46
  hideYAxisText?: boolean;
39
47
  rotateYAxisTexts?: number;
@@ -61,6 +69,7 @@ export type BarChartPropsType = {
61
69
  rulesType?: RuleType;
62
70
  dashWidth?: number;
63
71
  dashGap?: number;
72
+ rulesConfigArray?: Array<RulesConfig>;
64
73
  showReferenceLine1?: boolean;
65
74
  referenceLine1Config?: referenceConfigType;
66
75
  referenceLine1Position?: number;
@@ -97,6 +97,9 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
97
97
  const xAxisLength = axesAndRulesProps.xAxisLength;
98
98
  const xAxisType =
99
99
  axesAndRulesProps.xAxisType ?? AxesAndRulesDefaults.xAxisType;
100
+ const xAxisLabelsVerticalShift =
101
+ axesAndRulesProps.xAxisLabelsVerticalShift ??
102
+ AxesAndRulesDefaults.xAxisLabelsVerticalShift;
100
103
  const dashWidth =
101
104
  axesAndRulesProps.dashWidth ?? AxesAndRulesDefaults.dashWidth;
102
105
  const dashGap = axesAndRulesProps.dashGap ?? AxesAndRulesDefaults.dashGap;
@@ -111,6 +114,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
111
114
  axesAndRulesProps.rulesThickness ?? AxesAndRulesDefaults.rulesThickness;
112
115
  const rulesColor =
113
116
  axesAndRulesProps.rulesColor ?? AxesAndRulesDefaults.rulesColor;
117
+ const rulesConfigArray = axesAndRulesProps.rulesConfigArray ?? AxesAndRulesDefaults.rulesConfigArray;
114
118
  const showYAxisIndices = axesAndRulesProps.showYAxisIndices ?? false;
115
119
  const yAxisIndicesHeight =
116
120
  axesAndRulesProps.yAxisIndicesHeight ??
@@ -192,6 +196,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
192
196
  rulesType,
193
197
  rulesThickness,
194
198
  rulesColor,
199
+ rulesConfigArray,
195
200
  spacing,
196
201
  showYAxisIndices,
197
202
  yAxisIndicesHeight,
@@ -243,6 +248,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
243
248
  barWidth,
244
249
  labelsExtraHeight,
245
250
  scrollEventThrottle,
251
+ xAxisLabelsVerticalShift,
246
252
  };
247
253
  const extendedContainerHeight = containerHeight + 10;
248
254
  const containerHeightIncludingBelowXAxis =
@@ -270,6 +276,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
270
276
  containerHeightIncludingBelowXAxis,
271
277
  yAxisLabelWidth,
272
278
  totalWidth,
279
+ xAxisLabelsVerticalShift,
273
280
  };
274
281
 
275
282
  const actualContainerHeight =
@@ -311,8 +318,13 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
311
318
 
312
319
  const container = {
313
320
  width: '100%',
314
- height: actualContainerHeight,
315
- marginBottom: 40, //This is to not let the Things that should be rendered below the chart overlap with it
321
+ height:
322
+ containerHeightIncludingBelowXAxis +
323
+ labelsExtraHeight +
324
+ stepHeight / 2 +
325
+ xAxisLabelsVerticalShift +
326
+ 50,
327
+ marginBottom: 15, //This is to not let the Things that should be rendered below the chart overlap with it
316
328
  };
317
329
 
318
330
  return (
@@ -345,8 +357,6 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
345
357
  : yAxisLabelWidth + yAxisThickness,
346
358
  position: 'absolute',
347
359
  bottom:
348
- stepHeight * -0.5 -
349
- 60 +
350
360
  (chartType === chartTypes.LINE_BI_COLOR ? 0 : xAxisThickness),
351
361
  },
352
362
  !!props.width && {width: props.width},
@@ -361,7 +371,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
361
371
  containerHeightIncludingBelowXAxis +
362
372
  labelsExtraHeight +
363
373
  stepHeight / 2 +
364
- 50,
374
+ (50 + xAxisLabelsVerticalShift),
365
375
  width: totalWidth - spacing + endSpacing,
366
376
  paddingLeft: initialSpacing,
367
377
  paddingBottom:
@@ -37,6 +37,7 @@ export const renderHorizSections = (props: horizSectionPropTypes) => {
37
37
  rulesType,
38
38
  rulesThickness,
39
39
  rulesColor,
40
+ rulesConfigArray,
40
41
  spacing,
41
42
  showYAxisIndices,
42
43
  yAxisIndicesHeight,
@@ -382,62 +383,71 @@ export const renderHorizSections = (props: horizSectionPropTypes) => {
382
383
  );
383
384
  };
384
385
 
385
- const renderAxesAndRules = (index: number) => (
386
- <View
387
- style={[
388
- index === noOfSections ? styles.lastLeftPart : styles.leftPart,
389
- {
390
- borderColor: yAxisColor,
391
- backgroundColor: backgroundColor,
392
- width: (props.width || totalWidth - spacing) + endSpacing,
393
- },
394
- yAxisSide === yAxisSides.RIGHT
395
- ? {borderRightWidth: yAxisThickness}
396
- : {borderLeftWidth: yAxisThickness},
397
- ]}>
398
- {index === noOfSections ? (
399
- <Rule
400
- config={{
401
- thickness: xAxisThickness,
402
- color: xAxisColor,
403
- width:
404
- xAxisLength || (props.width || totalWidth - spacing) + endSpacing,
405
- dashWidth: dashWidth,
406
- dashGap: dashGap,
407
- type: xAxisType,
408
- }}
409
- />
410
- ) : hideRules ? null : (
411
- <Rule
412
- config={{
413
- thickness: rulesThickness,
414
- color: rulesColor,
415
- width:
416
- rulesLength || (props.width || totalWidth - spacing) + endSpacing,
417
- dashWidth: dashWidth,
418
- dashGap: dashGap,
419
- type: rulesType,
420
- }}
421
- />
422
- )}
423
- {showYAxisIndices && index !== noOfSections ? (
424
- <View
425
- style={{
426
- height: yAxisIndicesHeight,
427
- width: yAxisIndicesWidth,
428
- left:
429
- yAxisIndicesWidth / -2 +
430
- (yAxisSide === yAxisSides.RIGHT
431
- ? (width ?? totalWidth) +
432
- yAxisLabelWidth / 2 +
433
- yAxisIndicesWidth / 4
434
- : 0),
435
- backgroundColor: yAxisIndicesColor,
436
- }}
437
- />
438
- ) : null}
439
- </View>
440
- );
386
+ const renderAxesAndRules = (index: number) => {
387
+ const invertedIndex = horizSections.length - index - 1;
388
+ return (
389
+ <View
390
+ style={[
391
+ index === noOfSections ? styles.lastLeftPart : styles.leftPart,
392
+ {
393
+ borderColor: yAxisColor,
394
+ backgroundColor: backgroundColor,
395
+ width: (props.width || totalWidth - spacing) + endSpacing,
396
+ },
397
+ yAxisSide === yAxisSides.RIGHT
398
+ ? {borderRightWidth: yAxisThickness}
399
+ : {borderLeftWidth: yAxisThickness},
400
+ ]}>
401
+ {index === noOfSections ? (
402
+ <Rule
403
+ config={{
404
+ thickness: xAxisThickness,
405
+ color: xAxisColor,
406
+ width:
407
+ xAxisLength ||
408
+ (props.width || totalWidth - spacing) + endSpacing,
409
+ dashWidth: dashWidth,
410
+ dashGap: dashGap,
411
+ type: xAxisType,
412
+ }}
413
+ />
414
+ ) : hideRules ? null : (
415
+ <Rule
416
+ config={{
417
+ thickness:
418
+ rulesConfigArray[invertedIndex]?.rulesThickness ??
419
+ rulesThickness,
420
+ color: rulesConfigArray[invertedIndex]?.rulesColor ?? rulesColor,
421
+ width:
422
+ rulesConfigArray[invertedIndex]?.rulesLength ??
423
+ rulesLength ??
424
+ (props.width || totalWidth - spacing) + endSpacing,
425
+ dashWidth:
426
+ rulesConfigArray[invertedIndex]?.dashWidth ?? dashWidth,
427
+ dashGap: rulesConfigArray[invertedIndex]?.dashGap ?? dashGap,
428
+ type: rulesConfigArray[invertedIndex]?.rulesType ?? rulesType,
429
+ }}
430
+ />
431
+ )}
432
+ {showYAxisIndices && index !== noOfSections ? (
433
+ <View
434
+ style={{
435
+ height: yAxisIndicesHeight,
436
+ width: yAxisIndicesWidth,
437
+ left:
438
+ yAxisIndicesWidth / -2 +
439
+ (yAxisSide === yAxisSides.RIGHT
440
+ ? (width ?? totalWidth) +
441
+ yAxisLabelWidth / 2 +
442
+ yAxisIndicesWidth / 4
443
+ : 0),
444
+ backgroundColor: yAxisIndicesColor,
445
+ }}
446
+ />
447
+ ) : null}
448
+ </View>
449
+ );
450
+ };
441
451
 
442
452
  const renderSecondaryYaxisLabels = (
443
453
  horizSections: HorizSectionsType,
@@ -20,6 +20,7 @@ const RenderLineInBarChart = props => {
20
20
  totalWidth,
21
21
  barWidth,
22
22
  labelsExtraHeight,
23
+ xAxisLabelsVerticalShift,
23
24
  } = props;
24
25
 
25
26
  const firstBarWidth = data[0].barWidth ?? barWidth;
@@ -322,7 +323,7 @@ const RenderLineInBarChart = props => {
322
323
  position: 'absolute',
323
324
  height: containerHeight + 10,
324
325
  left: 34 - yAxisLabelWidth,
325
- bottom: 50, //stepHeight * -0.5 + xAxisThickness,
326
+ bottom: 50 + xAxisLabelsVerticalShift, //stepHeight * -0.5 + xAxisThickness,
326
327
  width: animatedWidth,
327
328
  zIndex: lineBehindBars ? -1 : 100000,
328
329
  // backgroundColor: 'wheat',
@@ -361,7 +362,7 @@ const RenderLineInBarChart = props => {
361
362
  position: 'absolute',
362
363
  height: containerHeight + 10 + labelsExtraHeight,
363
364
  left: 34 - yAxisLabelWidth,
364
- bottom: 50, //stepHeight * -0.5 + xAxisThickness,
365
+ bottom: 50 + xAxisLabelsVerticalShift, //stepHeight * -0.5 + xAxisThickness,
365
366
  width: totalWidth,
366
367
  zIndex: lineBehindBars ? -1 : 100000,
367
368
  // backgroundColor: 'rgba(200,150,150,0.1)'
@@ -25,8 +25,8 @@ const RenderVerticalLines = props => {
25
25
  maxValue,
26
26
  chartType,
27
27
  containerHeightIncludingBelowXAxis,
28
- yAxisLabelWidth,
29
28
  totalWidth,
29
+ xAxisLabelsVerticalShift,
30
30
  } = props;
31
31
 
32
32
  const getHeightOfVerticalLine = index => {
@@ -53,7 +53,7 @@ const RenderVerticalLines = props => {
53
53
  style={{
54
54
  position: 'absolute',
55
55
  height: extendedContainerHeight,
56
- bottom: 60, //stepHeight * -0.5 + xAxisThickness,
56
+ bottom: 60 + xAxisLabelsVerticalShift, //stepHeight * -0.5 + xAxisThickness,
57
57
  width: totalWidth,
58
58
  zIndex: verticalLinesZIndex || -1,
59
59
  }}>
@@ -103,6 +103,7 @@ const RenderVerticalLines = props => {
103
103
 
104
104
  const x =
105
105
  verticalLinesShift +
106
+ 1 +
106
107
  (chartType === chartTypes.BAR
107
108
  ? totalSpacing - 1
108
109
  : verticalLinesSpacing
@@ -17,7 +17,7 @@ export const Pointer = props => {
17
17
  style={{
18
18
  position: 'absolute',
19
19
  left: pointerX + (pointerX.pointerShiftX || 0),
20
- top: pointerYLocal,
20
+ top: pointerYLocal - 2,
21
21
  }}>
22
22
  {pointerComponent ? (
23
23
  pointerComponent()
@@ -380,6 +380,13 @@ export const LineChart = (props: LineChartPropsType) => {
380
380
  areaChart4 ||
381
381
  areaChart5;
382
382
 
383
+ const stepChart = props.stepChart ?? false;
384
+ const stepChart1 = props.stepChart1 ?? false;
385
+ const stepChart2 = props.stepChart2 ?? false;
386
+ const stepChart3 = props.stepChart3 ?? false;
387
+ const stepChart4 = props.stepChart4 ?? false;
388
+ const stepChart5 = props.stepChart5 ?? false;
389
+
383
390
  const textFontSize1 =
384
391
  props.textFontSize1 ?? props.textFontSize ?? LineDefaults.textFontSize;
385
392
  const textFontSize2 =
@@ -794,19 +801,84 @@ export const LineChart = (props: LineChartPropsType) => {
794
801
  if (!props.curved) {
795
802
  for (let i = 0; i < data.length; i++) {
796
803
  if (i >= startIndex1 && i <= endIndex1 && !animateOnDataChange) {
797
- pp += 'L' + getX(i) + ' ' + getY(data[i].value) + ' ';
804
+ 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
+ ' ';
815
+ } else {
816
+ pp += 'L' + getX(i) + ' ' + getY(data[i].value) + ' ';
817
+ }
798
818
  }
799
819
  if (data2.length && i >= startIndex2 && i <= endIndex2) {
800
- pp2 += 'L' + getX(i) + ' ' + getY(data2[i].value) + ' ';
820
+ 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
+ ' ';
831
+ } else {
832
+ pp2 += 'L' + getX(i) + ' ' + getY(data2[i].value) + ' ';
833
+ }
801
834
  }
802
835
  if (data3.length && i >= startIndex3 && i <= endIndex3) {
803
- pp3 += 'L' + getX(i) + ' ' + getY(data3[i].value) + ' ';
836
+ 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
+ ' ';
847
+ } else {
848
+ pp3 += 'L' + getX(i) + ' ' + getY(data3[i].value) + ' ';
849
+ }
804
850
  }
805
851
  if (data4.length && i >= startIndex4 && i <= endIndex4) {
806
- pp4 += 'L' + getX(i) + ' ' + getY(data4[i].value) + ' ';
852
+ 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
+ ' ';
863
+ } else {
864
+ pp4 += 'L' + getX(i) + ' ' + getY(data4[i].value) + ' ';
865
+ }
807
866
  }
808
867
  if (data5.length && i >= startIndex5 && i <= endIndex5) {
809
- pp5 += 'L' + getX(i) + ' ' + getY(data5[i].value) + ' ';
868
+ 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
+ ' ';
879
+ } else {
880
+ pp5 += 'L' + getX(i) + ' ' + getY(data5[i].value) + ' ';
881
+ }
810
882
  }
811
883
  }
812
884
  setPoints2(pp2.replace('L', 'M'));
@@ -1346,6 +1418,9 @@ export const LineChart = (props: LineChartPropsType) => {
1346
1418
  // const yAxisThickness = props.yAxisThickness ?? 1;
1347
1419
  const xAxisTextNumberOfLines =
1348
1420
  props.xAxisTextNumberOfLines ?? AxesAndRulesDefaults.xAxisTextNumberOfLines;
1421
+ const xAxisLabelsVerticalShift =
1422
+ props.xAxisLabelsVerticalShift ??
1423
+ AxesAndRulesDefaults.xAxisLabelsVerticalShift;
1349
1424
  const horizontalRulesStyle = props.horizontalRulesStyle;
1350
1425
  const showFractionalValues =
1351
1426
  props.showFractionalValues ?? AxesAndRulesDefaults.showFractionalValues;
@@ -1407,6 +1482,16 @@ export const LineChart = (props: LineChartPropsType) => {
1407
1482
  const activatePointersDelay =
1408
1483
  pointerConfig?.activatePointersDelay ??
1409
1484
  defaultPointerConfig.activatePointersDelay;
1485
+ const initialPointerIndex =
1486
+ pointerConfig?.initialPointerIndex ??
1487
+ defaultPointerConfig.initialPointerIndex;
1488
+ const initialPointerAppearDelay =
1489
+ pointerConfig?.initialPointerAppearDelay ??
1490
+ (isAnimated
1491
+ ? animationDuration
1492
+ : defaultPointerConfig.initialPointerAppearDelay);
1493
+ const persistPointer =
1494
+ pointerConfig?.persistPointer ?? defaultPointerConfig.persistPointer;
1410
1495
  const hidePointer1 =
1411
1496
  pointerConfig?.hidePointer1 ?? defaultPointerConfig.hidePointer1;
1412
1497
  const hidePointer2 =
@@ -1457,6 +1542,36 @@ export const LineChart = (props: LineChartPropsType) => {
1457
1542
  const lineGradientEndColor =
1458
1543
  props.lineGradientEndColor ?? LineDefaults.lineGradientEndColor;
1459
1544
 
1545
+ useEffect(() => {
1546
+ if (initialPointerIndex !== -1) {
1547
+ const item = data[initialPointerIndex];
1548
+ const x =
1549
+ initialSpacing +
1550
+ spacing * initialPointerIndex -
1551
+ (pointerRadius || pointerWidth / 2) -
1552
+ 1;
1553
+ const y =
1554
+ containerHeight -
1555
+ (item.value * containerHeight) / maxValue -
1556
+ (pointerRadius || pointerHeight / 2) +
1557
+ 10;
1558
+ if (initialPointerAppearDelay) {
1559
+ setTimeout(() => {
1560
+ setPointerConfig(initialPointerIndex, item, x, y);
1561
+ }, initialPointerAppearDelay);
1562
+ } else {
1563
+ setPointerConfig(initialPointerIndex, item, x, y);
1564
+ }
1565
+ }
1566
+ }, []);
1567
+
1568
+ const setPointerConfig = (initialPointerIndex, item, x, y) => {
1569
+ setPointerIndex(initialPointerIndex);
1570
+ setPointerItem(item);
1571
+ setPointerX(x);
1572
+ setPointerY(y);
1573
+ };
1574
+
1460
1575
  const renderLabel = (
1461
1576
  index: number,
1462
1577
  label: String,
@@ -1468,14 +1583,14 @@ export const LineChart = (props: LineChartPropsType) => {
1468
1583
  style={[
1469
1584
  {
1470
1585
  position: 'absolute',
1471
- bottom: 30,
1586
+ bottom: 54 - xAxisTextNumberOfLines * 18,
1472
1587
  zIndex: 10,
1473
1588
  width: spacing + labelsExtraHeight,
1474
1589
  left:
1475
1590
  index === 0 && initialSpacing < 10
1476
1591
  ? initialSpacing / 2 + spacing * index - spacing / 2 + 4
1477
1592
  : initialSpacing / 2 + spacing * index - spacing / 2 - 10,
1478
- justifyContent: 'center',
1593
+ height: props.xAxisLabelsHeight ?? xAxisTextNumberOfLines * 18,
1479
1594
  },
1480
1595
  rotateLabel && {transform: [{rotate: '60deg'}]},
1481
1596
  ]}>
@@ -1502,9 +1617,11 @@ export const LineChart = (props: LineChartPropsType) => {
1502
1617
  <Animated.View
1503
1618
  style={[
1504
1619
  {
1505
- height: rotateLabel ? 40 : 20,
1620
+ height: rotateLabel
1621
+ ? 40
1622
+ : props.xAxisLabelsHeight ?? xAxisTextNumberOfLines * 18,
1506
1623
  position: 'absolute',
1507
- bottom: rotateLabel ? 10 : 30,
1624
+ bottom: rotateLabel ? 10 : 54 - xAxisTextNumberOfLines * 18,
1508
1625
  zIndex: 10,
1509
1626
  width: spacing,
1510
1627
  left:
@@ -1677,22 +1794,22 @@ export const LineChart = (props: LineChartPropsType) => {
1677
1794
  {item.showStrip ||
1678
1795
  (focusEnabled && index === selectedIndex && showStripOnFocus) ? (
1679
1796
  <Rect
1680
- x={initialSpacing + (spacing * index - dataPointsWidth / 2)}
1797
+ x={initialSpacing + spacing * index - currentStripWidth / 2 - 1}
1681
1798
  y={
1682
1799
  currentStripHeight
1683
1800
  ? containerHeight - currentStripHeight + 8
1684
1801
  : containerHeight -
1685
1802
  dataPointsHeight / 2 +
1686
- 20 -
1803
+ 14 -
1687
1804
  (item.value * containerHeight) / maxValue
1688
1805
  }
1689
1806
  width={currentStripWidth}
1690
1807
  height={
1691
1808
  currentStripHeight ||
1692
- containerHeight - dataPointsHeight / 2 + 20
1809
+ (item.value * containerHeight) / maxValue - 2
1693
1810
  }
1694
1811
  opacity={currentStripOpacity}
1695
- fill={currentStripColor}
1812
+ fill={stripColor}
1696
1813
  />
1697
1814
  ) : null}
1698
1815
  {hideDataPoints ? null : (
@@ -2445,7 +2562,8 @@ export const LineChart = (props: LineChartPropsType) => {
2445
2562
  setResponderStartTime(0);
2446
2563
  setPointerIndex(-1);
2447
2564
  setResponderActive(false);
2448
- setTimeout(() => setPointerX(0), pointerVanishDelay);
2565
+ if (!persistPointer)
2566
+ setTimeout(() => setPointerX(0), pointerVanishDelay);
2449
2567
  }}
2450
2568
  onResponderTerminationRequest={evt => false}
2451
2569
  // onResponderTerminate={evt => {
@@ -2463,11 +2581,12 @@ export const LineChart = (props: LineChartPropsType) => {
2463
2581
  (props.overflowBottom ?? dataPointsRadius1),
2464
2582
  bottom:
2465
2583
  60 +
2584
+ xAxisLabelsVerticalShift +
2466
2585
  labelsExtraHeight -
2467
2586
  (props.overflowBottom ?? dataPointsRadius1),
2468
- width: totalWidth,
2469
2587
  zIndex: zIndex,
2470
2588
  transform: [{scaleX: I18nManager.isRTL ? -1 : 1}],
2589
+ width: totalWidth,
2471
2590
  }}>
2472
2591
  {lineSvgComponent(
2473
2592
  points,
@@ -2710,7 +2829,8 @@ export const LineChart = (props: LineChartPropsType) => {
2710
2829
  setResponderStartTime(0);
2711
2830
  setPointerIndex(-1);
2712
2831
  setResponderActive(false);
2713
- setTimeout(() => setPointerX(0), pointerVanishDelay);
2832
+ if (!persistPointer)
2833
+ setTimeout(() => setPointerX(0), pointerVanishDelay);
2714
2834
  }}
2715
2835
  onResponderTerminationRequest={evt => false}
2716
2836
  // onResponderTerminate={evt => {
@@ -2728,12 +2848,12 @@ export const LineChart = (props: LineChartPropsType) => {
2728
2848
  (props.overflowBottom ?? dataPointsRadius1),
2729
2849
  bottom:
2730
2850
  60 +
2851
+ xAxisLabelsVerticalShift +
2731
2852
  labelsExtraHeight -
2732
2853
  (props.overflowBottom ?? dataPointsRadius1),
2733
- width: animatedWidth,
2734
2854
  zIndex: zIndex,
2735
2855
  transform: [{scaleX: I18nManager.isRTL ? -1 : 1}],
2736
- // backgroundColor: 'wheat',
2856
+ width: animatedWidth,
2737
2857
  }}>
2738
2858
  {lineSvgComponent(
2739
2859
  points,
@@ -3003,7 +3123,7 @@ export const LineChart = (props: LineChartPropsType) => {
3003
3123
  position: 'absolute',
3004
3124
  height:
3005
3125
  extendedContainerHeight + noOfSectionsBelowXAxis * stepHeight,
3006
- bottom: 60 + labelsExtraHeight,
3126
+ bottom: 58 + labelsExtraHeight + xAxisLabelsVerticalShift,
3007
3127
  width: totalWidth,
3008
3128
  zIndex: 20,
3009
3129
  }}>
@@ -4,6 +4,7 @@ import {
4
4
  CurveType,
5
5
  Pointer,
6
6
  RuleType,
7
+ RulesConfig,
7
8
  arrowConfigType,
8
9
  secondaryLineConfigType,
9
10
  secondaryYAxisType,
@@ -75,6 +76,7 @@ export type LineChartPropsType = {
75
76
  rulesType?: RuleType;
76
77
  dashWidth?: number;
77
78
  dashGap?: number;
79
+ rulesConfigArray?: Array<RulesConfig>;
78
80
  showReferenceLine1?: boolean;
79
81
  referenceLine1Config?: referenceConfigType;
80
82
  referenceLine1Position?: number;
@@ -102,6 +104,12 @@ export type LineChartPropsType = {
102
104
  areaChart3?: boolean;
103
105
  areaChart4?: boolean;
104
106
  areaChart5?: boolean;
107
+ stepChart?: boolean;
108
+ stepChart1?: boolean;
109
+ stepChart2?: boolean;
110
+ stepChart3?: boolean;
111
+ stepChart4?: boolean;
112
+ stepChart5?: boolean;
105
113
 
106
114
  disableScroll?: boolean;
107
115
  pointerConfig?: Pointer;
@@ -255,6 +263,8 @@ export type LineChartPropsType = {
255
263
  yAxisLabelTexts?: Array<string>;
256
264
  xAxisLabelTexts?: Array<string>;
257
265
  xAxisLabelTextStyle?: any;
266
+ xAxisLabelsHeight?: number;
267
+ xAxisLabelsVerticalShift?: number;
258
268
  width?: number;
259
269
  yAxisLabelPrefix?: String;
260
270
  yAxisLabelSuffix?: String;
@@ -1,4 +1,4 @@
1
- import React, {useState} from 'react';
1
+ import React, {useEffect, useState} from 'react';
2
2
  import {View, ColorValue} from 'react-native';
3
3
  import {PieChartMain} from './main';
4
4
  import {FontStyle} from 'react-native-svg';
@@ -81,21 +81,56 @@ export const PieChart = (props: propTypes) => {
81
81
  ? radius / 10
82
82
  : 0;
83
83
  const pi = props.semiCircle ? Math.PI / 2 : Math.PI;
84
- const [selectedIndex, setSelectedIndex] = useState(
85
- props.data.findIndex(item => item.focused === true),
84
+ const [selectedIndex, setSelectedIndex] = useState(-1); // at the start, nothing is selected
85
+ // because we're going to use a useEffect, we need startAngle and total to be state variables
86
+ const [startAngle, setStartAngle] = useState(
87
+ props.initialAngle || (props.semiCircle ? -pi : 0),
86
88
  );
87
- let startAngle = props.initialAngle || (props.semiCircle ? -pi : 0);
88
- let total = 0;
89
- props.data.forEach(item => {
90
- total += item.value;
91
- });
92
- if (selectedIndex !== 0) {
93
- let start = 0;
94
- for (let i = 0; i < selectedIndex; i++) {
95
- start += props.data[i].value;
89
+ const [total, setTotal] = useState(0);
90
+
91
+ useEffect(() => {
92
+ // Update the total, this could be use to replace the forEach : const newTotal = props.data.reduce((acc, item) => acc + item.value, 0);
93
+ let newTotal = 0;
94
+ props.data.forEach(item => {
95
+ newTotal += item.value;
96
+ });
97
+ setTotal(newTotal);
98
+
99
+ // Update selectedIndex based on focused item
100
+ const newSelectedIndex = props.data.findIndex(
101
+ item => item.focused === true,
102
+ );
103
+ setSelectedIndex(newSelectedIndex);
104
+
105
+ // Calculate the new start angle
106
+ let newStartAngle = props.initialAngle || (props.semiCircle ? -pi : 0);
107
+ if (newSelectedIndex !== -1) {
108
+ // it was !== 0 here before, which would not work, it's either !==-1 or >=0
109
+ // This could be used to replace the for loop that was used before
110
+ const sumBeforeSelectedIndex = props.data
111
+ .slice(0, newSelectedIndex)
112
+ .reduce((acc, item) => acc + item.value, 0);
113
+ setStartAngle(
114
+ newStartAngle + (2 * pi * sumBeforeSelectedIndex) / newTotal,
115
+ );
116
+ } else {
117
+ setStartAngle(newStartAngle);
96
118
  }
97
- startAngle += (2 * pi * start) / total;
98
- }
119
+ }, [props.data, props.initialAngle, props.semiCircle]);
120
+
121
+ useEffect(() => {
122
+ if (selectedIndex !== -1) {
123
+ const newStartAngle = props.initialAngle || (props.semiCircle ? -pi : 0);
124
+ let start = 0;
125
+ for (let i = 0; i < selectedIndex; i++) {
126
+ start += props.data[i].value;
127
+ }
128
+ if (total) {
129
+ setStartAngle(newStartAngle + (2 * pi * start) / total);
130
+ }
131
+ }
132
+ }, [selectedIndex]);
133
+
99
134
  return (
100
135
  <View
101
136
  style={{
@@ -105,6 +140,7 @@ export const PieChart = (props: propTypes) => {
105
140
  marginTop: extraRadiusForFocused * 2,
106
141
  }}>
107
142
  {props.data.length > 1 &&
143
+ props.data[selectedIndex] && // don't forget to add this one so there are no errors when the data is empty / updating
108
144
  (props.focusOnPress || props.sectionAutoFocus) &&
109
145
  selectedIndex !== -1 && (
110
146
  <View
@@ -88,7 +88,12 @@ export const PieChartMain = (props: propTypes) => {
88
88
  if (propData[i].value !== 0) {
89
89
  data.push(propData[i]);
90
90
  } else {
91
- data.push({...propData[i], value: 0.0000009});
91
+ data.push({
92
+ ...propData[i],
93
+ value:
94
+ props.data.map(item => item.value).reduce((v, a) => v + a) /
95
+ 36000000,
96
+ });
92
97
  }
93
98
  }
94
99
  }
@@ -149,7 +154,6 @@ export const PieChartMain = (props: propTypes) => {
149
154
  total = 0;
150
155
 
151
156
  data.forEach((item: any) => {
152
- total += item.value;
153
157
  if (item.shiftX || item.shiftY) {
154
158
  isDataShifted = true;
155
159
  if (minShiftX > item.shiftX) {
@@ -38,6 +38,7 @@ export const AxesAndRulesDefaults = {
38
38
  xAxisThickness: 1,
39
39
  xAxisType: ruleTypes.SOLID,
40
40
  xAxisTextNumberOfLines: 1,
41
+ xAxisLabelsVerticalShift: 0,
41
42
  dashWidth: 4,
42
43
  dashGap: 8,
43
44
  backgroundColor: 'transparent',
@@ -46,6 +47,7 @@ export const AxesAndRulesDefaults = {
46
47
  rulesType: ruleTypes.DASHED,
47
48
  rulesThickness: 1,
48
49
  rulesColor: 'lightgray',
50
+ rulesConfigArray: [],
49
51
 
50
52
  rotateLabel: false,
51
53
 
@@ -226,6 +228,9 @@ export const defaultPointerConfig = {
226
228
  pointerVanishDelay: 150,
227
229
  activatePointersOnLongPress: false,
228
230
  activatePointersDelay: 150,
231
+ initialPointerIndex: -1,
232
+ initialPointerAppearDelay: 0,
233
+ persistPointer: false,
229
234
  hidePointer1: false,
230
235
  hidePointer2: false,
231
236
  hidePointer3: false,
@@ -224,6 +224,8 @@ export const getAxesAndRulesProps = (
224
224
  xAxisColor: props.xAxisColor,
225
225
  xAxisLength: props.xAxisLength,
226
226
  xAxisType: props.xAxisType,
227
+ xAxisLabelsHeight: props.xAxisLabelsHeight,
228
+ xAxisLabelsVerticalShift: props.xAxisLabelsVerticalShift,
227
229
  dashWidth: props.dashWidth,
228
230
  dashGap: props.dashGap,
229
231
  backgroundColor: props.backgroundColor,
@@ -232,6 +234,7 @@ export const getAxesAndRulesProps = (
232
234
  rulesType: props.rulesType,
233
235
  rulesThickness: props.rulesThickness,
234
236
  rulesColor: props.rulesColor,
237
+ rulesConfigArray: props.rulesConfigArray,
235
238
  showYAxisIndices: props.showYAxisIndices,
236
239
  yAxisIndicesHeight: props.yAxisIndicesHeight,
237
240
  yAxisIndicesWidth: props.yAxisIndicesWidth,
@@ -14,6 +14,15 @@ export enum CurveType {
14
14
  QUADRATIC,
15
15
  }
16
16
 
17
+ export type RulesConfig = {
18
+ rulesLength?: number;
19
+ rulesColor?: ColorValue;
20
+ rulesThickness?: number;
21
+ rulesType?: RuleType;
22
+ dashWidth?: number;
23
+ dashGap?: number;
24
+ }
25
+
17
26
  export type secondaryYAxisType = {
18
27
  noOfSections?: number;
19
28
  maxValue?: number;
@@ -103,6 +112,7 @@ export type horizSectionPropTypes = {
103
112
  xAxisType: RuleType;
104
113
  dashWidth: number;
105
114
  dashGap: number;
115
+ rulesConfigArray: Array<RulesConfig>;
106
116
  backgroundColor: string;
107
117
  hideRules: boolean;
108
118
  rulesLength: number;
@@ -243,6 +253,9 @@ export type Pointer = {
243
253
  pointerVanishDelay?: number;
244
254
  activatePointersOnLongPress?: boolean;
245
255
  activatePointersDelay?: number;
256
+ initialPointerIndex?: number;
257
+ initialPointerAppearDelay?: number;
258
+ persistPointer?: boolean;
246
259
  hidePointer1?: boolean;
247
260
  hidePointer2?: boolean;
248
261
  hidePointer3?: boolean;