ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Recharts 图表被极值压扁看不清?用 domain 和 allowDataOverflow 聚焦可视范围

Recharts 图表被极值压扁看不清?用 domain 和 allowDataOverflow 聚焦可视范围 Recharts 图表被极值压扁看不清用 domain 和 allowDataOverflow 聚焦可视范围【免费下载链接】rechartsRedefined chart library built with React and D3项目地址: https://gitcode.com/GitHub_Trending/re/recharts当数据集里同时存在数量级悬殊的值时Recharts 图表会出现一种典型问题最大的那个值把坐标轴撑满其余数据被压成不足 1px 的条形肉眼完全看不见只剩悬停 tooltip 才能读到数值。Recharts 官方文档用一个太阳系质量柱状图的例子完整演示了这个现象和修复路径太阳质量高达 1.989e30 kg而其他天体在 1e22 到 1e27 kg 之间默认渲染下只能看到太阳一根柱子。本文按文档中的操作顺序说明如何用domain和allowDataOverflow把可视范围聚焦到你关心的区间以及为什么只加domain不够、值差距仍然过大时的替代手段。先看被压扁的默认效果Recharts 仓库中的示例 MassBarChart.tsx 展示了这个问题的起点。核心部分如下数据为示例自带的太阳系质量数据完整文件可直接复用import { Bar, BarChart, Tooltip, XAxis, YAxis } from recharts; const solarSystem [ { name: Sun, massKg: 1.989e30 }, { name: Mercury, massKg: 3.3e23 }, { name: Venus, massKg: 4.87e24 }, { name: Earth, massKg: 5.97e24 }, { name: Mars, massKg: 6.42e23 }, { name: Jupiter, massKg: 1.9e27 }, { name: Saturn, massKg: 5.68e26 }, { name: Uranus, massKg: 8.68e25 }, { name: Neptune, massKg: 1.02e26 }, { name: Pluto, massKg: 1.3e22 }, ]; export default function MassBarChart() { return ( BarChart style{{ width: 100%, maxWidth: 800px, maxHeight: 80vh, aspectRatio: 1.618, }} responsive data{solarSystem} XAxis dataKeyname / YAxis widthauto label{{ value: Mass [kg], position: insideLeft, dx: 0, dy: 20, angle: -90 }} / Bar dataKeymassKg unitkg / Tooltip / /BarChart ); }仓库原示例中还引入了RechartsDevtools来自recharts/devtools用于开发调试上面已省略。默认渲染下可以观察到两点XAxis 是 category分类轴把值当作字符串处理不会尝试取中间值YAxis 是 number数值轴把数据当作连续谱处理。Recharts 的 auto 行为会自动把刻度撑到好看的范围——最大质量是太阳的 1.989e30 kg但 YAxis 会画出 2e30 的刻度。结果就是文档描述的原话Technically the data is there and you can mouse over it and see it in the tooltip, but the bars are less than 1px tall and so are invisible.也就是说数据没有丢只是坐标轴范围被极值主导了。为什么只加 domain 不生效直觉上的修复是直接指定 YAxis 的 domain。但 Recharts 的官方指南 DomainAndTicks 里明确记录了一个坑Lets start by adding a domain prop like this:YAxis domain{[1e23, 1e25]} /. You will see that nothing has changed! Thats because by default, Recharts will expand the domain so that it fits all the data.只写domain时Recharts 默认会把 domain 向外扩展到包含全部数据所以太阳的极值仍然把可视范围撑满图表看起来没有任何变化。加 allowDataOverflow 把极值裁掉关闭自动扩展的方式是在同一轴上加allowDataOverflowYAxis domain{[1e23, 1e25]} allowDataOverflow /仓库中的完整示例是 MassBarChartCustomYDomain.tsx其中 YAxis 配置为YAxis domain{[1e23, 2e27]} allowDataOverflow width{100} label{{ value: Mass [kg], position: insideLeft, dx: 0, dy: 20, angle: -90 }} /这里的domain{[1e23, 2e27]}是示例数据下的取值读者应按自己的数据区间替换上下界。加上allowDataOverflow后的效果文档描述为it will cut off the Sun bar (as its off the chart) and it will allow us to see the individual planets mass——太阳的柱形被裁掉因为它出了图各行星的质量条形因此可见。这就是最小可用的主路径先给数值轴写domain再写allowDataOverflow两个必须同时出现只写domain会被默认扩展行为抵消。domain 支持哪些写法YAxis的domain属性在源码 src/cartesian/YAxis.tsx 的 JSDoc 中有完整说明长度必须为 2每个元素可以是数字[0, 100]字符串auto、dataMin、dataMax可计算的字符串如dataMin - 20、dataMax 1000接收单个值并返回数字的函数例如dataMin 0 - Math.abs(dataMin)接收[dataMin, dataMax]并返回[min, max]的函数例如YAxis typenumber domain{([dataMin, dataMax]) { const absMax Math.max(Math.abs(dataMin), Math.abs(dataMax)); return [-absMax, absMax]; }} /其中任意一个元素设为auto时Recharts 会计算漂亮的刻度最终 domain 由刻度生成。allowDataOverflow则与domain{[0, 100]}这类显式数值范围配合使用即上面 JSDoc 中的示例domain{[0, 100]} allowDataOverflow。验证如何判断修复生效文档给出的判断方式是直接对照渲染结果而不是数值断言默认状态只看得见太阳一根柱其他条形不足 1px加上domainallowDataOverflow后超出 domain 的柱形示例中是太阳被截断落在 domain 内的行星质量条形变得可见。如果验证后岩石行星仍然小到看不见示例数据中确实如此因为 1e23 到 1e27 之间差距仍有四个数量级说明线性比例尺本身不适合对比数量级悬殊的值这时文档给出的下一步是换刻度。可选分支log 刻度与自定义 ticks用 log scale 对比数量级默认刻度是 lineareasy to read but it doesnt allow comparing very small and very large values. Logarithmic scale is better for that purpose (but it does require the reader to be careful)。通过scale属性切换YAxis scalelog domain{[1e22, 3e30]} width{100} label{{ value: Mass log10[kg], position: insideLeft, dx: 0, dy: 20, angle: -90 }} /这是仓库示例 MassBarChartLogScale.tsx 的写法domain 覆盖 1e22 到 3e30全部天体都能落入同一坐标轴。两点必须注意文档明确提示Note that the log scale has a bug where it requires one to set an explicit domain. 也就是说scalelog时必须显式给 domain不能依赖 autoscale也可以写成 d3-scale 的完整定义scale属性支持字符串快捷方式或完整的 scale 定义对象见 src/cartesian/YAxis.tsx 中scale的 JSDoc。用 tickFormatter 改刻度标签如果不想让刻度显示科学计数法可以用tickFormatter自定义刻度文本。仓库中的示例 MassBarChartCustomTicks.tsx 把质量值换算成 yottagrams 单位展示。这一步只影响刻度显示不改变坐标轴范围。边界与替代路径换轴类型不是等价方案指南里演示过把 YAxis 改成typecategory结果是shows more stuff但每个数值被当作独立字面值处理刻度不排序、不取整且太阳条形高度为零1.989e30 的刻度落在最底部起点。文档的结论是Recharts can do better即domainallowDataOverflow仍是推荐路径。把 XAxis 改成typenumber没有意义示例中 X 轴是行星名非数值数据转换后无内容可显示。被裁掉的极值数据并未丢失超出 domain 的值仍然在数据中tooltip 可以读到见 DomainAndTicks 指南只是柱形在图外被截断。如果业务上必须让读者看到极值本身需要另行取舍比如单独标注文档未给出更多方案。完整的指南原文在 www/src/components/GuideView/DomainAndTicks/index.tsx五个示例组件基线、category Y 轴、自定义 domain、log scale、自定义 ticks都在 DomainAndTicks 目录 下可以直接对照运行。【免费下载链接】rechartsRedefined chart library built with React and D3项目地址: https://gitcode.com/GitHub_Trending/re/recharts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表