如何让MUI-X与React中的BarChart实现响应式?
问题
我正尝试让当前固定尺寸(500x200px)的BarChart实现响应式。官方文档说明需将BarChart包裹在ResponsiveChartContainer中,但我尝试各种方式后,要么图表完全消失,要么出现报错。请问正确的实现方式是什么?
原代码如下:
import React from 'react'; import { BarChart } from '@mui/x-charts'; interface HighlightCounts { [key: string]: number; } interface MyBarChartComponentProps { counts: HighlightCounts; } class MyBarChartComponent extends React.Component<MyBarChartComponentProps> { render() { const { counts } = this.props; const xAxisConfig = { tickLabelInterval: (value: any, index: any) => Number.isInteger(value), // only full numbers bc these are counts valueFormatter: (value: any) => value.toFixed(0), label:'Votes' }; // Transform the highlightCounts object into an array suitable for the BarChart const dataset = Object.entries(counts).map(([name, value]) => ({ name, value })); return ( <BarChart dataset={dataset} yAxis={[{ scaleType: 'band', dataKey: 'name' }]} xAxis={[xAxisConfig]} series={[ { color:'#DBF881', dataKey: 'value', valueFormatter: (value) => `${value} votes` } ]} width={500} height={200} layout="horizontal" borderRadius={5} margin={{ left: 75 }} sx={{ "& .MuiChartsAxis-left .MuiChartsAxis-tickLabel, & .MuiChartsAxis-bottom .MuiChartsAxis-tickLabel, &.MuiChartsAxis-tick, .MuiChartsAxis-label": { strokeWidth: "0.4", fill: "#fff" }, "& .MuiChartsAxis-left .MuiChartsAxis-line, & .MuiChartsAxis-bottom .MuiChartsAxis-line, .MuiChartsAxis-tick": { stroke: "#fff", strokeWidth: 0.4, } }} /> ); } } export default MyBarChartComponent;
正确实现方式
要实现响应式BarChart,只需按以下步骤修改代码:
- 导入ResponsiveChartContainer:从
@mui/x-charts中同时导入ResponsiveChartContainer和BarChart。 - 移除固定尺寸属性:删除BarChart组件上的
width和height属性,响应式容器会自动适配父容器尺寸。 - 用ResponsiveChartContainer包裹BarChart:将BarChart放入容器中,通过容器的
sx属性设置响应式尺寸约束。
修改后的完整代码:
import React from 'react'; import { BarChart, ResponsiveChartContainer } from '@mui/x-charts'; interface HighlightCounts { [key: string]: number; } interface MyBarChartComponentProps { counts: HighlightCounts; } class MyBarChartComponent extends React.Component<MyBarChartComponentProps> { render() { const { counts } = this.props; const xAxisConfig = { tickLabelInterval: (value: any, index: any) => Number.isInteger(value), // 只显示整数刻度,因为是计数 valueFormatter: (value: any) => value.toFixed(0), label:'票数' }; // 将counts对象转换为BarChart可用的数组格式 const dataset = Object.entries(counts).map(([name, value]) => ({ name, value })); return ( <ResponsiveChartContainer sx={{ width: '100%', maxWidth: 500, height: 200 }} // 响应式约束:占满父容器宽度,最大宽度500px,高度保持200px margin={{ left: 75 }} > <BarChart dataset={dataset} yAxis={[{ scaleType: 'band', dataKey: 'name' }]} xAxis={[xAxisConfig]} series={[ { color:'#DBF881', dataKey: 'value', valueFormatter: (value) => `${value} 票` } ]} layout="horizontal" borderRadius={5} sx={{ "& .MuiChartsAxis-left .MuiChartsAxis-tickLabel, & .MuiChartsAxis-bottom .MuiChartsAxis-tickLabel, &.MuiChartsAxis-tick, .MuiChartsAxis-label": { strokeWidth: "0.4", fill: "#fff" }, "& .MuiChartsAxis-left .MuiChartsAxis-line, & .MuiChartsAxis-bottom .MuiChartsAxis-line, .MuiChartsAxis-tick": { stroke: "#fff", strokeWidth: 0.4, } }} /> </ResponsiveChartContainer> ); } } export default MyBarChartComponent;
关键说明
ResponsiveChartContainer会自动监听父容器尺寸变化,实时调整图表大小。- 若需要高度也实现响应式,可将
height改为百分比(如height: '20vh'),或使用aspectRatio属性(如aspectRatio: 5/2匹配原500x200的宽高比)。
内容的提问来源于stack exchange,提问作者J_R
相关产品推荐
相关产品推荐

