Plotly React点击柱状图后,无法更新坐标轴类型切换图表方向的问题
问题:Plotly React切换柱状图方向时坐标轴类型未自动更新
我用Plotly React实现柱状图切换功能:初始为垂直柱状图,点击图表后旋转90度变为水平柱状图,同时交换X、Y轴数据。
尝试使用<Plot />组件的revision属性和layout.datarevision属性,但点击后图表变为空白。通过onUpdate事件监听发现,点击前后data和layout数据均正常,但坐标轴类型未更新——仍沿用初始设置:
// 初始坐标轴设置(正确) xaxis: {autorange: true, range: Array(2), type: "category"}, yaxis: {autorange: true, range: Array(2), type: "linear"} // 切换后需要的坐标轴设置 xaxis: {autorange: true, range: Array(2), type: "linear"}, yaxis: {autorange: true, range: Array(2), type: "category"}
数据已更新,但坐标轴未自动识别新数据类型,导致图表异常。如何让Plotly自动识别新数据并同步更新布局?
监听更新事件代码
const onUpdate = (event) => { console.log('update', event); };
完整代码示例
import { useEffect, useState } from "react"; import Plot from "react-plotly.js"; export default function BarChart() { const [chart, setChart] = useState({ data: [], layout: { title: "Some BarChart", showlegend: true, legend: { x: 0, y: -0.4, orientation: "h" }, autosize: true, barmode: "stack", datarevision: 0 }, config: { responive: true }, revision: 0 }); useEffect(() => { const farm1 = { x: ["Ducks", "Cows", "Pigs", "Chickens"], y: [10, 12, 14, 16], name: "Farm 1", type: "bar", marker: { color: "#000" }, hovertemplate: "%{x} - %{y:.0f} <extra></extra>" }; const farm2 = { x: ["Ducks", "Cows", "Pigs", "Chickens"], y: [8, 10, 12, 14], name: "Farm 2", type: "bar", marker: { color: "#FE7100" }, hovertemplate: "%{x} - %{y:.0f} <extra></extra>" }; setChart((prevState) => ({ data: [farm1, farm2], layout: { ...prevState.layout } })); }, [setChart]); const onUpdate = (event) => { console.log("update", event); }; const onClick = (event) => { const farm1 = { x: [10, 12, 14, 16], y: ["Ducks", "Cows", "Pigs", "Chickens"], name: "Farm 1", type: "bar", marker: { color: "#000" }, hovertemplate: "%{x} - %{y:.0f} <extra></extra>", orientation: "h" }; const farm2 = { x: [8, 10, 12, 14], y: ["Ducks", "Cows", "Pigs", "Chickens"], name: "Farm 2", type: "bar", marker: { color: "#FE7100" }, hovertemplate: "%{x} - %{y:.0f} <extra></extra>", orientation: "h" }; setChart((prevState) => ({ data: [farm1, farm2], layout: { ...prevState.layout, datarevision: prevState.layout.datarevision + 1 }, revision: prevState.revision + 1 })); console.log(event.points[0].x.replaceAll("<br>", " ").trim()); }; return ( <Plot data={chart.data} layout={chart.layout} config={chart.config} revision={chart.revision} style={{ width: "100%", height: "100%" }} useResizeHandler onClick={onClick} onUpdate={onUpdate} /> ); }
解决方案
Plotly在更新图表时会保留之前的坐标轴配置,不会自动根据新数据重新推断坐标轴类型。解决方法有两种:
方法1:显式指定坐标轴类型
在切换图表方向时,手动更新layout中的xaxis和yaxis的type属性,匹配新数据的类型:
const onClick = (event) => { // ... 数据定义部分不变 setChart((prevState) => ({ data: [farm1, farm2], layout: { ...prevState.layout, datarevision: prevState.layout.datarevision + 1, xaxis: { type: "linear" }, // 切换后X轴为数值型 yaxis: { type: "category" } // 切换后Y轴为分类型 }, revision: prevState.revision + 1 })); };
如果需要支持双向切换,可以添加状态变量(如const [isHorizontal, setIsHorizontal] = useState(false))跟踪当前图表方向,切换时根据状态动态设置坐标轴类型和数据。
方法2:清除坐标轴类型配置,让Plotly自动推断
如果不想手动指定类型,可以清除layout中xaxis和yaxis的原有配置,让Plotly根据新数据重新自动推断类型:
const onClick = (event) => { // ... 数据定义部分不变 setChart((prevState) => ({ data: [farm1, farm2], layout: { ...prevState.layout, datarevision: prevState.layout.datarevision + 1, xaxis: {}, // 清除原有X轴配置 yaxis: {} // 清除原有Y轴配置 }, revision: prevState.revision + 1 })); };
这种方式更灵活,适合数据类型动态变化的场景。
内容的提问来源于stack exchange,提问作者GeorgeEDW
相关产品推荐
相关产品推荐

