Я пытаюсь добавить значения в узлы графического графика, но есть проблема.
Код:
<html>
<head>
<script src = "https://cdn.plot.ly/plotly-latest.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 });
document.getElementById("myDiv").on("plotly_click", function(data){
var nodeIndex = data.points[0].pointIndex;
var values = nodes[nodeIndex].value;
console.info(values);
Plotly.newPlot('lineGraph', [{ x: [0, 1, 2], y: values, type: 'scatter3d'}], {
margin: { t: 0 }
});
});
</script>
</body>
</html>
var values = nodes[nodeIndex].value;
не может получить доступ к значениям узла.
Предложения о том, как это исправить, будут действительно полезными.
РЕДАКТИРОВАТЬ0:
<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 });
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;
console.info(values);
Plotly.newPlot('lineGraph', [{ x: [0, 1, 2], y: values, type: 'scatter3d'}], {
margin: { t: 0 },
yaxis: {autorange: false, range: [0, ymax + 1]}
});
});
</script>
</body>
</html>
Я внес исправления, предложенные в ответе ниже, но я по-прежнему не могу видеть линейный график при нажатии узлов на главной панели.
Я хочу видеть линейный график на боковой панели (справа) при нажатии узлов
Консоль @NIKUNJKOTHIYA выдает ошибку в строке `var values = nodes[nodeIndex].value; `
Яа, я получил это ошибка
Используйте pointNumber
вместо pointIndex
. Вам также необходимо исправить type
второго графика, для которого я также предлагаю установить фиксированный диапазон оси (в противном случае ось будет сбрасываться для каждой выбранной точки):
// 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;
Plotly.newPlot('lineGraph', [{
type: 'scatter',
mode: 'lines',
x: [0, 1, 2],
y: values
}], {
margin: { t: 0 },
yaxis: {autorange: false, range: [0, ymax + 1]}
});
});
Для справки, вот структура данных событий для 3D-графиков:
{
points: [{
curveNumber: 2, // index in data of the trace associated with the selected point
pointNumber: 2, // index of the selected point
x: 5, // x value
y: 600, // y value
z: 12, // z value
data: {/* */}, // ref to the trace as sent to Plotly.newPlot associated with the selected point
fullData: {/* */}, // ref to the trace including all of the default attributes
xaxis: {/* */}, // ref to x-axis object (i.e layout.xaxis) associated with the selected point
yaxis: {/* */} // ref to y-axis object " "
zaxis: {/* */} // ref to z-axis object " "
}, {
/* similarly for other selected points */
}]
}
И последнее: больше не используйте plotly-latest.js или его уменьшенную версию. Хотя они все еще упоминаются здесь и там в документации, они застряли на версии 1.58.5
.
Обратите внимание, что начиная с версии 2 «последние сюжетные» выходы больше не будут обновляться в CDN и останутся с последним патчем v1 v1.58.5. Поэтому для использования CDN с plotly.js v2 и выше необходимо указать точную версию plotly.js.
Вот полный код:
<html>
<head>
<script src = "https://cdn.plot.ly/plotly-2.18.1.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_click', function(data){
var nodeIndex = data.points[0].pointNumber;
var values = nodes[nodeIndex].value;
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>
Большое спасибо. Не могли бы вы проверить мое редактирование? Я не уверен, что document.getElementById('myDiv').on('plotly_click', function(data)
нужно изменить. Не могли бы вы опубликовать полный ответ?
Да, я только что добавил полный код. Вам не хватало части type: 'scatter', mode: 'lines'
для линейного графика в обработчике plotly_click.
Это прекрасно работает! Если щелкнуть несколько узлов, можем ли мы построить несколько линий одновременно? Не могли бы вы подсказать, как это можно сделать?
Я не уверен, что вы можете выбрать несколько точек в 3d, но предположим, что это возможно, вы бы использовали событие plotly_selected вместо plotly_click, затем в обработчике вы бы перебрали data.points
и построили одну трассу для каждой выбранной точки, добавили эти трассы в массив данных и, наконец, вызовите Plotly.newPlot('lineGraph', data, ...)
.
Большое спасибо, я пытался plotly_selected
, но это не работает. Если вы не возражаете, не могли бы вы проверить stackoverflow.com/questions/75413890/…?
В чем проблема? Я попробовал JSFiddle и успешно получил 3D-график с вашим кодом.