简体   繁体   English

如何从 react-native-svg-charts 沿 PieChart 组件的圆周呈现标签?

[英]How to render labels along the circumference of PieChart component from react-native-svg-charts?

Here's a snapshot of my code:这是我的代码的快照:

  const data = filteredKeys.map((key, index) => {
    return {
      key,
      value: filteredValues[index],
      svg: { fill: colors[index] },
      arc: {
        outerRadius: 70 + filteredValues[index] + '%',
        padAngle: label === key ? 0.1 : 0,
      },
      onPress: () =>
        setSelectedSlice({ label: key, value: filteredValues[index] }),
    };
  });

  const Labels = ({ slices, height, width }) => {
    return slices.map((slice, index) => {
      console.log(slice);
      const { labelCentroid, pieCentroid, data } = slice;
      return (
        <Text
          key={index}
          x={labelCentroid[0]}
          y={labelCentroid[1]}
          fill={'#000'}
          textAnchor={'middle'}
          alignmentBaseline={'center'}
          fontSize={14}
          stroke={'black'}
          strokeWidth={0.2}
        >
          {data.key}
        </Text>
      );
    });
  };

  return (
    <View style={styles.container}>
      <PieChart
        style={{ height: 300 }}
        outerRadius={'100%'}
        innerRadius={'10%'}
        data={data}
        labelRadius={'85%'}
      >
        <Labels />
      </PieChart>
    </View>
  );

This is the result:这是结果:

在此处输入图像描述

I want to labels to align like this:我想像这样对齐标签:

在此处输入图像描述

The labels look very inconsistent on different pie charts, that's why I want to render the labels along the curve of their respective arcs (center of the arc is prefered).标签在不同的饼图上看起来非常不一致,这就是为什么我想沿着各自弧线的曲线渲染标签(首选弧线的中心)。

I have tried TextPath and TSpan from react-native-svg, but couldn't figure out how to draw the TextPath when it is child of the component along which the path is to be drawn.我已经尝试过 react-native-svg 中的 TextPath 和 TSpan,但是当它是要绘制路径的组件的子组件时,无法弄清楚如何绘制 TextPath。

Hate to resurrect this but since I was wanting to do the same thing I figured I would show the math behind it.讨厌复活这个,但因为我想做同样的事情,我想我会展示它背后的数学。

Given we know the center of the circle is 0,0 and we have the x,y of the labels current position we can calculate the adjacent angle which is what your looking for.鉴于我们知道圆的中心是 0,0 并且我们有当前标签 position 的 x,y,我们可以计算出您要查找的相邻角度。 Heres a simple diagram to illustrate.这里有一个简单的图表来说明。

tx,ty = labelCentroid
R = atan2(ty, tx)

在此处输入图像描述

Given that information the example code below gives the desired results.鉴于这些信息,下面的示例代码给出了预期的结果。


function TestPieChart() {
  const Labels: any = ({slices, height, width}) => {
    return slices.map((slice, index) => {
      const {labelCentroid, data} = slice;
      const labelAngle =
        Math.atan2(labelCentroid[1], labelCentroid[0]) + Math.PI / 2;
      return (
        <G key={index}>
          <Text
            transform={
              `translate(${labelCentroid[0]}, ${labelCentroid[1]})` +
              `rotate(${(360 * labelAngle) / (2 * Math.PI)})`
            }
            fill={'#000000'}
            textAnchor={'middle'}
            alignmentBaseline={'center'}
            fontSize={14}
            stroke={'black'}
            strokeWidth={0.2}
          >
            {data.key}
          </Text>
        </G>
      );
    });
  };

  return (
    <View style={{backgroundColor: 'white'}}>
      <PieChart
        data={[
          {key: 'arms', value: 20, svg: {fill: '#FAA'}},
          {key: 'legs', value: 20, svg: {fill: '#1bb234'}},
          {key: 'chest', value: 50, svg: {fill: '#8a5a00'}},
          {key: 'foot', value: 30, svg: {fill: '#00ffbb'}},
          {key: 'finger', value: 20, svg: {fill: '#223193'}},
        ]}
        style={{height: 270, marginTop: 0, padding: 10}}
        padAngle={0}
        outerRadius={'90%'}
        innerRadius={'80%'}
        labelRadius={'100%'}
      >
        <Labels></Labels>
      </PieChart>
    </View>
  );
}

在此处输入图像描述

Can you show a full code?你能显示一个完整的代码吗? I try to label each piece of pie and add polylines to each of them.我尝试 label 每个饼图并为每个饼图添加折线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM