Plotly 的restyle
函数在这里对我们没有帮助,但我们仍然可以将onclick
事件与一点 JavaScript 一起使用。该代码在 10,000 分上具有可接受的性能。
我们可以使用以下方法获取在 JavaScript 中单击的点:
var point = document.getElementsByClassName('scatterlayer')[0].getElementsByClassName('scatter')[data.points[0].curveNumber].getElementsByClassName('point')[data.points[0].pointNumber];
(scatterlayer
是所有散点图元素所在的层,
scatter[n]
是第n个散点图,point[p]
是其中的第p个点)
现在我们只是把这一点放大很多(或者你想要的任何其他形状/变换):
point.setAttribute('d', 'M10,0A10,10 0 1,1 0,-10A10,10 0 0,1 10,0Z');
为了获得恢复所有内容的可能性,我们将关于该点的未更改信息与其余的 Plotly 信息一起存储:
var plotly_div = document.getElementsByClassName('plotly')[0];
plotly_div.backup = {curveNumber: data.points[0].curveNumber,
pointNumber: data.points[0].pointNumber,
d: point.attributes['d'].value
}
稍后我们可以恢复点:
var old_point = document.getElementsByClassName('scatterlayer')[0].getElementsByClassName('scatter')[plotly_div.backup.curveNumber].getElementsByClassName('point')[plotly_div.backup.pointNumber]
old_point.setAttribute('d', plotly_div.backup.d);
现在我们可以将所有代码添加到plotly
小部件中。
javascript <- "
function(el, x){
el.on('plotly_click', function(data) {
var point = document.getElementsByClassName('scatterlayer')[0].getElementsByClassName('scatter')[data.points[0].curveNumber].getElementsByClassName('point')[data.points[0].pointNumber];
var plotly_div = document.getElementsByClassName('plotly')[0];
if (plotly_div.backup !== undefined) {
var old_point = document.getElementsByClassName('scatterlayer')[0].getElementsByClassName('scatter')[plotly_div.backup.curveNumber].getElementsByClassName('point')[plotly_div.backup.pointNumber]
if (old_point !== undefined) {
old_point.setAttribute('d', plotly_div.backup.d);
}
}
plotly_div.backup = {curveNumber: data.points[0].curveNumber,
pointNumber: data.points[0].pointNumber,
d: point.attributes['d'].value,
style: point.attributes['style'].value
}
point.setAttribute('d', 'M10,0A10,10 0 1,1 0,-10A10,10 0 0,1 10,0Z');
});
}"
[...]
ggplotly(p) %>% onRender(javascript)
或者,您可以根据单击点的位置创建一个新的 SVG 元素,但颜色和形状是您想要的。
你可以在这里尝试没有 R/Shiny。
//create some random data
var data = [];
for (var i = 0; i < 10; i += 1) {
data.push({x: [],
y: [],
mode: 'markers',
type: 'scatter'});
for (var p = 0; p < 200; p += 1) {
data[i].x.push(Math.random());
data[i].y.push(Math.random());
}
}
//create the plot
var myDiv = document.getElementById('myDiv');
Plotly.newPlot(myDiv, data, layout = { hovermode:'closest'});
//add the same click event as the snippet above
myDiv.on('plotly_click', function(data) {
//let's check if some traces are hidden
var traces = document.getElementsByClassName('legend')[0].getElementsByClassName('traces');
var realCurveNumber = data.points[0].curveNumber;
for (var i = 0; i < data.points[0].curveNumber; i += 1) {
if (traces[i].style['opacity'] < 1) {
realCurveNumber -= 1
}
}
data.points[0].curveNumber = realCurveNumber;
var point = document.getElementsByClassName('scatterlayer')[0].getElementsByClassName('scatter')[data.points[0].curveNumber].getElementsByClassName('point')[data.points[0].pointNumber];
var plotly_div = document.getElementsByClassName('plotly')[0];
if (plotly_div.backup !== undefined) {
var old_point = document.getElementsByClassName('scatterlayer')[0].getElementsByClassName('scatter')[plotly_div.backup.curveNumber].getElementsByClassName('point')[plotly_div.backup.pointNumber]
if (old_point !== undefined) {
old_point.setAttribute('d', plotly_div.backup.d);
}
}
plotly_div.backup = {curveNumber: data.points[0].curveNumber,
pointNumber: data.points[0].pointNumber,
d: point.attributes['d'].value,
style: point.attributes['style'].value
}
point.setAttribute('d', 'M10,0A10,10 0 1,1 0,-10A10,10 0 0,1 10,0Z');
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv">