This is a follow-up to my previous question posted here How to add custom values to nodes of plotly graph.
The solution posted works well for selecting a single node using plotly_click. As suggested in the comments, I tried to use plotly_selected for displaying multiple nodes.
I am trying to select multiple nodes and display the values associated with the nodes using the following code.
<html>
<head>
<script src="https://cdn.plot.ly/plotly-1.58.5.min.js"></script>
<style>
.graph-container {
display: flex;
justify-content: center;
align-items: center;
}
.main-panel {
width: 70%;
float: left;
}
.side-panel {
width: 30%;
background-color: lightgray;
min-height: 300px;
overflow: auto;
float: right;
}
</style>
</head>
<body>
<div class="graph-container">
<div id="myDiv" class="main-panel"></div>
<div id="lineGraph" class="side-panel"></div>
</div>
<script>
var nodes = [
{ x: 0, y: 0, z: 0, value: [1, 2, 3] },
{ x: 1, y: 1, z: 1, value: [4, 5, 6] },
{ x: 2, y: 0, z: 2, value: [7, 8, 9] },
{ x: 3, y: 1, z: 3, value: [10, 11, 12] },
{ x: 4, y: 0, z: 4, value: [13, 14, 15] }
];
var edges = [
{ source: 0, target: 1 },
{ source: 1, target: 2 },
{ source: 2, target: 3 },
{ source: 3, target: 4 }
];
var x = [];
var y = [];
var z = [];
for (var i = 0; i < nodes.length; i++) {
x.push(nodes[i].x);
y.push(nodes[i].y);
z.push(nodes[i].z);
}
var xS = [];
var yS = [];
var zS = [];
var xT = [];
var yT = [];
var zT = [];
for (var i = 0; i < edges.length; i++) {
xS.push(nodes[edges[i].source].x);
yS.push(nodes[edges[i].source].y);
zS.push(nodes[edges[i].source].z);
xT.push(nodes[edges[i].target].x);
yT.push(nodes[edges[i].target].y);
zT.push(nodes[edges[i].target].z);
}
var traceNodes = {
x: x, y: y, z: z,
mode: 'markers',
marker: { size: 12, color: 'red' },
type: 'scatter3d',
text: [0, 1, 2, 3, 4],
hoverinfo: 'text',
hoverlabel: {
bgcolor: 'white'
},
customdata: nodes.map(function(node) {
if (node.value !== undefined)
return node.value;
}),
type: 'scatter3d'
};
var layout = {
margin: { l: 0, r: 0, b: 0, t: 0 }
};
Plotly.newPlot('myDiv', [traceNodes], layout, { displayModeBar: false });
// max y value for the line plot
const ymax = Math.max(...nodes.map(n => n.value).flat());
document.getElementById('myDiv').on('plotly_selected', function(data){
var selectedNodeIndices = data.points.map(function(point) {
return point.pointNumber;
});
var values = [];
for (var i = 0; i < selectedNodeIndices.length; i++) {
values.push(nodes[selectedNodeIndices[i]].value);
}
var data = [];
for (var i = 0; i < values.length; i++) {
data.push({
type: 'scatter',
mode: 'lines',
x: [0, 1, 2],
y: values[i],
name: 'Node ' + selectedNodeIndices[i]
});
}
Plotly.newPlot('lineGraph', data, {
margin: { t: 0 },
yaxis: {autorange: false, range: [0, ymax + 1]}
});
});
</script>
</body>
</html>
There is some issue, I am not able to select multiple nodes and the line graph is not plotted when nodes are clicked.
Suggestions on how to fix this will be really helpful.
EDIT:
<html>
<head>
<script src="https://cdn.plot.ly/plotly-1.58.5.min.js"></script>
<style>
.graph-container {
display: flex;
justify-content: center;
align-items: center;
}
.main-panel {
width: 70%;
float: left;
}
.side-panel {
width: 30%;
background-color: lightgray;
min-height: 300px;
overflow: auto;
float: right;
}
</style>
</head>
<body>
<div class="graph-container">
<div id="myDiv" class="main-panel"></div>
<div id="lineGraph" class="side-panel"></div>
</div>
<script>
var nodes = [
{ x: 0, y: 0, z: 0, value: [1, 2, 3] },
{ x: 1, y: 1, z: 1, value: [4, 5, 6] },
{ x: 2, y: 0, z: 2, value: [7, 8, 9] },
{ x: 3, y: 1, z: 3, value: [10, 11, 12] },
{ x: 4, y: 0, z: 4, value: [13, 14, 15] }
];
var edges = [
{ source: 0, target: 1 },
{ source: 1, target: 2 },
{ source: 2, target: 3 },
{ source: 3, target: 4 }
];
var x = [];
var y = [];
var z = [];
for (var i = 0; i < nodes.length; i++) {
x.push(nodes[i].x);
y.push(nodes[i].y);
z.push(nodes[i].z);
}
const edge_x = [];
const edge_y = [];
const edge_z = [];
for (var i = 0; i < edges.length; i++) {
const a = nodes[edges[i].source];
const b = nodes[edges[i].target];
edge_x.push(a.x, b.x, null);
edge_y.push(a.y, b.y, null);
edge_z.push(a.z, b.z, null);
}
var traceNodes = {
x: x, y: y, z: z,
mode: 'markers',
marker: { size: 12, color: Array.from({length: nodes.length}, () => 'red') },
text: [0, 1, 2, 3, 4],
hoverinfo: 'text',
hoverlabel: {
bgcolor: 'white'
},
customdata: nodes.map(function(node) {
if (node.value !== undefined)
return node.value;
}),
type: 'scatter3d'
};
var traceEdges = {
x: edge_x,
y: edge_y,
z: edge_z,
type: 'scatter3d',
mode: 'lines',
line: { color: 'red', width: 2},
opacity: 0.8
};
var layout = {
margin: { l: 0, r: 0, b: 0, t: 0 }
};
Plotly.newPlot('myDiv', [traceNodes, traceEdges], layout, { displayModeBar: false });
// max y value for the line plot
const ymax = Math.max(...nodes.map(n => n.value).flat());
document.getElementById('myDiv').on('plotly_click', function(data){
var nodeIndex = data.points[0].pointNumber;
var values = nodes[nodeIndex].value;
// Change color of the selected node
traceNodes.marker.color = Array.from({length: nodes.length}, (_, i) => i === nodeIndex ? 'blue' : 'red');
Plotly.update('myDiv', {
marker: {
color: traceNodes.marker.color
}
}, [0]);
Plotly.newPlot('lineGraph', [{
type: 'scatter',
mode: 'lines',
x: [0, 1, 2],
y: values
}], {
margin: { t: 0 },
yaxis: {autorange: false, range: [0, ymax + 1]}
});
});
</script>
</body>
</html>
I tried to define the selected marker's color i.e. blue to indicate that it has been selected. Unfortunately, this is not working.
Regarding selecting multiple nodes,

Currently, one single curve is visible on the side panel. I would like to know how to select multiple nodes and display multiple curves.