ReCharts: Donut Chart w/two labels in center
Asked Answered
R

3

11

I have a donut chart in which i need to add two stacked labels in center which I have done. What i can't figure out is how to add a little vertical space between. ReCharts renders both these lines as SVG The chart is in a responsive container so no hard coded values. I know how to get a single label in center but can't figure out how to get two separate ones there without writing a render method for the entire chart. Suggestions?

<ResponsiveContainer>
            <PieChart >
              <Tooltip/>
              <Legend
                verticalAlign="bottom"
                align="left"
                iconType="circle"
                payload={ getCustomLegendValues(tasks) } />
              <Pie
                data={tasks}
                nameKey="name"
                dataKey="value"
                innerRadius="60%"
                outerRadius="80%"
                startAngle={90}
                endAngle={-270}
                fill="#8884d8">
                {
                  tasks.map((entry, index) => <Cell fill={ entry.color }/>)
                }
                <Label width={30} position="center">
                  { `${totalTasks} ${tasksNameLabel}` }
                </Label>
              </Pie>
            </PieChart>
          </ResponsiveContainer>

enter image description here

enter image description here

Reverse answered 16/8, 2017 at 21:57 Comment(0)
L
6

You should use the content property of the Label component in order to create your own custom Label because both the children and the value property only accept string or numbers. With the content property you can pass a component as such:

<Label width={30} position="center"
  content={<CustomLabel value1={totalTasks} value2={tasksNameLabel}/>}>
</Label>

and the CustomLabel component:

function CustomLabel({viewBox, value1, value2}){
  const {cx, cy} = viewBox;
  return (
   <text x={cx} y={cy} fill="#3d405c" className="recharts-text recharts-label" textAnchor="middle" dominantBaseline="central">
      <tspan alignmentBaseline="middle" fontSize="26">{value1}</tspan>
      <tspan fontSize="14">{value2}</tspan>
   </text>
  )
}
Linder answered 3/1, 2018 at 12:30 Comment(3)
Is this working ? i have tried but the label not renderingSummerlin
@SoorajJose this renders both values in one line and not one under another.Grady
I'ts working, but I'm getting TS2741: Property viewBox is missing in typ. Is there something, I'm missing?Pika
C
6

This is an old question, but I recently played with this and looks like you can use multiple Label components and tweak their positions with css. Here is what I tweaked from the Recharts example:

const {PieChart, Pie, Legend, Tooltip, Cell, Label} = Recharts;
const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];

const data01 = [{name: 'Group A', value: 5}, {name: 'Group B', value: 4},
                 {name: 'Group C', value: 1}, {name: 'Group D', value: 1}]

const TwoSimplePieChart = React.createClass({
   render () {
   return (
       <PieChart width={800} height={400}>
       <Pie 
       data={data01} 
       cx={300}
       cy={150} 
       innerRadius={60}
       outerRadius={70} 
       fill="#8884d8"
       paddingAngle={2}
       >
       <Label 
       value="6" position="centerBottom"  className='label-top' fontSize='27px'
       />
       <Label 
       value="tasks left" position="centerTop" className='label'
       />
         {
           data01.map((entry, index) => <Cell fill={COLORS[index % COLORS.length]}/>)
         }
       </Pie>
       <Tooltip/>
      </PieChart>
   );
 }
})

ReactDOM.render(
 <TwoSimplePieChart />,
 document.getElementById('container')
);

and CSS:

.label-top {
    transform: translateY(-10px);
}

You can check the JSFiddle here: https://jsfiddle.net/trung2012/pcbq3146/34/

Christenson answered 14/1, 2020 at 2:46 Comment(1)
This is works just fine! I was wondering if there a was to wrap the label text. That would be great.Sines
N
2

I needed the labels one above another. I made the below change to accomplish it.

<Label width={30} position="center"
  content={<CustomLabel value1={totalTasks} value2={tasksNameLabel}/>}>
</Label>

And the Custom labels will be as follows:

function CustomLabel(props) {
  const { cx, cy } = props.viewBox;
  return (
    <>
      <text
        x={cx}
        y={cy - 5}
        fill="rgba(0, 0, 0, 0.87)"
        className="recharts-text recharts-label"
        textAnchor="middle"
        dominantBaseline="central"
      >
        <tspan alignmentBaseline="middle" fontSize="31.5px" fontFamily="Roboto">
          {props.value2}
        </tspan>
      </text>
      <text
        x={cx}
        y={cy + 20}
        fill="rgba(0, 0, 0, 0.54)"
        className="recharts-text recharts-label"
        textAnchor="middle"
        dominantBaseline="central"
      >
        <tspan fontSize="12.3px" fontFamily="Roboto">
          {props.value1}
        </tspan>
      </text>
    </>
  );
}
Nightspot answered 27/9, 2020 at 11:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.