RMS*_*RMS 6 javascript charts plotly
我使用 Plotly.js 创建了 3 个时间序列图,并且我希望保持缩放级别/平移同步,因此如果用户缩放/平移 3 个图中的任何一个,则其他 2 个得到更新。
现在我在事件的第一个图表上设置了一个事件处理程序plotly_relayout。事件处理程序使用传入的事件数据调用Plotly.relayout其他两个图表。
有谁知道如何识别哪个图首先发出plotly_relayout事件,这样它就不会陷入处理自己事件的循环中?或者也许有更好的方法来处理保持多个图表之间的缩放/平移同步?
正如 Ashish Rathi 注意到的,上述解决方案有一个错误 - 当您尝试按下某些按钮时,代码执行进入无限循环。解决方案是检查自己的重新布局处理程序中的“ed”变量,如果它没有属性 - 只是退出。看起来在某些情况下,Plotly 发送带有包含更新的空对象的plotly_relayout 事件只是为了好玩 - 可能是某种错误。
就我而言,我不想将 Y 缩放从一个图传播到另一个图 - 因此我准备了一个单独的结构,其中仅包含我想要传播的那些属性。
var myDiv = document.getElementById("myDiv");
var myDiv2 = document.getElementById("myDiv2");
var myDiv3 = document.getElementById("myDiv3");
var startTime = new Date().getTime();
var timeStep = 60000;
var myDivMax = 70;
var myDiv2Max = 9000;
var myDiv3Max = 500;
var d3 = Plotly.d3,
N = 40,
x = d3.range(N).map(() => {
return new Date((startTime += timeStep));
}),
y = d3.range(N).map(() => Math.random() * myDivMax),
data = [{ x: x, y: y }];
var layout = {
height: 200,
margin: { l: 45, t: 5, r: 45, b: 45 },
xaxis: {
tickfont: {
size: 10,
color: "#7f7f7f"
}
},
yaxis: {
fixedrange: true,
tickfont: {
size: 10,
color: "#7f7f7f"
}
}
};
var layout2 = {
height: 200,
margin: { l: 45, t: 5, r: 45, b: 45 },
xaxis: {
tickfont: {
size: 10,
color: "#7f7f7f"
}
},
yaxis: {
fixedrange: true,
tickfont: {
size: 10,
color: "#7f7f7f"
}
}
};
var layout3 = {
height: 200,
margin: { l: 45, t: 5, r: 45, b: 45 },
xaxis: {
tickfont: {
size: 10,
color: "#7f7f7f"
}
},
yaxis: {
fixedrange: true,
tickfont: {
size: 10,
color: "#7f7f7f"
}
}
};
Plotly.plot(myDiv, data, layout);
var data2 = [{ x: x, y: d3.range(N).map(() => Math.random() * myDiv2Max) }];
Plotly.plot(myDiv2, data2, layout2);
var data3 = [{ x: x, y: d3.range(N).map(() => Math.random() * myDiv3Max) }];
Plotly.plot(myDiv3, data3, layout3);
var divs = [myDiv, myDiv2, myDiv3];
function relayout(ed, divs) {
if (Object.entries(ed).length === 0) {return;}
divs.forEach((div, i) => {
let x = div.layout.xaxis;
if (ed["xaxis.autorange"] && x.autorange) return;
if (x.range[0] != ed["xaxis.range[0]"] ||x.range[1] != ed["xaxis.range[1]"])
{
var update = {
'xaxis.range[0]': ed["xaxis.range[0]"],
'xaxis.range[1]': ed["xaxis.range[1]"],
'xaxis.autorange': ed["xaxis.autorange"],
};
Plotly.relayout(div, update);
}
});
}
var plots = [myDiv, myDiv2, myDiv3];
plots.forEach(div => {
div.on("plotly_relayout", function(ed) {
relayout(ed, divs);
});
});Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<h2>Resize any chart, the others will get the same zoom level applied</h2>
<div id="myDiv"></div>
<div id="myDiv2"></div>
<div id="myDiv3"></div>Run Code Online (Sandbox Code Playgroud)
我在这里复制 @ChrisG 的评论以给予他信任并显示我的问题的答案:
var myDiv = document.getElementById("myDiv");
var myDiv2 = document.getElementById("myDiv2");
var myDiv3 = document.getElementById("myDiv3");
var startTime = new Date().getTime();
var timeStep = 60000;
var myDivMax = 70;
var myDiv2Max = 9000;
var myDiv3Max = 500;
var d3 = Plotly.d3,
N = 40,
x = d3.range(N).map(() => {
return new Date((startTime += timeStep));
}),
y = d3.range(N).map(() => Math.random() * myDivMax),
data = [{ x: x, y: y }];
var layout = {
height: 200,
margin: { l: 45, t: 5, r: 45, b: 45 },
xaxis: {
tickfont: {
size: 10,
color: "#7f7f7f"
}
},
yaxis: {
fixedrange: true,
tickfont: {
size: 10,
color: "#7f7f7f"
}
}
};
var layout2 = {
height: 200,
margin: { l: 45, t: 5, r: 45, b: 45 },
xaxis: {
tickfont: {
size: 10,
color: "#7f7f7f"
}
},
yaxis: {
fixedrange: true,
tickfont: {
size: 10,
color: "#7f7f7f"
}
}
};
var layout3 = {
height: 200,
margin: { l: 45, t: 5, r: 45, b: 45 },
xaxis: {
tickfont: {
size: 10,
color: "#7f7f7f"
}
},
yaxis: {
fixedrange: true,
tickfont: {
size: 10,
color: "#7f7f7f"
}
}
};
Plotly.plot(myDiv, data, layout);
var data2 = [{ x: x, y: d3.range(N).map(() => Math.random() * myDiv2Max) }];
Plotly.plot(myDiv2, data2, layout2);
var data3 = [{ x: x, y: d3.range(N).map(() => Math.random() * myDiv3Max) }];
Plotly.plot(myDiv3, data3, layout3);
var divs = [myDiv, myDiv2, myDiv3];
function relayout(ed, divs) {
divs.forEach((div, i) => {
let x = div.layout.xaxis;
if (ed["xaxis.autorange"] && x.autorange) return;
if (
x.range[0] != ed["xaxis.range[0]"] ||
x.range[1] != ed["xaxis.range[1]"]
)
Plotly.relayout(div, ed);
});
}
var plots = [myDiv, myDiv2, myDiv3];
plots.forEach(div => {
div.on("plotly_relayout", function(ed) {
console.log(ed);
relayout(ed, divs);
});
});Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<h2>Resize any chart, the others will get the same zoom level applied</h2>
<div id="myDiv"></div>
<div id="myDiv2"></div>
<div id="myDiv3"></div>Run Code Online (Sandbox Code Playgroud)