Home > database >  React, Nivo: Passing custom valueFormat function as props to PieChart
React, Nivo: Passing custom valueFormat function as props to PieChart

Time:01-10

I am trying to pass a custom valueFormat function as props so the arcLabels will be rendered with an trailing "%" to a PieChart. While this works pretty well with simple expressions, I do not get it to work with an arrow function. I am fairly new to coding so I hope this is an easy one for you experienced guys.

What works

Calling the PieChart with a simple expression as a prop:

valueFormat: ">-~",

into:

valueFormat={props.valueFormat}

Using the arrow function for "%" as hard coded attribute, so no call with a prop:

valueFormat={value =>            
${Number(value).toLocaleString('en-EN', {
            minimumFractionDigits: 2,
        })} %`
    }

What doesn't work

Calling the PieChart with an arrow function as a prop:

valueFormat:{{value =>
${Number(value).toLocaleString('en-EN', {minimumFractionDigits: 2,
        })} %`
    }}

into:

valueFormat={props.valueFormat}

I tried:

  • to wrap it as a const and pass the const
  • convert it to a string and pass it as that

I cannot be sure that I didn't do any mistakes, though.

At this point I am just trying things without understanding anything. Hope you guys can give me a quick hint. Currently I simply built a second PieChart component and hard-coded it into the second.

Thanks in advance!

CodePudding user response:

When you set a top-level prop on a component, you always use the = syntax.

String constants can be passed directly in quotes:

<Component someProp="someValue"/>

But all other values must be wrapped in curly braces { }. This includes numbers, objects, functions, and variables of any type:

<Component
  a={5}
  b={someVariable}
  c={someFunction}
  d={(e) => {
    console.log(e);
  }}
  e={{ property: "value" }}
/>

You only use colons : in props for setting a property on an object, like the e={{ property: "value" }} in the above example.

valueFormat is a top-level prop of the Pie component, so you need to use valueFormat=.

The valueFormat prop of a Nivo chart can be either:

  • a string which is a D3 formatter, like your ">-~" example.
  • a function which takes the value and returns a string.

You can define your formatter with an inline arrow function like this:

<ResponsivePie
    data={data}
    {/* ... your other props ... */}
    valueFormat={(value) =>
      `${Number(value).toLocaleString("en-EN", { minimumFractionDigits: 2 })} %`
    }
/>

You can also store that function as a variable (either function or const) and set that variable as the prop of the pie chart:

function percentFormat(value) {
  return `${Number(value).toLocaleString("en-EN", { minimumFractionDigits: 2 })} %`;
}
const percentFormat = (value) =>
  `${Number(value).toLocaleString("en-EN", { minimumFractionDigits: 2 })} %`;
<ResponsivePie
    data={data}
    {/* ... your other props ... */}
    valueFormat={percentFormat}
/>

CodePudding user response:

Thanks to your post I was now able to put it in a const and pass it as a prop of the PieCompanySizes which then creates the Pie (ResponsivePie) and passes the valueFormat as a prop to it, like this:

PieCompanySizes:

const PieCompanySizes = () => {
  const valueF = (value) =>
    `${Number(value).toLocaleString("en-EN", { minimumFractionDigits: 2 })}%`;
  return (
    <div className="flex mt-5 relative xs:mr-[-16px]">
      <PieChart
        {...{
          data: piedata,
          arcLabels: true,
          arcLabelsRadiusOffset: 0.5,
          translateX: 0,
          translateY: 45,
          itemsSpacing: 10,
          endAngle: 360,
          width: 320,
          height: 500,
          margin: { top: -65, right: 20, bottom: 80, left: 20 },
          valueFormat: valueF,
        }}
        ...

Pie (from Nivo):

const PieChart = (props) => {
  const theme = useTheme();
  const colors = tokens(theme.palette.mode);
 return (
    <Pie
      data={props.data}
      width={props.width}
      height={props.height}
      margin={props.margin}
      enableArcLabels={props.arcLabels}
      valueFormat={props.valueFormat}
      ...

Just so no one is confused: I am using <Pie> instead of <ResponsivePie> as fiddling around with CSS flex and the zero-height issue of Nivo Pies created too much headache for me to solve at that point.

Thank you! :)

  • Related