How to arrange the x axis lables wihtout overlapping in victory-native stacked bar chart

6.1k views Asked by At

I have a stacked bar chart, whose x axis labels would be date, the labels are overlapping how do I arrange them in such a way that it does not overlap on the next label of x axis.

I did not get how to arrange them changing the angle of the label, can anyone help me out solving the problem.

current graph image

enter image description here

victory-native

react-native-svg

const myDataset = [
  [
      { x: "20/10/2020", y: 18653 },
      { x: "21/10/2020", y: 20000 },
      { x: "23/10/2020", y: 97345 },
      { x: "24/10/2020", y: 25687 },
      { x: "25/10/2020", y: 89761 }
  ],
  [
      { x: "20/10/2020", y: 4566 },
      { x: "21/10/2020", y: 3888 },
      { x: "23/10/2020", y: 4975 },
      { x: "24/10/2020", y: 5965 },
      { x: "25/10/2020", y: 5768 }
  ],
];

class App extends React.Component {
  // This is an example of a function you might use to transform your data to make 100% data
  transformData(dataset) {
    const totals = dataset[0].map((data, i) => {
      return dataset.reduce((memo, curr) => {
        return memo + curr[i].y;
      }, 0);
    });
    return dataset.map((data) => {
      return data.map((datum, i) => {
        return { x: datum.x, y: (datum.y / totals[i]) * 100 };
      });
    });
  }

  render() {
    const dataset = this.transformData(myDataset);
    return (
      <div>
        <VictoryChart height={400} width={400}
          domain={{ x: [0,5], y: [0, 100000] }}
          domainPadding={{ x: 30, y: 20 }}
        >
           <VictoryLegend x={280} y={0}
              gutter={50}
              style={{title: {fontSize: 20 } }}
              data={[
                { name: "Tax", symbol: { fill: "blue" } },
                { name: "Amount", symbol: { fill: "black" } }
              ]}
            />
            <VictoryStack
              colorScale={["black", "blue"]}
            >
              {myDataset.map((data, i) => {
                return <VictoryBar barWidth={20}
             data={data} key={i} labelComponent={<VictoryLabel y={250} verticalAnchor={"start"}/>}/>;
              })}
            </VictoryStack>
            <VictoryAxis dependentAxis />
            <VictoryAxis 
            padding={{ left: 80, right: 60 }}
            axisLabelComponent={<VictoryLabel angle={20}/>}
            tickFormat={["20/oct/20","21/oct/20", "23/oct/20","24/oct/20","25/10/20"]}/>
        </VictoryChart>
      </div>
    );
  }
}

ReactDOM.render(<App/>, mountNode);

The above code can be copy pasted in below link and can edit https://formidable.com/open-source/victory/gallery/100-column-chart/

Is there any way that I could arrange them like below.

enter image description here

2

There are 2 answers

0
bas On

I've gotten it to work by passing a VictoryLabel with a -45 degree angle to the tickLabelComponent prop on your independent axis:

<VictoryAxis tickLabelComponent={<VictoryLabel angle={-45} y={350} />} />

So instead of passing the VictoryLabel to the axisLabelComponent prop on the VictoryAxis, pass it to the tickLabelComponent prop.

https://formidable.com/open-source/victory/docs/victory-axis#ticklabelcomponent


You might also need to add some padding to your VictoryChart component if the labels are cut off:

padding={{top: 100, bottom: 90, left: 70, right: 80}}

https://formidable.com/open-source/victory/docs/victory-axis#padding

1
Nibin Benjamin On

This is the solution i used. I had to display time on the x-axis.

In your case, you can take off the tick formatting from the VictoryAxis and let VictoryChart do the date formatting by adding property scale={{x: 'time'}} to VictoryChart

And then add fixLabelOverlap to VictoryAxis which fixes the overlap issue.