Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[charts] Pie chart overflow with legend #13648

Closed
ValberJunior opened this issue Jun 27, 2024 · 9 comments
Closed

[charts] Pie chart overflow with legend #13648

ValberJunior opened this issue Jun 27, 2024 · 9 comments
Labels
component: charts This is the name of the generic UI component, not the React module! support: docs-feedback Feedback from documentation page

Comments

@ValberJunior
Copy link

ValberJunior commented Jun 27, 2024

Search keywords

responsiveChartContainer for PieChart

Related page

https://mui.com/x/react-charts/pie/

Kind of issue

Missing information

Issue description

I have a small problem with responsiveness when using Pie Charts.
In the documentation there is a brief mention of the "RespomsiveChartContainer", but it doesn't show any example of use with Pie Chart, and I try to add it to my code and the Pie Chart doesn't render.
On large screens, the subtitles are clearly visible, but when I reduce the screen,the subtitles are scrambled in the chart. Is there anything I can do to make it responsive without losing the subtitles?

Context

Current code:

import React from 'react'
import { ChartProps } from './types'
import { PieChart } from '@mui/x-charts/PieChart';
import { Box } from '@material-ui/core';

export const Chart : React.FC<ChartProps> = (props) => {

 const { items } = props;

  return (
      <Box sx={{ width:'100%'}}>
        <PieChart
        series={[
          {
            data: items,
            innerRadius: 50,
            highlightScope: { faded: 'global', highlighted: 'item' },
          }
        ]}
        height={250}
        slotProps={{
          legend: { 
              hidden: false
           },
        }}
      />
      </Box>
  );
}
@ValberJunior ValberJunior added status: waiting for maintainer These issues haven't been looked at yet by a maintainer support: docs-feedback Feedback from documentation page labels Jun 27, 2024
@alexfauquette
Copy link
Member

On large screens, the subtitles are clearly visible, but when I reduce the screen,the subtitles are scrambled in the chart.

You can use the margin={{ right: 150 }} (or other value, or top, left, bottom) to restrain the space available to draw the pie (end then free some space for the legend)

Here is an example, where you can modify right.
https://codesandbox.io/p/sandbox/charming-blackburn-tl5yvr?file=%2Fsrc%2FDemo.tsx%3A11%2C12

At right: 50 it overflows. But at 150 it let enough space for the legend

image
image

Does that solves your issue?

@alexfauquette alexfauquette added component: charts This is the name of the generic UI component, not the React module! and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jun 28, 2024
@alexfauquette alexfauquette changed the title [docs] [charts] Pie chart overflow with legend Jun 28, 2024
@ValberJunior
Copy link
Author

ValberJunior commented Jun 28, 2024

Hello, how are you?
So, maybe it will help a bit, but I ended up choosing to put the subtitles at the bottom and hide them when the screen is smaller:

import React from 'react'
import { ChartProps } from './types'
import { PieChart } from '@mui/x-charts/PieChart';
import { Box } from '@material-ui/core';

export const Chart : React.FC<ChartProps> = (props) => {

 const [ isHidden, setIsHidden ] = React.useState<boolean>(false);
 const { items } = props;
 const chartItems = (items.length === 1 && items[0].value === 0) ? [{id: items[0].id, label: items[0].label, value: 0.001}] : items;
 const size = {height: 450}

 const handleResize = () => {
  if(window && window.innerWidth < 950) setIsHidden(true);
  else setIsHidden(false);
 }

 React.useEffect(()=>{
  window.addEventListener('resize', handleResize);
  handleResize();

  return () => {
    window.removeEventListener('resize',handleResize)
  }
 },[])

  return (
    <Box sx={{ width: '100%', height: '100%' }}>
      <PieChart
        series={[
          {
            data: chartItems,
            innerRadius: '50%',
            highlightScope: { faded: 'global', highlighted: 'item' },
          },
        ]}
        slotProps={{
          legend: {
            hidden: isHidden,
            direction: 'row',
            position: { vertical: 'bottom', horizontal: 'middle' },
            padding: 0,
            labelStyle:{
              fontSize: 14
            },
            itemMarkWidth: 11,
            itemMarkHeight: 10,
          },
        }}
        margin={{ top: 100, bottom: 100, left: 100, right: 100 }}
        {...size}
      />
    </Box>
  );
}

In this case it helped, but I missed being able to manipulate the pieChart responsively, having control over its size and being able to edit the captions better. At first the idea was to have a personalized caption with a table, but as it was a bit obscure to manipulate the component, I opted to leave the caption below and create a separate explanatory table.

image

@alexfauquette
Copy link
Member

At first the idea was to have a personalized caption with a table

The legend is currently in the SVG, so drawing a table might be complex.
At that level of customization, the easiest might be to create your legend with HTML and display it next to the chart, and hide the legend

@ValberJunior
Copy link
Author

Great, but how can I insert a new html into the chart? and even more, how can I get item by item, because I imagine that to draw an html table I would need to get the color of the item, the label and the value and iterate over the table.
Are there any props that ChartPie accepts that I can do this with? Or any props that it exposes that I can manipulate?

@alexfauquette
Copy link
Member

You don't need to put it in. You can put it out

function ChartsWithLegend() {
  <div>
    <PieChart />
    <MyLegend />
  </div>
}

how can I get item by item

You are providing the items to chat <PieChart/> so you have acce to them.

The only thing we defaultize is the color. Either you force them in the charts with <PieChart colors={[....]} />

or you can use the default one import { blueberryTwilightPalette } from '@mui/x-charts/colorPalettes';

@blarson-hearst
Copy link

Using margin "solves" the issue, but it is really only useful for static charts. Many of us have dynamic data, so the label height/width is unknown making overlaps very common. I've had to do clunky margin calculations based on legend character widths, but I have to overshoot it, so there often ends up being a lot of awkward white space.

I have investigated the source code too much, but the legend and the chart appear to be a single SVG. Without knowing much about the a11y impacts there, couldn't we split it into 2 SVGs and use something like flexbox to handle the flow so it can't overlap?

@alexfauquette
Copy link
Member

The plan for the next major is to remove the current built-in legend and create a new one with HTML, so we can benefit from the Flex and other nice CSS text placement SVG miss.

@alexfauquette
Copy link
Member

I'm closing this one for the same reason as #13787

The next major moves legend outside of the SVG so this should not be an issue anymore.
You can already have a look at https://next.mui.com/x/react-charts/legend/ and open issue if you seem missing edge cases

Copy link

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

Note

@ValberJunior How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: charts This is the name of the generic UI component, not the React module! support: docs-feedback Feedback from documentation page
Projects
None yet
Development

No branches or pull requests

3 participants