Search code examples
javascriptreact-nativereact-native-svgreact-native-svg-charts

How to onPress and other Color in barChart on react-native-svg-charts


I want to put an event where I click on the chart and express the color of the chart differently. To do so, chart data was processed, but the processed option did not work normally.

And after processing the data, additional SVG cannot be inserted into the chart. An error has occurred. So I've annotated it.

    const getFill = (index: number) => {
        if (index > 30) return "purple";
        if (index > 20) return "blue";
        if (index > 10) return "green";
        return "red";
    };
    const pieData = dataList.map((value, index) => ({
        value,
        svg: {
            fill: getFill(index)
        },
        key: `bar-${index}`
    }));

    console.log(pieData);

    return (
        ...
                          <BarChart
                            style={{ flex: 9, width: apx(750) }}
                            spacingInner={0.2}
                            data={pieData}
                            gridMin={Y_AXIS_MIN}
                            gridMax={Y_AXIS_MAX}
                            // svg={{ fill: "red" }}
                            animate
                        >
                            {/* {pieData.map((_, i) => (
                                <Tooltip index={i} />
                            ))} */}
                        </BarChart>
        ...
    );

Console.log

[{"key": "bar-0", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-1", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-2", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-3", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-4", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-5", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-6", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-7", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-8", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-9", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-10", "svg": {"fill": "red"}, "value": 4000}, {"key": "bar-11", "svg": {"fill": "green"}, "value": 4000}, {"key": "bar-12", "svg": {"fill": "green"}, "value": 4000}, {"key": "bar-13", "svg": {"fill": "green"}, "value": 4000}]

Not Show Chart Screenshot

  • package.json
{
 "react-native-svg": "^12.1.0",
 "react-native-svg-charts": "^5.4.0",
}

enter image description here

How can you solve this problem?


Solution

  • I identified the problem while looking at the library source code.

        calcAreas(x, y) {
            const { horizontal, data, yAccessor } = this.props
    
            const _data = data.map((obj) => {
                const { svg = {} } = obj
                return {
                    ...obj,
                    data: obj.data.map((item) => {
                        if (typeof item === 'number') {
                            return {
                                value: item,
                                svg,
                            }
                        }
    
                        return {
                            ...item,
                            svg: {
                                ...svg,
                                ...item.svg,
                            },
                            value: yAccessor({ item }), // 
                        }
                    }),
                }
            })
    

    This part was the problem. I was adding a value, but it was being newly defined.

    So I added the yAccessor option.

        const pieData = dataList.map((value, index) => ({
            value,
            svg: {
                fill: getFill(index),
                onPress: () => console.log(`${value}-${index}`)
            },
            key: `bar-${index}`
        }));
    
                            <BarChart
                                style={{ flex: 9, width: apx(750) }}
                                spacingInner={0.2}
                                data={pieData}
                                gridMin={Y_AXIS_MIN}
                                gridMax={Y_AXIS_MAX}
                                yAccessor={({ item }) => item.value}
                                animate
                            >
                                {pieData.map((_, i) => (
                                    <Tooltip index={i} />
                                ))}
                            </BarChart>
    

    it very good work