Как добавить пользовательские значения в узлы графического графика

Я пытаюсь добавить значения в узлы графического графика, но есть проблема.

Код:

<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>

Я внес исправления, предложенные в ответе ниже, но я по-прежнему не могу видеть линейный график при нажатии узлов на главной панели.

В чем проблема? Я попробовал JSFiddle и успешно получил 3D-график с вашим кодом.

NIKUNJ PATEL 08.02.2023 12:17

Я хочу видеть линейный график на боковой панели (справа) при нажатии узлов

Natasha 08.02.2023 12:18

Консоль @NIKUNJKOTHIYA выдает ошибку в строке `var values ​​= nodes[nodeIndex].value; `

Natasha 08.02.2023 12:19

Яа, я получил это ошибка

NIKUNJ PATEL 08.02.2023 12:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте 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) нужно изменить. Не могли бы вы опубликовать полный ответ?

Natasha 08.02.2023 17:44

Да, я только что добавил полный код. Вам не хватало части type: 'scatter', mode: 'lines' для линейного графика в обработчике plotly_click.

EricLavault 08.02.2023 18:00

Это прекрасно работает! Если щелкнуть несколько узлов, можем ли мы построить несколько линий одновременно? Не могли бы вы подсказать, как это можно сделать?

Natasha 09.02.2023 05:13

Я не уверен, что вы можете выбрать несколько точек в 3d, но предположим, что это возможно, вы бы использовали событие plotly_selected вместо plotly_click, затем в обработчике вы бы перебрали data.points и построили одну трассу для каждой выбранной точки, добавили эти трассы в массив данных и, наконец, вызовите Plotly.newPlot('lineGraph', data, ...).

EricLavault 09.02.2023 12:19

Большое спасибо, я пытался plotly_selected , но это не работает. Если вы не возражаете, не могли бы вы проверить stackoverflow.com/questions/75413890/…?

Natasha 10.02.2023 17:46

Другие вопросы по теме