From aa7403eed06bf2edbecd4ce4b7ed03e72a0f0be2 Mon Sep 17 00:00:00 2001 From: abhinandan-kushwaha Date: Wed, 9 Mar 2022 02:43:14 +0530 Subject: [PATCH] Added feature for Line chart with breaks, and separate data arrays for combined charts --- App.js | 24 +++- README.md | 4 + docs/BarChart/BarChartProps.md | 6 +- docs/LineChart/LineChartProps.md | 9 ++ package.json | 2 +- src/BarChart/index.tsx | 67 ++++++--- src/LineChart/index.tsx | 226 +++++++++++++++++++++---------- src/todos.md | 8 ++ 8 files changed, 246 insertions(+), 100 deletions(-) create mode 100644 src/todos.md diff --git a/App.js b/App.js index b2f30bc..ffed2c7 100644 --- a/App.js +++ b/App.js @@ -581,7 +581,7 @@ const App = () => { }, ]; - const [dtt,setDtt] = useState([ + const [dtt, setDtt] = useState([ {value: 110}, {value: 130}, {value: 120}, @@ -599,6 +599,8 @@ const App = () => { {value: 40, label: 'Thu'}, {value: -16, label: 'Wed'}, {value: 40, label: 'Thu'}, + {value: -16, label: 'Wed'}, + {value: 40, label: 'Thu'}, ]; return ( @@ -608,7 +610,20 @@ const App = () => { // marginLeft: 46, marginLeft: 20, }}> - + + {/* */} {/* { // showTextBackground={true} /> */} {dtt[1].value+=20;setDtt([...dtt])}}> + onPress={() => { + dtt[1].value += 20; + setDtt([...dtt]); + }}> Press me {/* `maxValue = noOfSections * stepValue;`
is followed. [See this](https://github.com/Abhinandan-Kushwaha/react-native-gifted-charts/issues/71) | +## To-dos + +[To do list](./src/todos.md) + ## License MIT diff --git a/docs/BarChart/BarChartProps.md b/docs/BarChart/BarChartProps.md index 469bc35..c692d3a 100644 --- a/docs/BarChart/BarChartProps.md +++ b/docs/BarChart/BarChartProps.md @@ -20,10 +20,12 @@ | disableScroll | Boolean | To disable horizontal scroll | false | | showScrollIndicator | Boolean | To show horizontal scroll indicator | false | | showLine | Boolean | To show a Line chart over the Bar chart with the same data | false | +| lineData | Array of items | The data object for the line chart (use only when showLine is true) | data | | lineConfig | lineConfigType | Properties of the Line chart shown over the Bar chart (lineConfigType) is described below | defaultLineConfig | | autoShiftLabels | Boolean | When set to true, automatically shifts the X axis labels for negative values | false | | scrollToEnd | Boolean | When set to true, the chart automatically scrolls to the rightmost bar | false | | scrollAnimation | Boolean | When set to true, scroll animation is visible when the chart automatically scrolls to the rightmost bar | true | +| initialSpacing | number | distance of the first bar from the Y axis | 40 | --- @@ -51,6 +53,7 @@ The properties of this line chart can be controlled using the `lineConfig` prop | Property | Type | Description | Default value | | ---------------- | ---------- | ----------------------------------------------------------------- | ------------- | +| initialSpacing | number | distance of the first data point from the Y axis | initialSpacing for the Bar Chart | | curved | Boolean | To show curved line joining the data points | false | | isAnimated | Boolean | To show animates Line Chart | false | | delay | number | Delay (in milliseconds) before starting the animation of the line | 0 | @@ -67,6 +70,8 @@ The properties of this line chart can be controlled using the `lineConfig` prop | textShiftX | number | To shift the dataPointText text horizontally | 0 | | textShiftY | number | To shift the dataPointText text vertically | 0 | | shiftY | number | To shift the Lift the Line chart up or down by the given quantity | 0 | +| startIndex | number | Start index for data line (used to display data lines having breaks) | 0 | +| endIndex | number | End index for data line (used to display data lines having breaks) | lineData.length -1 | --- @@ -84,7 +89,6 @@ The properties of this line chart can be controlled using the `lineConfig` prop | topColor | ColorValue | Color of the top view of the bar, only for 3 D | | showGradient | Boolean | Prop to enable linear gradient for the bar color, defaults to false | | gradientColor | ColorValue | Along with frontColor, this prop constitutes the 2 colors for gradient | -| initialSpacing | number | distance of the first bar from the Y axis | | label | string | Label text appearing below the bar (under the X axis) | | labelWidth | number | Width of the Label text appearing below the bar (under the X axis) | | labelTextStyle | object | Style object for the label text appearing below the bar | diff --git a/docs/LineChart/LineChartProps.md b/docs/LineChart/LineChartProps.md index 6697404..59aab4d 100644 --- a/docs/LineChart/LineChartProps.md +++ b/docs/LineChart/LineChartProps.md @@ -24,6 +24,7 @@ | onDataChangeAnimationDuration | number | Duration (milliseconds) in which the transition animation takes place on a change in data | 400 | | scrollToEnd | Boolean | When set to true, the chart automatically scrolls to the rightmost data point | false | | scrollAnimation | Boolean | When set to true, scroll animation is visible when the chart automatically scrolls to the rightmost data point | true | +| initialSpacing | number | distance of the first data point from the Y axis | 40 | --- @@ -160,6 +161,14 @@ type referenceConfigType = { | thickness1 | number | Thickness of the lines joining the first set of data points | thickness (from props) | | thickness2 | number | Thickness of the lines joining the second set of data points | thickness (from props) | | thickness3 | number | Thickness of the lines joining the third set of data points | thickness (from props) | +| startIndex | number | Start index for data line (used to display data lines having breaks) | 0 | +| startIndex1 | number | Start index for data line 1 (used to display data lines having breaks) | 0 | +| startIndex2 | number | Start index for data line 2 (used to display data lines having breaks) | 0 | +| startIndex3 | number | Start index for data line 3 (used to display data lines having breaks) | 0 | +| endIndex | number | End index for data line (used to display data lines having breaks) | data.length -1 | +| endIndex1 | number | End index for data line 1 (used to display data lines having breaks) | data.length -1 | +| endIndex2 | number | End index for data line 2 (used to display data lines having breaks) | data2.length -1 | +| endIndex3 | number | End index for data line 3 (used to display data lines having breaks) | data3.length -1 | | curved | Boolean | To show curved line joining the data points | false | --- diff --git a/package.json b/package.json index fa0358d..4ef5180 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-gifted-charts", - "version": "1.0.6", + "version": "1.0.7", "description": "The most complete library for Bar, Line, Area, Pie and Donut charts in React Native. Allows 2D, 3D, gradient, animations and live data updates.", "main": "src/index.tsx", "files": [ diff --git a/src/BarChart/index.tsx b/src/BarChart/index.tsx index 43e90dc..dac9dfb 100644 --- a/src/BarChart/index.tsx +++ b/src/BarChart/index.tsx @@ -52,6 +52,7 @@ type PropTypes = { barWidth?: number; sideWidth?: number; showLine?: Boolean; + lineData?: any; lineConfig?: lineConfigType; cappedBars?: Boolean; @@ -124,6 +125,7 @@ type PropTypes = { labelsExtraHeight?: number; }; type lineConfigType = { + initialSpacing?: number; curved?: Boolean; isAnimated?: Boolean; delay?: number; @@ -140,6 +142,8 @@ type lineConfigType = { textShiftX?: number; textShiftY?: number; shiftY?: number; + startIndex?: number; + endIndex?: number; }; type referenceConfigType = { thickness: number; @@ -175,7 +179,12 @@ export const BarChart = (props: PropTypes) => { const scrollRef = useRef(); const [points, setPoints] = useState(''); const showLine = props.showLine || false; + const initialSpacing = + props.initialSpacing === 0 ? 0 : props.initialSpacing || 40; + const data = useMemo(() => props.data || [], [props.data]); + const lineData = props.lineData || data; const defaultLineConfig = { + initialSpacing: initialSpacing, curved: false, isAnimated: false, thickness: 1, @@ -192,9 +201,16 @@ export const BarChart = (props: PropTypes) => { textShiftY: 0, shiftY: 0, delay: 0, + startIndex: 0, + endIndex: lineData.length - 1, }; const lineConfig = props.lineConfig ? { + initialSpacing: + props.lineConfig.initialSpacing === 0 + ? 0 + : props.lineConfig.initialSpacing || + defaultLineConfig.initialSpacing, curved: props.lineConfig.curved || defaultLineConfig.curved, isAnimated: props.lineConfig.isAnimated || defaultLineConfig.isAnimated, thickness: props.lineConfig.thickness || defaultLineConfig.thickness, @@ -220,6 +236,11 @@ export const BarChart = (props: PropTypes) => { textShiftY: props.lineConfig.textShiftY || defaultLineConfig.textShiftY, shiftY: props.lineConfig.shiftY || defaultLineConfig.shiftY, delay: props.lineConfig.delay || defaultLineConfig.delay, + startIndex: props.lineConfig.startIndex || defaultLineConfig.startIndex, + endIndex: + props.lineConfig.endIndex === 0 + ? 0 + : props.lineConfig.endIndex || defaultLineConfig.endIndex, } : defaultLineConfig; const containerHeight = props.height || 200; @@ -227,7 +248,6 @@ export const BarChart = (props: PropTypes) => { const horizSections = [{value: '0'}]; const horizSectionsBelow = []; const stepHeight = props.stepHeight || containerHeight / noOfSections; - const data = useMemo(() => props.data || [], [props.data]); const spacing = props.spacing === 0 ? 0 : props.spacing ? props.spacing : 20; const labelWidth = props.labelWidth || 0; const scrollToEnd = props.scrollToEnd || false; @@ -295,8 +315,6 @@ export const BarChart = (props: PropTypes) => { props.noOfSectionsBelowXAxis || -minValue / stepValue; const disableScroll = props.disableScroll || false; const showScrollIndicator = props.showScrollIndicator || false; - const initialSpacing = - props.initialSpacing === 0 ? 0 : props.initialSpacing || 40; // const oldData = props.oldData || []; const side = props.side || ''; const rotateLabel = props.rotateLabel || false; @@ -395,39 +413,41 @@ export const BarChart = (props: PropTypes) => { if (showLine) { let pp = ''; if (!lineConfig.curved) { - for (let i = 0; i < data.length; i++) { + for (let i = 0; i < lineData.length; i++) { + if (i < lineConfig.startIndex || i > lineConfig.endIndex) continue; const currentBarWidth = (data && data[i] && data[i].barWidth) || props.barWidth || 30; pp += 'L' + (yAxisLabelWidth + + lineConfig.initialSpacing + 6 - (initialSpacing - currentBarWidth / 2) - lineConfig.dataPointsWidth / 2 + (currentBarWidth + spacing) * i) + ' ' + (containerHeight - - lineConfig.shiftY + - 10 - - (data[i].value * containerHeight) / maxValue) + + lineConfig.shiftY - + (lineData[i].value * containerHeight) / maxValue) + ' '; } setPoints(pp.replace('L', 'M')); } else { let p1Array = []; - for (let i = 0; i < data.length; i++) { + for (let i = 0; i < lineData.length; i++) { + if (i < lineConfig.startIndex || i > lineConfig.endIndex) continue; const currentBarWidth = (data && data[i] && data[i].barWidth) || props.barWidth || 30; p1Array.push([ yAxisLabelWidth + + lineConfig.initialSpacing + 6 - (initialSpacing - currentBarWidth / 2) - lineConfig.dataPointsWidth / 2 + (currentBarWidth + spacing) * i, containerHeight - - lineConfig.shiftY + - 10 - - (data[i].value * containerHeight) / maxValue, + lineConfig.shiftY - + (lineData[i].value * containerHeight) / maxValue, ]); let xx = svgPath(p1Array, bezierCommand); setPoints(xx); @@ -443,14 +463,18 @@ export const BarChart = (props: PropTypes) => { animationDuration, containerHeight, data, + lineData, decreaseWidth, initialSpacing, labelsAppear, + lineConfig.initialSpacing, lineConfig.curved, lineConfig.dataPointsWidth, lineConfig.shiftY, lineConfig.isAnimated, lineConfig.delay, + lineConfig.startIndex, + lineConfig.endIndex, maxValue, // moveBar, props.barWidth, @@ -849,7 +873,10 @@ export const BarChart = (props: PropTypes) => { }; const renderDataPoints = () => { - return data.map((item: any, index: number) => { + return lineData.map((item: any, index: number) => { + if (index < lineConfig.startIndex || index > lineConfig.endIndex){ + return null; + } // console.log('comes in'); const currentBarWidth = item.barWidth || props.barWidth || 30; if (lineConfig.dataPointsShape === 'rectangular') { @@ -858,6 +885,7 @@ export const BarChart = (props: PropTypes) => { { y={ containerHeight - lineConfig.shiftY - - lineConfig.dataPointsHeight / 2 + - 10 - + lineConfig.dataPointsHeight / 2 - (item.value * containerHeight) / maxValue } width={lineConfig.dataPointsWidth} @@ -880,6 +907,7 @@ export const BarChart = (props: PropTypes) => { fontSize={item.textFontSize || lineConfig.textFontSize} x={ yAxisLabelWidth + + lineConfig.initialSpacing + 6 - (initialSpacing - currentBarWidth / 2) - lineConfig.dataPointsWidth + @@ -889,8 +917,7 @@ export const BarChart = (props: PropTypes) => { y={ containerHeight - lineConfig.shiftY - - lineConfig.dataPointsHeight / 2 + - 10 - + lineConfig.dataPointsHeight / 2 - (item.value * containerHeight) / maxValue + (item.textShiftY || lineConfig.textShiftY || 0) }> @@ -905,6 +932,7 @@ export const BarChart = (props: PropTypes) => { { } cy={ containerHeight - - lineConfig.shiftY + - 10 - + lineConfig.shiftY - (item.value * containerHeight) / maxValue } r={lineConfig.dataPointsRadius} @@ -925,6 +952,7 @@ export const BarChart = (props: PropTypes) => { fontSize={item.textFontSize || lineConfig.textFontSize} x={ yAxisLabelWidth + + lineConfig.initialSpacing + 6 - (initialSpacing - currentBarWidth / 2) - lineConfig.dataPointsWidth + @@ -934,8 +962,7 @@ export const BarChart = (props: PropTypes) => { y={ containerHeight - lineConfig.shiftY - - lineConfig.dataPointsHeight / 2 + - 10 - + lineConfig.dataPointsHeight / 2 - (item.value * containerHeight) / maxValue + (item.textShiftY || lineConfig.textShiftY || 0) }> diff --git a/src/LineChart/index.tsx b/src/LineChart/index.tsx index 6fdb72b..0f90eef 100644 --- a/src/LineChart/index.tsx +++ b/src/LineChart/index.tsx @@ -104,6 +104,15 @@ type propTypes = { yAxisIndicesColor?: ColorValue; yAxisSide?: string; + startIndex?: number; + startIndex1?: number; + startIndex2?: number; + startIndex3?: number; + endIndex?: number; + endIndex1?: number; + endIndex2?: number; + endIndex3?: number; + color?: string; color1?: string; color2?: string; @@ -282,6 +291,28 @@ export const LineChart = (props: propTypes) => { const yAxisLabelSuffix = props.yAxisLabelSuffix || ''; const yAxisSide = props.yAxisSide || 'left'; + const startIndex1 = + props.startIndex1 === 0 ? 0 : props.startIndex1 || props.startIndex || 0; + + let endIndex1; + if (props.endIndex1 === undefined || props.endIndex1 === null) { + if (props.endIndex === undefined || props.endIndex === null) { + endIndex1 = data.length - 1; + } else { + endIndex1 = props.endIndex; + } + } else { + endIndex1 = props.endIndex1; + } + + const startIndex2 = props.startIndex2 || 0; + const endIndex2 = + props.endIndex2 === 0 ? 0 : props.endIndex2 || data2.length - 1; + + const startIndex3 = props.startIndex3 || 0; + const endIndex3 = + props.endIndex3 === 0 ? 0 : props.endIndex3 || data3.length - 1; + if (!initialData) { initialData = [...data]; animations = initialData.map(item => new Animated.Value(item.value)); @@ -522,7 +553,7 @@ export const LineChart = (props: propTypes) => { pp3 = ''; if (!props.curved) { for (let i = 0; i < data.length; i++) { - if (!animateOnDataChange) { + if (i >= startIndex1 && i <= endIndex1 && !animateOnDataChange) { pp += 'L' + (initialSpacing - dataPointsWidth1 / 2 + spacing * i) + @@ -533,7 +564,7 @@ export const LineChart = (props: propTypes) => { ' '; setPoints(pp.replace('L', 'M')); } - if (data2.length) { + if (data2.length && i >= startIndex2 && i <= endIndex2) { pp2 += 'L' + (initialSpacing - dataPointsWidth2 / 2 + spacing * i) + @@ -543,7 +574,7 @@ export const LineChart = (props: propTypes) => { (data2[i].value * containerHeight) / maxValue) + ' '; } - if (data3.length) { + if (data3.length && i >= startIndex3 && i <= endIndex3) { pp3 += 'L' + (initialSpacing - dataPointsWidth3 / 2 + spacing * i) + @@ -647,11 +678,13 @@ export const LineChart = (props: propTypes) => { p2Array = [], p3Array = []; for (let i = 0; i < data.length; i++) { - p1Array.push([ - initialSpacing - dataPointsWidth1 / 2 + spacing * i, - containerHeight + 10 - (data[i].value * containerHeight) / maxValue, - ]); - if (data2.length) { + if (i >= startIndex1 && i <= endIndex1) { + p1Array.push([ + initialSpacing - dataPointsWidth1 / 2 + spacing * i, + containerHeight + 10 - (data[i].value * containerHeight) / maxValue, + ]); + } + if (data2.length && i >= startIndex2 && i <= endIndex2) { p2Array.push([ initialSpacing - dataPointsWidth2 / 2 + spacing * i, containerHeight + @@ -659,7 +692,7 @@ export const LineChart = (props: propTypes) => { (data2[i].value * containerHeight) / maxValue, ]); } - if (data3.length) { + if (data3.length && i >= startIndex3 && i <= endIndex3) { p3Array.push([ initialSpacing - dataPointsWidth3 / 2 + spacing * i, containerHeight + @@ -790,6 +823,12 @@ export const LineChart = (props: propTypes) => { props.curved, spacing, xAxisThickness, + startIndex1, + endIndex1, + startIndex2, + endIndex2, + startIndex3, + endIndex3, ]); const horizSections = [{value: '0'}]; @@ -1309,8 +1348,11 @@ export const LineChart = (props: propTypes) => { dataPtsRadius, textColor, textFontSize, + startIndex, + endIndex, ) => { return dataForRender.map((item: itemType, index: number) => { + if (index < startIndex || index > endIndex) return null; if (item.hideDataPoint) { return null; } @@ -1575,6 +1617,16 @@ export const LineChart = (props: propTypes) => { endFillColor: string, startOpacity: number, endOpacity: number, + hideDataPoints: Boolean, + dataPointsShape, + dataPointsWidth, + dataPointsHeight, + dataPointsColor, + dataPointsRadius, + textColor, + textFontSize, + startIndex, + endIndex, ) => { return ( { {renderSpecificVerticalLines(data)} {renderSpecificVerticalLines(data2)} - {!hideDataPoints1 + {!hideDataPoints ? renderDataPoints( data, - dataPointsShape1, - dataPointsWidth1, - dataPointsHeight1, - dataPointsColor1, - dataPointsRadius1, - textColor1, - textFontSize1, - ) - : null} - {!hideDataPoints2 - ? renderDataPoints( - data2, - dataPointsShape2, - dataPointsWidth2, - dataPointsHeight2, - dataPointsColor2, - dataPointsRadius2, - textColor2, - textFontSize2, - ) - : null} - {!hideDataPoints3 - ? renderDataPoints( - data3, - dataPointsShape3, - dataPointsWidth3, - dataPointsHeight3, - dataPointsColor3, - dataPointsRadius3, - textColor3, - textFontSize3, + dataPointsShape, + dataPointsWidth, + dataPointsHeight, + dataPointsColor, + dataPointsRadius, + textColor, + textFontSize, + startIndex, + endIndex, ) : null} @@ -1680,6 +1710,16 @@ export const LineChart = (props: propTypes) => { endFillColor: string, startOpacity: number, endOpacity: number, + hideDataPoints: Boolean, + dataPointsShape, + dataPointsWidth, + dataPointsHeight, + dataPointsColor, + dataPointsRadius, + textColor, + textFontSize, + startIndex, + endIndex, ) => { // console.log('animatedWidth is-------->', animatedWidth); return ( @@ -1736,40 +1776,18 @@ export const LineChart = (props: propTypes) => { {renderSpecificVerticalLines(data2)} {renderSpecificVerticalLines(data3)} - {!hideDataPoints1 + {!hideDataPoints ? renderDataPoints( data, - dataPointsShape1, - dataPointsWidth1, - dataPointsHeight1, - dataPointsColor1, - dataPointsRadius1, - textColor1, - textFontSize1, - ) - : null} - {!hideDataPoints2 - ? renderDataPoints( - data2, - dataPointsShape2, - dataPointsWidth2, - dataPointsHeight2, - dataPointsColor2, - dataPointsRadius2, - textColor2, - textFontSize2, - ) - : null} - {!hideDataPoints3 - ? renderDataPoints( - data3, - dataPointsShape3, - dataPointsWidth3, - dataPointsHeight3, - dataPointsColor3, - dataPointsRadius3, - textColor3, - textFontSize3, + dataPointsShape, + dataPointsWidth, + dataPointsHeight, + dataPointsColor, + dataPointsRadius, + textColor, + textFontSize, + startIndex, + endIndex, ) : null} @@ -1777,8 +1795,6 @@ export const LineChart = (props: propTypes) => { ); }; - console.log('horizSectionsBelow -- >', horizSectionsBelow); - return ( { endFillColor1, startOpacity1, endOpacity1, + hideDataPoints1, + dataPointsShape1, + dataPointsWidth1, + dataPointsHeight1, + dataPointsColor1, + dataPointsRadius1, + textColor1, + textFontSize1, + startIndex1, + endIndex1, ) : renderLine( points, @@ -1880,6 +1906,16 @@ export const LineChart = (props: propTypes) => { endFillColor1, startOpacity1, endOpacity1, + hideDataPoints1, + dataPointsShape1, + dataPointsWidth1, + dataPointsHeight1, + dataPointsColor1, + dataPointsRadius1, + textColor1, + textFontSize1, + startIndex1, + endIndex1, )} {points2 ? isAnimated @@ -1893,6 +1929,16 @@ export const LineChart = (props: propTypes) => { endFillColor2, startOpacity2, endOpacity2, + hideDataPoints2, + dataPointsShape2, + dataPointsWidth2, + dataPointsHeight2, + dataPointsColor2, + dataPointsRadius2, + textColor2, + textFontSize2, + startIndex2, + endIndex2, ) : renderLine( points2, @@ -1903,6 +1949,16 @@ export const LineChart = (props: propTypes) => { endFillColor2, startOpacity2, endOpacity2, + hideDataPoints2, + dataPointsShape2, + dataPointsWidth2, + dataPointsHeight2, + dataPointsColor2, + dataPointsRadius2, + textColor2, + textFontSize2, + startIndex2, + endIndex2, ) : null} {points3 @@ -1917,6 +1973,16 @@ export const LineChart = (props: propTypes) => { endFillColor3, startOpacity3, endOpacity3, + hideDataPoints3, + dataPointsShape3, + dataPointsWidth3, + dataPointsHeight3, + dataPointsColor3, + dataPointsRadius3, + textColor3, + textFontSize3, + startIndex3, + endIndex3, ) : renderLine( points3, @@ -1927,6 +1993,16 @@ export const LineChart = (props: propTypes) => { endFillColor3, startOpacity3, endOpacity3, + hideDataPoints3, + dataPointsShape3, + dataPointsWidth3, + dataPointsHeight3, + dataPointsColor3, + dataPointsRadius3, + textColor3, + textFontSize3, + startIndex3, + endIndex3, ) : null} {data.map((item: itemType, index: number) => { diff --git a/src/todos.md b/src/todos.md new file mode 100644 index 0000000..23da12b --- /dev/null +++ b/src/todos.md @@ -0,0 +1,8 @@ +## To-dos in documentation- + +1. Prepare a doc for Bar chart with negative values +2. Prepare a doc for Line chart with negative values +3. Prepare a doc for Bar chart with y axis on right side +4. Prepare a doc for Line chart with y axis on right side +5. Prepare a doc for Bar chart combined with Line chart having a separate data for the Line chart +6. Prepare a doc for Line chart with breaks \ No newline at end of file