react-native-gifted-charts 1.3.22 → 1.3.24

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.22",
3
+ "version": "1.3.24",
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": [
@@ -39,6 +39,8 @@ type propTypes = {
39
39
  showValuesAsTopLabel: boolean;
40
40
  topLabelContainerStyle?: any;
41
41
  topLabelTextStyle?: any;
42
+ barBorderWidth?: number;
43
+ barBorderColor: ColorValue;
42
44
  barBorderRadius?: number;
43
45
  barBorderTopLeftRadius?: number;
44
46
  barBorderTopRightRadius?: number;
@@ -66,6 +68,8 @@ const Animated2DWithGradient = (props: propTypes) => {
66
68
  containerHeight,
67
69
  maxValue,
68
70
  barMarginBottom,
71
+ barBorderWidth,
72
+ barBorderColor,
69
73
  barBorderRadius,
70
74
  barBorderTopLeftRadius,
71
75
  barBorderTopRightRadius,
@@ -150,6 +154,8 @@ const Animated2DWithGradient = (props: propTypes) => {
150
154
  height: '100%',
151
155
  backgroundColor:
152
156
  item.frontColor || props.frontColor || 'black',
157
+ borderWidth: barBorderWidth ?? 0,
158
+ borderColor: barBorderColor,
153
159
  borderRadius: item.barBorderRadius ?? barBorderRadius ?? 0,
154
160
  borderTopLeftRadius:
155
161
  item.barBorderTopLeftRadius ??
@@ -211,6 +217,8 @@ const Animated2DWithGradient = (props: propTypes) => {
211
217
  position: 'absolute',
212
218
  width: '100%',
213
219
  height: '100%',
220
+ borderWidth: barBorderWidth ?? 0,
221
+ borderColor: barBorderColor,
214
222
  borderRadius: item.barBorderRadius ?? barBorderRadius ?? 0,
215
223
  borderTopLeftRadius:
216
224
  item.barBorderTopLeftRadius ??
@@ -1,7 +1,6 @@
1
1
  import React, {Component} from 'react';
2
2
  import {View, TouchableOpacity, Animated, Text, ColorValue} from 'react-native';
3
- import ThreeDBar from '../Components/ThreeDBar';
4
- import AnimatedBar from '../Components/AnimatedBar';
3
+ import AnimatedThreeDBar from '../Components/AnimatedThreeDBar';
5
4
  import LinearGradient from 'react-native-linear-gradient';
6
5
  import Animated2DWithGradient from './Animated2DWithGradient';
7
6
  import Cap from '../Components/BarSpecificComponents/cap';
@@ -61,6 +60,8 @@ type Props = {
61
60
  rtl: boolean;
62
61
  intactTopLabel: boolean;
63
62
  showValuesAsTopLabel?: boolean;
63
+ barBorderWidth?: number;
64
+ barBorderColor: ColorValue;
64
65
  barBorderRadius?: number;
65
66
  barBorderTopLeftRadius?: number;
66
67
  barBorderTopRightRadius?: number;
@@ -96,6 +97,8 @@ const RenderBars = (props: Props) => {
96
97
  side,
97
98
  data,
98
99
  barStyle,
100
+ barBorderWidth,
101
+ barBorderColor,
99
102
  barBorderRadius,
100
103
  barBorderTopLeftRadius,
101
104
  barBorderTopRightRadius,
@@ -253,6 +256,8 @@ const RenderBars = (props: Props) => {
253
256
  position: 'absolute',
254
257
  width: '100%',
255
258
  height: '100%',
259
+ borderWidth: barBorderWidth ?? 0,
260
+ borderColor: barBorderColor,
256
261
  borderRadius: item.barBorderRadius ?? barBorderRadius ?? 0,
257
262
  borderTopLeftRadius:
258
263
  item.barBorderTopLeftRadius ??
@@ -405,7 +410,7 @@ const RenderBars = (props: Props) => {
405
410
  (pointerConfig && pointerConfig.barTouchable !== true);
406
411
 
407
412
  const barContent = () => {
408
- const animated2DWithGradient = noGradient => (
413
+ const animated2DWithGradient = (noGradient, noAnimation) => (
409
414
  <Animated2DWithGradient
410
415
  barBackgroundPattern={props.barBackgroundPattern}
411
416
  patternId={props.patternId}
@@ -417,6 +422,7 @@ const RenderBars = (props: Props) => {
417
422
  roundedBottom={props.roundedBottom || false}
418
423
  roundedTop={props.roundedTop || false}
419
424
  noGradient={noGradient}
425
+ noAnimation={noAnimation}
420
426
  gradientColor={noGradient ? undefined : props.gradientColor}
421
427
  frontColor={props.frontColor || 'black'}
422
428
  containerHeight={containerHeight}
@@ -433,6 +439,8 @@ const RenderBars = (props: Props) => {
433
439
  showValuesAsTopLabel={!!showValuesAsTopLabel}
434
440
  topLabelContainerStyle={topLabelContainerStyle}
435
441
  topLabelTextStyle={topLabelTextStyle}
442
+ barBorderWidth={barBorderWidth}
443
+ barBorderColor={barBorderColor}
436
444
  barBorderRadius={props.barBorderRadius || 0}
437
445
  barBorderTopLeftRadius={barBorderTopLeftRadius}
438
446
  barBorderTopRightRadius={barBorderTopRightRadius}
@@ -459,77 +467,45 @@ const RenderBars = (props: Props) => {
459
467
  />
460
468
  )}
461
469
  {isThreeD ? (
462
- isAnimated ? (
463
- <AnimatedBar
464
- barBackgroundPattern={
465
- item.barBackgroundPattern || props.barBackgroundPattern
466
- }
467
- patternId={item.patternId || props.patternId}
468
- width={item.barWidth || props.barWidth || 30}
469
- barStyle={barStyle}
470
- item={item}
471
- sideWidth={
472
- item.sideWidth ||
473
- props.sideWidth ||
474
- (item.barWidth || props.barWidth || 30) / 2
475
- }
476
- side={side || 'left'}
477
- frontColor={item.frontColor || props.frontColor || ''}
478
- sideColor={item.sideColor || props.sideColor || ''}
479
- topColor={item.topColor || props.topColor || ''}
480
- showGradient={item.showGradient || props.showGradient || false}
481
- gradientColor={item.gradientColor || props.gradientColor}
482
- opacity={opacity || 1}
483
- animationDuration={animationDuration || 800}
484
- height={barHeight}
485
- intactTopLabel={intactTopLabel}
486
- showValuesAsTopLabel={!!showValuesAsTopLabel}
487
- topLabelContainerStyle={topLabelContainerStyle}
488
- topLabelTextStyle={topLabelTextStyle}
489
- horizontal={horizontal}
490
- />
491
- ) : (
492
- <ThreeDBar
493
- barBackgroundPattern={
494
- item.barBackgroundPattern || props.barBackgroundPattern
495
- }
496
- patternId={item.patternId || props.patternId}
497
- style={{}}
498
- color={''}
499
- width={item.barWidth || props.barWidth || 30}
500
- sideWidth={
501
- item.sideWidth ||
502
- props.sideWidth ||
503
- (item.barWidth || props.barWidth || 30) / 2
504
- }
505
- barStyle={barStyle}
506
- item={item}
507
- side={side || 'left'}
508
- frontColor={item.frontColor || props.frontColor || ''}
509
- sideColor={item.sideColor || props.sideColor || ''}
510
- topColor={item.topColor || props.topColor || ''}
511
- showGradient={item.showGradient || props.showGradient || false}
512
- gradientColor={item.gradientColor || props.gradientColor}
513
- opacity={opacity || 1}
514
- horizontal={horizontal}
515
- intactTopLabel={intactTopLabel}
516
- showValuesAsTopLabel={!!showValuesAsTopLabel}
517
- topLabelContainerStyle={topLabelContainerStyle}
518
- topLabelTextStyle={topLabelTextStyle}
519
- height={barHeight}
520
- value={item.value}
521
- />
522
- )
470
+ <AnimatedThreeDBar
471
+ barBackgroundPattern={
472
+ item.barBackgroundPattern || props.barBackgroundPattern
473
+ }
474
+ patternId={item.patternId || props.patternId}
475
+ width={item.barWidth || props.barWidth || 30}
476
+ barStyle={barStyle}
477
+ item={item}
478
+ sideWidth={
479
+ item.sideWidth ||
480
+ props.sideWidth ||
481
+ (item.barWidth || props.barWidth || 30) / 2
482
+ }
483
+ side={side || 'left'}
484
+ frontColor={item.frontColor || props.frontColor || ''}
485
+ sideColor={item.sideColor || props.sideColor || ''}
486
+ topColor={item.topColor || props.topColor || ''}
487
+ showGradient={item.showGradient || props.showGradient || false}
488
+ gradientColor={item.gradientColor || props.gradientColor}
489
+ opacity={opacity || 1}
490
+ height={barHeight}
491
+ intactTopLabel={intactTopLabel}
492
+ showValuesAsTopLabel={!!showValuesAsTopLabel}
493
+ topLabelContainerStyle={topLabelContainerStyle}
494
+ topLabelTextStyle={topLabelTextStyle}
495
+ horizontal={horizontal}
496
+ isAnimated={isAnimated}
497
+ animationDuration={animationDuration || 800}
498
+ />
523
499
  ) : item.showGradient || props.showGradient ? (
524
500
  isAnimated ? (
525
- animated2DWithGradient(false)
501
+ animated2DWithGradient(false, false)
526
502
  ) : (
527
503
  static2DWithGradient(item)
528
504
  )
529
505
  ) : isAnimated ? (
530
- animated2DWithGradient(true)
506
+ animated2DWithGradient(true, false)
531
507
  ) : (
532
- animated2DWithGradient(true)
508
+ animated2DWithGradient(true, true)
533
509
  )}
534
510
  {isAnimated
535
511
  ? renderAnimatedLabel(label, labelTextStyle, item.value)
@@ -12,6 +12,12 @@ import {
12
12
  import LinearGradient from 'react-native-linear-gradient';
13
13
  import Svg, {Defs, Rect} from 'react-native-svg';
14
14
  import {BarDefaults} from '../utils/constants';
15
+ import {
16
+ isValueSumZeroForStackBottom,
17
+ isValueSumZeroForStackTop,
18
+ } from '../utils';
19
+ import {stackItemType} from './types';
20
+ import {Pointer} from '../utils/types';
15
21
 
16
22
  if (Platform.OS === 'android') {
17
23
  UIManager.setLayoutAnimationEnabledExperimental &&
@@ -47,7 +53,18 @@ type Props = {
47
53
  xAxisIndicesColor: ColorValue;
48
54
  horizontal: boolean;
49
55
  intactTopLabel: boolean;
56
+ barBorderWidth?: number;
57
+ barBorderColor: ColorValue;
50
58
  barBorderRadius?: number;
59
+ barBorderTopLeftRadius?: number;
60
+ barBorderTopRightRadius?: number;
61
+ barBorderBottomLeftRadius?: number;
62
+ barBorderBottomRightRadius?: number;
63
+ stackBorderRadius?: number;
64
+ stackBorderTopLeftRadius?: number;
65
+ stackBorderTopRightRadius?: number;
66
+ stackBorderBottomLeftRadius?: number;
67
+ stackBorderBottomRightRadius?: number;
51
68
  xAxisThickness: number;
52
69
  barBackgroundPattern?: Function;
53
70
  patternId?: String;
@@ -66,45 +83,9 @@ type Props = {
66
83
  stackData: Array<stackItemType>;
67
84
  isAnimated?: boolean;
68
85
  animationDuration?: number;
86
+ pointerConfig?: Pointer;
69
87
  };
70
- export type stackItemType = {
71
- onPress?: any;
72
- label?: String;
73
- barWidth?: number;
74
- spacing?: number;
75
- labelTextStyle?: any;
76
- topLabelComponent?: Function;
77
- topLabelContainerStyle?: any;
78
- disablePress?: any;
79
- color?: ColorValue;
80
- showGradient?: boolean;
81
- gradientColor?: any;
82
- capThickness?: number;
83
- capColor?: ColorValue;
84
- capRadius?: number;
85
- labelComponent?: Function;
86
- borderRadius?: number;
87
- stacks: Array<{
88
- value: number;
89
- color?: ColorValue;
90
- onPress?: (event: GestureResponderEvent) => void;
91
- marginBottom?: number;
92
- barBorderRadius?: number;
93
- borderTopLeftRadius?: number;
94
- borderTopRightRadius?: number;
95
- borderBottomLeftRadius?: number;
96
- borderBottomRightRadius?: number;
97
- showGradient?: boolean;
98
- gradientColor?: ColorValue;
99
- barWidth?: number;
100
- innerBarComponent?: Function;
101
- }>;
102
- barBackgroundPattern?: Function;
103
- barBorderRadius?: number;
104
- patternId?: String;
105
- leftShiftForTooltip?: number;
106
- showXAxisIndex?: boolean;
107
- };
88
+
108
89
  const RenderStackBars = (props: Props) => {
109
90
  const {
110
91
  barBackgroundPattern,
@@ -131,10 +112,25 @@ const RenderStackBars = (props: Props) => {
131
112
  stackData,
132
113
  isAnimated,
133
114
  animationDuration = BarDefaults.animationDuration,
115
+ barBorderWidth,
116
+ barBorderColor,
117
+ stackBorderRadius,
118
+ stackBorderTopLeftRadius,
119
+ stackBorderTopRightRadius,
120
+ stackBorderBottomLeftRadius,
121
+ stackBorderBottomRightRadius,
134
122
  } = props;
135
123
  const cotainsNegative = item.stacks.some(item => item.value < 0);
136
124
  const noAnimation = cotainsNegative || !isAnimated;
137
125
 
126
+ const {
127
+ borderRadius,
128
+ borderTopLeftRadius,
129
+ borderTopRightRadius,
130
+ borderBottomLeftRadius,
131
+ borderBottomRightRadius,
132
+ } = item;
133
+
138
134
  let leftSpacing = initialSpacing;
139
135
  for (let i = 0; i < index; i++) {
140
136
  leftSpacing +=
@@ -213,6 +209,76 @@ const RenderStackBars = (props: Props) => {
213
209
  setTimeout(() => elevate(), Platform.OS == 'ios' ? 10 : 100);
214
210
  };
215
211
 
212
+ const getStackBorderRadii = (item: stackItemType, index: number) => {
213
+ const stackItem = item.stacks[index];
214
+ const borderRadii = {
215
+ borderTopLeftRadius:
216
+ stackItem.borderTopLeftRadius ??
217
+ borderTopLeftRadius ??
218
+ stackItem.borderRadius ??
219
+ borderRadius ??
220
+ props.barBorderTopLeftRadius ??
221
+ props.barBorderRadius ??
222
+ 0,
223
+ borderTopRightRadius:
224
+ stackItem.borderTopRightRadius ??
225
+ borderTopRightRadius ??
226
+ stackItem.borderRadius ??
227
+ borderRadius ??
228
+ props.barBorderTopRightRadius ??
229
+ props.barBorderRadius ??
230
+ 0,
231
+ borderBottomLeftRadius:
232
+ stackItem.borderBottomLeftRadius ??
233
+ borderBottomLeftRadius ??
234
+ stackItem.borderRadius ??
235
+ borderRadius ??
236
+ props.barBorderBottomLeftRadius ??
237
+ props.barBorderRadius ??
238
+ 0,
239
+ borderBottomRightRadius:
240
+ stackItem.borderBottomRightRadius ??
241
+ borderBottomRightRadius ??
242
+ stackItem.borderRadius ??
243
+ borderRadius ??
244
+ props.barBorderBottomRightRadius ??
245
+ props.barBorderRadius ??
246
+ 0,
247
+ };
248
+ if (
249
+ !borderRadii.borderTopLeftRadius &&
250
+ isValueSumZeroForStackTop(item, index)
251
+ ) {
252
+ const stackTopLeft = stackBorderTopLeftRadius ?? stackBorderRadius ?? 0;
253
+ borderRadii.borderTopLeftRadius = stackTopLeft;
254
+ }
255
+ if (
256
+ !borderRadii.borderTopRightRadius &&
257
+ isValueSumZeroForStackTop(item, index)
258
+ ) {
259
+ const stackTopRight = stackBorderTopRightRadius ?? stackBorderRadius ?? 0;
260
+ borderRadii.borderTopRightRadius = stackTopRight;
261
+ }
262
+ if (
263
+ !borderRadii.borderBottomLeftRadius &&
264
+ isValueSumZeroForStackBottom(item, index)
265
+ ) {
266
+ const stackBottomLeft =
267
+ stackBorderBottomLeftRadius ?? stackBorderRadius ?? 0;
268
+ borderRadii.borderBottomLeftRadius = stackBottomLeft;
269
+ }
270
+ if (
271
+ !borderRadii.borderBottomRightRadius &&
272
+ isValueSumZeroForStackBottom(item, index)
273
+ ) {
274
+ const stackBottomRight =
275
+ stackBorderBottomRightRadius ?? stackBorderRadius ?? 0;
276
+ borderRadii.borderBottomRightRadius = stackBottomRight;
277
+ }
278
+
279
+ return borderRadii;
280
+ };
281
+
216
282
  const barWrapper = () => {
217
283
  return noAnimation ? (
218
284
  static2DSimple()
@@ -258,52 +324,37 @@ const RenderStackBars = (props: Props) => {
258
324
  },
259
325
  ]}>
260
326
  {item.stacks.map((stackItem, index) => {
327
+ const borderRadii = getStackBorderRadii(item, index);
261
328
  return (
262
329
  <TouchableOpacity
263
330
  key={index}
264
331
  onPress={stackItem.onPress}
265
332
  activeOpacity={activeOpacity}
266
333
  disabled={disablePress || !stackItem.onPress}
267
- style={[
268
- {
269
- position: 'absolute',
270
- bottom: getPosition(index) + (stackItem.marginBottom || 0),
271
- width: '100%',
272
- height:
273
- (Math.abs(stackItem.value) * (containerHeight || 200)) /
274
- (maxValue || 200) -
275
- (stackItem.marginBottom || 0),
276
- backgroundColor:
277
- stackItem.color || item.color || props.color || 'black',
278
- borderRadius:
279
- stackItem.barBorderRadius || props.barBorderRadius || 0,
280
- },
281
- !props.barBorderRadius &&
282
- !stackItem.barBorderRadius && {
283
- borderTopLeftRadius: stackItem.borderTopLeftRadius || 0,
284
- borderTopRightRadius: stackItem.borderTopRightRadius || 0,
285
- borderBottomLeftRadius:
286
- stackItem.borderBottomLeftRadius || 0,
287
- borderBottomRightRadius:
288
- stackItem.borderBottomRightRadius || 0,
289
- },
290
- ]}>
334
+ style={{
335
+ position: 'absolute',
336
+ bottom: getPosition(index) + (stackItem.marginBottom || 0),
337
+ width: '100%',
338
+ height:
339
+ (Math.abs(stackItem.value) * (containerHeight || 200)) /
340
+ (maxValue || 200) -
341
+ (stackItem.marginBottom || 0),
342
+ backgroundColor:
343
+ stackItem.color || item.color || props.color || 'black',
344
+ borderWidth: barBorderWidth ?? 0,
345
+ borderColor: barBorderColor,
346
+ ...borderRadii,
347
+ }}>
291
348
  {stackItem.showGradient ||
292
349
  item.showGradient ||
293
350
  props.showGradient ? (
294
351
  <LinearGradient
295
- style={[
296
- {
297
- position: 'absolute',
298
- width: '100%',
299
- height: '100%',
300
- borderRadius:
301
- stackItem.barBorderRadius ||
302
- item.barBorderRadius ||
303
- props.barBorderRadius ||
304
- 0,
305
- },
306
- ]}
352
+ style={{
353
+ position: 'absolute',
354
+ width: '100%',
355
+ height: '100%',
356
+ ...borderRadii,
357
+ }}
307
358
  start={{x: 0, y: 0}}
308
359
  end={{x: 0, y: 1}}
309
360
  colors={[
@@ -365,6 +416,11 @@ const RenderStackBars = (props: Props) => {
365
416
  return (
366
417
  <>
367
418
  <View
419
+ pointerEvents={
420
+ props.pointerConfig
421
+ ? props.pointerConfig.pointerEvents ?? 'none'
422
+ : 'auto'
423
+ }
368
424
  style={[
369
425
  {
370
426
  // overflow: 'visible',
@@ -373,6 +429,18 @@ const RenderStackBars = (props: Props) => {
373
429
  height: totalHeight,
374
430
  marginRight: spacing,
375
431
  },
432
+
433
+ props.pointerConfig
434
+ ? {
435
+ transform: [
436
+ {
437
+ translateY:
438
+ (containerHeight || 200) -
439
+ (totalHeight - 10 + xAxisLabelsVerticalShift),
440
+ },
441
+ ],
442
+ }
443
+ : null,
376
444
  ]}>
377
445
  {/* {props.showVerticalLines && (
378
446
  <View
@@ -220,6 +220,7 @@ export const BarChart = (props: BarChartPropsType) => {
220
220
  const autoShiftLabels = props.autoShiftLabels ?? false;
221
221
 
222
222
  const barWidth = props.barWidth || BarDefaults.barWidth;
223
+ const barBorderColor = props.barBorderColor ?? BarDefaults.barBorderColor;
223
224
 
224
225
  const extendedContainerHeight = getExtendedContainerHeightWithPadding(
225
226
  containerHeight,
@@ -521,10 +522,13 @@ export const BarChart = (props: BarChartPropsType) => {
521
522
  lineConfig.arrowConfig.width,
522
523
  lineConfig.arrowConfig.showArrowBase,
523
524
  ]);
524
-
525
525
  useEffect(() => {
526
526
  if (initialPointerIndex !== -1) {
527
- const item = data[initialPointerIndex];
527
+ const item = (props.stackData ?? data)[initialPointerIndex];
528
+ const stackSum = item.stacks?.reduce(
529
+ (acc, stack) => acc + (stack.value ?? 0),
530
+ 0,
531
+ );
528
532
  const x =
529
533
  initialSpacing +
530
534
  (spacing + barWidth) * initialPointerIndex -
@@ -532,7 +536,7 @@ export const BarChart = (props: BarChartPropsType) => {
532
536
  barWidth / 2;
533
537
  const y =
534
538
  containerHeight -
535
- (item.value * containerHeight) / maxValue -
539
+ ((stackSum ?? item.value) * containerHeight) / maxValue -
536
540
  (pointerRadius || pointerHeight / 2) +
537
541
  10;
538
542
  if (initialPointerAppearDelay) {
@@ -648,10 +652,14 @@ export const BarChart = (props: BarChartPropsType) => {
648
652
  setPointerX(z);
649
653
  setPointerIndex(factor);
650
654
  let item, y;
651
- item = data[factor];
655
+ item = (props.stackData ?? data)[factor];
656
+ const stackSum = item.stacks?.reduce(
657
+ (acc, stack) => acc + (stack.value ?? 0),
658
+ 0,
659
+ );
652
660
  y =
653
661
  containerHeight -
654
- (item.value * containerHeight) / maxValue -
662
+ ((stackSum ?? item.value) * containerHeight) / maxValue -
655
663
  (pointerRadius || pointerHeight / 2) +
656
664
  10;
657
665
  setPointerY(y);
@@ -676,7 +684,7 @@ export const BarChart = (props: BarChartPropsType) => {
676
684
  let factor =
677
685
  (x - initialSpacing - barWidth / 2) / (spacing + barWidth);
678
686
  factor = Math.round(factor);
679
- factor = Math.min(factor, data.length - 1);
687
+ factor = Math.min(factor, (props.stackData ?? data).length - 1);
680
688
  factor = Math.max(factor, 0);
681
689
  let z =
682
690
  initialSpacing +
@@ -686,10 +694,14 @@ export const BarChart = (props: BarChartPropsType) => {
686
694
  let item, y;
687
695
  setPointerX(z);
688
696
  setPointerIndex(factor);
689
- item = data[factor];
697
+ item = (props.stackData ?? data)[factor];
698
+ const stackSum = item.stacks?.reduce(
699
+ (acc, stack) => acc + (stack.value ?? 0),
700
+ 0,
701
+ );
690
702
  y =
691
703
  containerHeight -
692
- (item.value * containerHeight) / maxValue -
704
+ ((stackSum ?? item.value) * containerHeight) / maxValue -
693
705
  (pointerRadius || pointerHeight / 2) +
694
706
  10;
695
707
  setPointerY(y);
@@ -760,6 +772,8 @@ export const BarChart = (props: BarChartPropsType) => {
760
772
  showValuesAsTopLabel: props.showValuesAsTopLabel,
761
773
  topLabelContainerStyle: props.topLabelContainerStyle,
762
774
  topLabelTextStyle: props.topLabelTextStyle,
775
+ barBorderWidth: props.barBorderWidth,
776
+ barBorderColor: barBorderColor,
763
777
  barBorderRadius: props.barBorderRadius,
764
778
  barBorderTopLeftRadius: props.barBorderTopLeftRadius,
765
779
  barBorderTopRightRadius: props.barBorderTopRightRadius,
@@ -798,6 +812,11 @@ export const BarChart = (props: BarChartPropsType) => {
798
812
  stackData={props.stackData || []}
799
813
  isAnimated={isAnimated}
800
814
  animationDuration={animationDuration}
815
+ stackBorderRadius={props.stackBorderRadius}
816
+ stackBorderTopLeftRadius={props.stackBorderTopLeftRadius}
817
+ stackBorderTopRightRadius={props.stackBorderTopRightRadius}
818
+ stackBorderBottomLeftRadius={props.stackBorderBottomLeftRadius}
819
+ stackBorderBottomRightRadius={props.stackBorderBottomRightRadius}
801
820
  {...getPropsCommonForBarAndStack(item, index)}
802
821
  />
803
822
  );
@@ -1,5 +1,4 @@
1
- import {ColorValue, View} from 'react-native';
2
- import {stackItemType} from '../BarChart/RenderStackBars';
1
+ import {ColorValue, GestureResponderEvent, View} from 'react-native';
3
2
  import {yAxisSides} from '../utils/constants';
4
3
  import {
5
4
  CurveType,
@@ -9,6 +8,48 @@ import {
9
8
  secondaryYAxisType,
10
9
  } from '../utils/types';
11
10
 
11
+ export type stackItemType = {
12
+ onPress?: any;
13
+ label?: String;
14
+ barWidth?: number;
15
+ spacing?: number;
16
+ labelTextStyle?: any;
17
+ topLabelComponent?: Function;
18
+ topLabelContainerStyle?: any;
19
+ disablePress?: any;
20
+ color?: ColorValue;
21
+ showGradient?: boolean;
22
+ gradientColor?: any;
23
+ capThickness?: number;
24
+ capColor?: ColorValue;
25
+ capRadius?: number;
26
+ labelComponent?: Function;
27
+ stacks: Array<{
28
+ value: number;
29
+ color?: ColorValue;
30
+ onPress?: (event: GestureResponderEvent) => void;
31
+ marginBottom?: number;
32
+ borderRadius?: number;
33
+ borderTopLeftRadius?: number;
34
+ borderTopRightRadius?: number;
35
+ borderBottomLeftRadius?: number;
36
+ borderBottomRightRadius?: number;
37
+ showGradient?: boolean;
38
+ gradientColor?: ColorValue;
39
+ barWidth?: number;
40
+ innerBarComponent?: Function;
41
+ }>;
42
+ barBackgroundPattern?: Function;
43
+ borderRadius?: number;
44
+ borderTopLeftRadius?: number;
45
+ borderTopRightRadius?: number;
46
+ borderBottomLeftRadius?: number;
47
+ borderBottomRightRadius?: number;
48
+ patternId?: String;
49
+ leftShiftForTooltip?: number;
50
+ showXAxisIndex?: boolean;
51
+ };
52
+
12
53
  export type BarChartPropsType = {
13
54
  width?: number;
14
55
  height?: number;
@@ -131,11 +172,18 @@ export type BarChartPropsType = {
131
172
  topLabelTextStyle?: any;
132
173
 
133
174
  horizSections?: Array<sectionType>;
175
+ barBorderWidth?: number;
176
+ barBorderColor?: ColorValue;
134
177
  barBorderRadius?: number;
135
178
  barBorderTopLeftRadius?: number;
136
179
  barBorderTopRightRadius?: number;
137
180
  barBorderBottomLeftRadius?: number;
138
181
  barBorderBottomRightRadius?: number;
182
+ stackBorderRadius?: number;
183
+ stackBorderTopLeftRadius?: number;
184
+ stackBorderTopRightRadius?: number;
185
+ stackBorderBottomLeftRadius?: number;
186
+ stackBorderBottomRightRadius?: number;
139
187
  hideOrigin?: boolean;
140
188
  labelWidth?: number;
141
189
  yAxisLabelTexts?: Array<string>;
@@ -167,6 +215,7 @@ export type BarChartPropsType = {
167
215
  };
168
216
  type lineConfigType = {
169
217
  initialSpacing?: number;
218
+ spacing?: number;
170
219
  curved?: boolean;
171
220
  curvature?: number;
172
221
  curveType?: CurveType;
@@ -24,6 +24,7 @@ type trianglePropTypes = {
24
24
  };
25
25
 
26
26
  type animatedBarPropTypes = {
27
+ isAnimated?: boolean;
27
28
  animationDuration: number;
28
29
  width: number;
29
30
  sideWidth: number;
@@ -73,21 +74,36 @@ const triangleStyles = StyleSheet.create({
73
74
  },
74
75
  });
75
76
 
76
- const AnimatedBar = (props: animatedBarPropTypes) => {
77
- const [initialRender, setInitialRender] = useState(true);
78
- const [height, setHeight] = useState(Platform.OS === 'ios' ? 0 : 20);
77
+ const AnimatedThreeDBar = (props: animatedBarPropTypes) => {
78
+ const {
79
+ isAnimated,
80
+ animationDuration,
81
+ item,
82
+ width,
83
+ sideWidth,
84
+ barStyle,
85
+ barBackgroundPattern,
86
+ patternId,
87
+ intactTopLabel,
88
+ showValuesAsTopLabel,
89
+ topLabelContainerStyle,
90
+ topLabelTextStyle,
91
+ } = props;
79
92
 
80
- const animationDuration = props.animationDuration || 800;
93
+ const [initialRender, setInitialRender] = useState(isAnimated);
94
+ const [height, setHeight] = useState(
95
+ isAnimated ? (Platform.OS === 'ios' ? 0 : 20) : props.height,
96
+ );
81
97
 
82
98
  useEffect(() => {
83
- if (initialRender) {
84
- // labelsAppear();
85
- // increaseOpacity();
86
- setTimeout(() => {
87
- layoutAppear();
88
- }, 20);
89
- } else {
90
- elevate();
99
+ if (isAnimated) {
100
+ if (initialRender) {
101
+ setTimeout(() => {
102
+ layoutAppear();
103
+ }, 20);
104
+ } else {
105
+ elevate();
106
+ }
91
107
  }
92
108
  }, [props.height]);
93
109
 
@@ -109,19 +125,6 @@ const AnimatedBar = (props: animatedBarPropTypes) => {
109
125
  setTimeout(() => elevate(), Platform.OS == 'ios' ? 10 : 100);
110
126
  };
111
127
 
112
- const {
113
- item,
114
- width,
115
- sideWidth,
116
- barStyle,
117
- barBackgroundPattern,
118
- patternId,
119
- intactTopLabel,
120
- showValuesAsTopLabel,
121
- topLabelContainerStyle,
122
- topLabelTextStyle,
123
- } = props;
124
-
125
128
  const showGradient = props.showGradient || false;
126
129
  const gradientColor = props.gradientColor || 'white';
127
130
 
@@ -271,4 +274,4 @@ const AnimatedBar = (props: animatedBarPropTypes) => {
271
274
  );
272
275
  };
273
276
 
274
- export default AnimatedBar;
277
+ export default AnimatedThreeDBar;
@@ -1,5 +1,5 @@
1
1
  import React, {Fragment} from 'react';
2
- import {View, ScrollView} from 'react-native';
2
+ import {View, ScrollView, StyleSheet} from 'react-native';
3
3
  import {renderHorizSections} from './renderHorizSections';
4
4
  import RenderLineInBarChart from './renderLineInBarChart';
5
5
  import RenderVerticalLines from './renderVerticalLines';
@@ -268,7 +268,7 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
268
268
  const verticalLinesProps = {
269
269
  verticalLinesAr,
270
270
  verticalLinesSpacing,
271
- spacing,
271
+ spacing: lineConfig?.spacing ?? spacing,
272
272
  initialSpacing,
273
273
  verticalLinesZIndex,
274
274
  verticalLinesHeight,
@@ -328,21 +328,23 @@ const BarAndLineChartsWrapper = (props: BarAndLineChartsWrapperTypes) => {
328
328
  /*******************************************************************************************************************************************/
329
329
  /*******************************************************************************************************************************************/
330
330
 
331
- const container = {
332
- width: '100%',
333
- height:
334
- containerHeightIncludingBelowXAxis +
335
- labelsExtraHeight +
336
- stepHeight / 2 +
337
- xAxisLabelsVerticalShift +
338
- 50,
339
- marginBottom: (xAxisLabelsHeight ?? xAxisTextNumberOfLines * 18) - 50, //This is to not let the Things that should be rendered below the chart overlap with it
340
- };
331
+ const styles = StyleSheet.create({
332
+ container: {
333
+ width: '100%',
334
+ height:
335
+ containerHeightIncludingBelowXAxis +
336
+ labelsExtraHeight +
337
+ stepHeight / 2 +
338
+ xAxisLabelsVerticalShift +
339
+ 50,
340
+ marginBottom: (xAxisLabelsHeight ?? xAxisTextNumberOfLines * 18) - 50, //This is to not let the Things that should be rendered below the chart overlap with it
341
+ },
342
+ });
341
343
 
342
344
  return (
343
345
  <View
344
346
  style={[
345
- container,
347
+ styles.container,
346
348
  horizontal && {
347
349
  width: actualContainerWidth,
348
350
  transform: transformForHorizontal,
@@ -90,7 +90,7 @@ const RenderLineInBarChart = props => {
90
90
  ),
91
91
  },
92
92
  ]}>
93
- {customDataPoint()}
93
+ {customDataPoint(item, index)}
94
94
  </View>
95
95
  );
96
96
  }
@@ -1827,6 +1827,14 @@ export const LineChart = (props: LineChartPropsType) => {
1827
1827
  const lineGradientEndColor =
1828
1828
  props.lineGradientEndColor ?? LineDefaults.lineGradientEndColor;
1829
1829
 
1830
+ const getPointerY = value =>
1831
+ value
1832
+ ? containerHeight -
1833
+ (value * containerHeight) / maxValue -
1834
+ (pointerRadius || pointerHeight / 2) +
1835
+ 10
1836
+ : 0;
1837
+
1830
1838
  useEffect(() => {
1831
1839
  if (initialPointerIndex !== -1) {
1832
1840
  const item = (data0 ?? data)[initialPointerIndex];
@@ -1835,26 +1843,40 @@ export const LineChart = (props: LineChartPropsType) => {
1835
1843
  spacing * initialPointerIndex -
1836
1844
  (pointerRadius || pointerWidth / 2) -
1837
1845
  1;
1838
- const y =
1839
- containerHeight -
1840
- (item.value * containerHeight) / maxValue -
1841
- (pointerRadius || pointerHeight / 2) +
1842
- 10;
1846
+ const y = getPointerY(item.value);
1847
+ const y2 = getPointerY(data2?.[initialPointerIndex]?.value);
1848
+ const y3 = getPointerY(data3?.[initialPointerIndex]?.value);
1849
+ const y4 = getPointerY(data4?.[initialPointerIndex]?.value);
1850
+ const y5 = getPointerY(data5?.[initialPointerIndex]?.value);
1851
+
1843
1852
  if (initialPointerAppearDelay) {
1844
1853
  setTimeout(() => {
1845
- setPointerConfig(initialPointerIndex, item, x, y);
1854
+ setPointerConfig(initialPointerIndex, item, x, y, y2, y3, y4, y5);
1846
1855
  }, initialPointerAppearDelay);
1847
1856
  } else {
1848
- setPointerConfig(initialPointerIndex, item, x, y);
1857
+ setPointerConfig(initialPointerIndex, item, x, y, y2, y3, y4, y5);
1849
1858
  }
1850
1859
  }
1851
1860
  }, []);
1852
1861
 
1853
- const setPointerConfig = (initialPointerIndex, item, x, y) => {
1862
+ const setPointerConfig = (
1863
+ initialPointerIndex,
1864
+ item,
1865
+ x,
1866
+ y,
1867
+ y2,
1868
+ y3,
1869
+ y4,
1870
+ y5,
1871
+ ) => {
1854
1872
  setPointerIndex(initialPointerIndex);
1855
1873
  setPointerItem(item);
1856
1874
  setPointerX(x);
1857
1875
  setPointerY(y);
1876
+ setPointerY2(y2);
1877
+ setPointerY3(y3);
1878
+ setPointerY4(y4);
1879
+ setPointerY5(y5);
1858
1880
  };
1859
1881
 
1860
1882
  const renderLabel = (
@@ -2112,7 +2134,7 @@ export const LineChart = (props: LineChartPropsType) => {
2112
2134
  transform: [{scaleX: I18nManager.isRTL ? -1 : 1}],
2113
2135
  },
2114
2136
  ]}>
2115
- {customDataPoint()}
2137
+ {customDataPoint(item, index)}
2116
2138
  </View>
2117
2139
  ) : null}
2118
2140
  {dataPointsShape === 'rectangular' ? (
@@ -118,6 +118,7 @@ export const BarDefaults = {
118
118
  capThickness: 6,
119
119
  capColor: 'gray',
120
120
  capRadius: 0,
121
+ barBorderColor: 'gray',
121
122
 
122
123
  horizontal: false,
123
124
  rtl: false,
@@ -1,3 +1,4 @@
1
+ import {stackItemType} from '../BarChart/types';
1
2
  import {
2
3
  RANGE_ENTER,
3
4
  RANGE_EXIT,
@@ -1026,7 +1027,7 @@ export const getXForLineInBar = (
1026
1027
  yAxisLabelWidth +
1027
1028
  firstBarWidth / 2 +
1028
1029
  lineConfig.initialSpacing +
1029
- (currentBarWidth + spacing) * index +
1030
+ (currentBarWidth + (lineConfig.spacing ?? spacing)) * index +
1030
1031
  lineConfig.shiftX -
1031
1032
  lineConfig.dataPointsWidth / 2 -
1032
1033
  32;
@@ -1056,6 +1057,7 @@ export const getLineConfigForBarChart = lineConfig => {
1056
1057
  return {
1057
1058
  initialSpacing:
1058
1059
  lineConfig.initialSpacing ?? defaultLineConfig.initialSpacing,
1060
+ spacing: lineConfig.initialSpacing,
1059
1061
  curved: lineConfig.curved || defaultLineConfig.curved,
1060
1062
  curvature: lineConfig.curvature ?? defaultLineConfig.curvature,
1061
1063
  curveType: lineConfig.curveType ?? defaultLineConfig.curveType,
@@ -1116,3 +1118,33 @@ export const getLineConfigForBarChart = lineConfig => {
1116
1118
  isSecondary: lineConfig.isSecondary ?? defaultLineConfig.isSecondary,
1117
1119
  };
1118
1120
  };
1121
+
1122
+ export const isValueSumZeroForStackBottom = (
1123
+ item: stackItemType,
1124
+ index: number,
1125
+ ) => {
1126
+ const {stacks} = item;
1127
+ let isValueSumZero = true;
1128
+ for (let i = 0; i < index; i++) {
1129
+ if (stacks[i].value) {
1130
+ isValueSumZero = false;
1131
+ break;
1132
+ }
1133
+ }
1134
+ return isValueSumZero;
1135
+ };
1136
+
1137
+ export const isValueSumZeroForStackTop = (
1138
+ item: stackItemType,
1139
+ index: number,
1140
+ ) => {
1141
+ const {stacks} = item;
1142
+ let isValueSumZero = true;
1143
+ for (let i = stacks.length - 1; i > index; i--) {
1144
+ if (stacks[i].value) {
1145
+ isValueSumZero = false;
1146
+ break;
1147
+ }
1148
+ }
1149
+ return isValueSumZero;
1150
+ };
@@ -1,224 +0,0 @@
1
- import React from 'react';
2
- import {View, StyleSheet, ColorValue, Text} from 'react-native';
3
- import LinearGradient from 'react-native-linear-gradient';
4
- import Svg, {Defs, Rect} from 'react-native-svg';
5
- import {styles} from './styles';
6
-
7
- type PropTypes = {
8
- style: any;
9
- width: number;
10
- sideWidth: number;
11
- height: number;
12
- color: ColorValue;
13
- showGradient: boolean;
14
- gradientColor: any;
15
- frontColor: ColorValue;
16
- sideColor: ColorValue;
17
- topColor: ColorValue;
18
- opacity: number;
19
- side: String;
20
- horizontal: boolean;
21
- intactTopLabel: boolean;
22
- showValuesAsTopLabel: boolean;
23
- topLabelContainerStyle?: any;
24
- topLabelTextStyle?: any;
25
- value: number;
26
- barBackgroundPattern?: Function;
27
- patternId?: String;
28
- barStyle?: object;
29
- item?: any;
30
- };
31
-
32
- type TriangleProps = {
33
- color: ColorValue;
34
- width: number;
35
- style: any;
36
- };
37
-
38
- const TriangleCorner = (props: TriangleProps) => {
39
- return (
40
- <View
41
- style={[
42
- aStyles.triangleCorner,
43
- props.style,
44
- {
45
- borderRightWidth: props.width / 2,
46
- borderTopWidth: props.width / 2,
47
- borderTopColor: props.color,
48
- },
49
- ]}
50
- />
51
- );
52
- };
53
-
54
- const aStyles = StyleSheet.create({
55
- triangleCorner: {
56
- width: 0,
57
- height: 0,
58
- backgroundColor: 'transparent',
59
- borderStyle: 'solid',
60
- borderRightColor: 'transparent',
61
- transform: [{rotate: '90deg'}],
62
- },
63
- });
64
-
65
- const ThreeDBar = (props: PropTypes) => {
66
- const {
67
- width,
68
- sideWidth,
69
- height,
70
- value,
71
- barBackgroundPattern,
72
- patternId,
73
- barStyle,
74
- item,
75
- } = props;
76
-
77
- const showGradient = props.showGradient || false;
78
- const gradientColor = props.gradientColor || 'white';
79
-
80
- const frontColor = props.frontColor || '#fe2233';
81
- const sideColor = props.sideColor || '#cc2233';
82
- const topColor = props.topColor || '#ff4433';
83
-
84
- const {
85
- intactTopLabel,
86
- showValuesAsTopLabel,
87
- topLabelContainerStyle,
88
- topLabelTextStyle,
89
- } = props;
90
-
91
- const opacity = props.opacity || 1;
92
- return (
93
- <View style={styles.container}>
94
- {props.height ? (
95
- <View
96
- style={[
97
- styles.row,
98
- props.side === 'right' && {transform: [{rotateY: '180deg'}]},
99
- ]}>
100
- {/******************* Top View *****************/}
101
-
102
- <View style={{position: 'absolute', top: sideWidth / -2}}>
103
- <TriangleCorner
104
- color={topColor}
105
- width={sideWidth}
106
- style={{transform: [{rotate: '90deg'}], opacity: opacity}}
107
- />
108
- </View>
109
- <View style={{position: 'absolute', top: sideWidth / -2}}>
110
- <View
111
- style={{
112
- width: width,
113
- height: width * 0.4,
114
- // left: width / -8,
115
- backgroundColor: topColor,
116
- opacity: opacity,
117
- }}
118
- />
119
- </View>
120
- <View
121
- style={{position: 'absolute', top: sideWidth / -2, left: width}}>
122
- <TriangleCorner
123
- color={topColor}
124
- width={sideWidth}
125
- style={{transform: [{rotate: '-90deg'}], opacity: opacity}}
126
- />
127
- </View>
128
-
129
- {/*******************************************************************/}
130
-
131
- <View style={{marginTop: sideWidth / -2}}>
132
- <TriangleCorner
133
- color={sideColor}
134
- width={sideWidth}
135
- style={{transform: [{rotate: '-90deg'}], opacity: opacity}}
136
- />
137
- <View
138
- style={{
139
- width: sideWidth / 2,
140
- height: height - sideWidth / 2,
141
- backgroundColor: sideColor,
142
- opacity: opacity,
143
- }}
144
- />
145
- <TriangleCorner
146
- color={sideColor}
147
- width={sideWidth}
148
- style={{transform: [{rotate: '90deg'}], opacity: opacity}}
149
- />
150
- </View>
151
-
152
- <View
153
- style={[
154
- {
155
- width: width,
156
- height: height,
157
- backgroundColor: frontColor,
158
- borderLeftWidth: StyleSheet.hairlineWidth,
159
- borderTopWidth: StyleSheet.hairlineWidth,
160
- borderColor: 'white',
161
- opacity: opacity,
162
- },
163
- item.barStyle || barStyle,
164
- ]}>
165
- {showGradient && (
166
- <LinearGradient
167
- style={{position: 'absolute', width: '100%', height: '100%'}}
168
- start={{x: 0, y: 0}}
169
- end={{x: 1, y: 1}}
170
- colors={[gradientColor, frontColor]}
171
- />
172
- )}
173
- {barBackgroundPattern && (
174
- <Svg>
175
- <Defs>{barBackgroundPattern()}</Defs>
176
- <Rect
177
- stroke="transparent"
178
- x="1"
179
- y="1"
180
- width={width || 30}
181
- height={height}
182
- fill={`url(#${patternId})`}
183
- />
184
- </Svg>
185
- )}
186
- </View>
187
- </View>
188
- ) : null}
189
-
190
- {/******************* Top Label *****************/}
191
-
192
- {(item.topLabelComponent || showValuesAsTopLabel) && (
193
- <View
194
- style={[
195
- {
196
- position: 'absolute',
197
- top: value < 0 ? width * -1 : width * -2,
198
- height: (width * 3) / 2,
199
- width: width,
200
- justifyContent: 'flex-end',
201
- alignItems: 'center',
202
- },
203
- value < 0 && {transform: [{rotate: '180deg'}]},
204
- props.horizontal &&
205
- !intactTopLabel && {transform: [{rotate: '270deg'}]},
206
- props.side === 'right'
207
- ? {right: (-1 * width) / 4}
208
- : {left: (-1 * width) / 4},
209
- topLabelContainerStyle ?? item.topLabelContainerStyle,
210
- ]}>
211
- {showValuesAsTopLabel ? (
212
- <Text style={topLabelTextStyle}>{item.value}</Text>
213
- ) : (
214
- item.topLabelComponent?.()
215
- )}
216
- </View>
217
- )}
218
-
219
- {/*******************************************************************/}
220
- </View>
221
- );
222
- };
223
-
224
- export default ThreeDBar;
@@ -1,14 +0,0 @@
1
- import {StyleSheet} from 'react-native';
2
-
3
- export const styles = StyleSheet.create({
4
- container: {
5
- flex: 1,
6
- // width: '100%',
7
- // height: '100%',
8
- justifyContent: 'center',
9
- alignItems: 'center',
10
- },
11
- row: {
12
- flexDirection: 'row',
13
- },
14
- });