Search code examples
react-nativesvgchart.jsreact-chartjsreact-native-svg

Make a chart clickable when placed under another SVG <View>


I am having trouble working with some SVG in React Native. I have a chart that is clickable and works well, I then needed to place another SVG on top of the chart in order to draw a line that would represent a limit score value. The problem that I am now facing is that I cannot click on the chart anymore since the view of the SVG is placed on top of it. I made the background color of the SVG to be transparent so that I can at least see the chart behind it but, I do not know how to make it clickable again.

Is there any work around where I can maybe make the chart clickable trough a transparent view that is place on top?

It might be a stupid question but I am pretty new to both react and JS in general, so I could really use any type of help. :)

Here is the picture of the chart:

Polar Chart and Svg circle

And here the same Svg with a non-transparent background that, as you can see, covers almost the hole chart.

Svg covering the chart

Here's the Svg code:

export class NutritionChartSvg extends Component {
 render() {
  return (
  <View style={styles.container} >

      <Svg height={height * 0.5} width={width * 0.5} viewBox="0 0 100 100">
        <Svg.Circle
          id="circle"
          cx="50"
          cy="13"
          r="40"
          stroke="gray"
          strokeWidth="0.6"
          fill="none"
        />
      <Text fill="black" fontSize="8" dy="-2">
        <TextPath href="#circle" startOffset='181'>
        100
        </TextPath>
      </Text>

      </Svg>
    </View>
  );
 }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   alignContent: 'center',
   justifyContent: 'center' ,
   position: 'absolute',
   left: '25%',
   height: 'auto',
   width: 'auto',
  },
 });'

This is the chart form chartjs:

export const NutritionChart = (props) => {
 return (
    <Chart
      chartConfiguration={
      {
        type: 'polarArea',
        data: {
          labels: ['Fiber', 'Protein', 'Healthy Oil', 'Good Energy', 'Immune 
                   Defense'],
          datasets: [
            {
              label: '# of Votes',
              data: [
                50,
                140,
                90,
                120,
                100,
              ],
              backgroundColor: backgroundColor,
              borderColor: borderColor,
              borderWidth: datasets.border,
              hoverBackgroundColor: hoverBackgroundColor,
            },
          ],
        },
        options: {
          layout: {
           padding: {
               top: options.layout.padding.top,
               bottom: options.layout.padding.bottom,
               }
           },
          legend: {
            display: false,
            fullWidth: false,
            labels: {
              fontSize: options.legend.labels.fontSize,
              boxWidth: options.legend.labels.boxWidth,
              padding: options.legend.labels.padding,
            }
          },
          scale: {
            display: false,
            ticks: {
              min:0,
              max:200,
            }
          },
          responsive: true,
          maintainAspectRatio: false,
        },
      }
      }
      defaultFontSize={10}
    />
  );
};

and they are together in a view :

  <View style={styles.nutritionChart} key={3}>
        <NutritionChart/>
        <NutritionChartSvg/>
   </View>

Solution

  • Either:

    1. Move the limit line into the chart SVG, instead of laying it separately on top, or
    2. Set pointer-events: none on the top SVG. This will make clicks pass right through it.