Заполнение всплывающей подсказки d3.js из массива

Данные JSON

    var IDData = JSON.stringify([
  ["C2", "ID2", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 500.0, 2],
  ["C2", "ID2", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 700.0, 3],
  ["C2", "C3", "Customer", "Customer", "2015-1-1", "2015-1-1", 500.0, 2],
  ["C2", "C3", "Customer", "Customer", "2015-1-2", "2015-1-3", 600.0, 2],
  ["C6", "C1", "Customer", "Customer", "2015-1-1", "2015-1-1", 500.0, 1],
  ["C5", "ID4", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 500.0, 2],
  ["C1", "ID1", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 500.0, 1],
  ["C1", "P1", "Customer", "Phone", "2015-1-1", "2015-1-1", 500.0, 1],
  ["C6", "P2", "Customer", "Phone", "2015-1-1", "2015-1-1", 500.0, 2],
  ["C6", "P2", "Customer", "Phone", "2015-1-3", "2015-1-4", 800.0, 2],

  ["C2", "C6", "Customer", "Customer", "2015-1-1", "2015-1-1", 500.0, 1],
  ["C4", "C3", "Customer", "Customer", "2015-1-1", "2015-1-1", 500.0, 3],
  ["C1", "C2", "Customer", "Customer", '2015-1-1', "2015-1-1", 500.0, 1],
  ["C4", "ID3", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 500.0, 3],
  ["C3", "ID3", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 500.0, 3],
  ["C1", "C5", "Customer", "Customer", "2015-1-1", "2015-1-1", 500.0, 1]
]);

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

 var galData = JSON.parse(IDData);
var startnodes = [];
var endnodes = [];
var startnodetype = [];
var endnodetype = [];
var SendTime = [];
var PayTime = [];
var Total_Amt = [];
var Depth = [];
galData.map(function(e, i) {
  startnodes.push(e[0]);
  endnodes.push(e[1]);
  startnodetype.push(e[2]);
  endnodetype.push(e[3]);
  SendTime.push(e[4]);
  PayTime.push(e[5]);
  Total_Amt.push(e[6]);
  Depth.push(e[7]);
});
var final_data = createNodes(startnodes, endnodes, startnodetype, endnodetype, SendTime, PayTime, Total_Amt, Depth);
makeGraph("#Network_graph", final_data);

Ниже представлена ​​функция createNodes(), которая помогает создавать узлы и ссылки:

    function createNodes(startnodes, endnodes, startnodetype, endnodetype, SendTime, PayTime, Total_Amt, Depth) {
  var node_set = [];
  var links = [];
  var nodetype = d3.set();
  startnodes.forEach(function(src, i) {
    var tgt = endnodes[i];
    if (!node_set.find(function(d) {
        return d.id == src
      })) {
      node_set.push({
        id: src,
        type: startnodetype[i]
      });
    }
    if (!node_set.find(function(d) {
        return d.id == tgt
      })) {
      node_set.push({
        id: tgt,
        type: endnodetype[i]
      });
    }

    links.push({
      source: src,
      target: tgt,
      sendtime: SendTime[i],
      paytime: PayTime[i],
      total_amt: Total_Amt[i],
      depth: Depth[i],
      value: 1
    });
  });

  startnodetype.forEach(function(src, i) {
    var tgt_type = endnodetype[i];
    nodetype.add(src);
    nodetype.add(tgt_type);
  });

  var d3GraphData = {
    nodes: node_set.map(function(d) {
      return {
        id: d.id,
        type: d.type,
        group: 1
      }
    }),
    links: links,
    nodetype: nodetype.values().map(function(d) {
      return {
        id: d.id,
        group: 1
      }
    })
  }
  return d3GraphData;

};

Теперь в моей функции makeGraph() я пытаюсь отобразить некоторые данные при наведении курсора на узлы и ссылки с помощью всплывающей подсказки.

узлы: d.id и d.type, ссылки: d.paytime, d.Sendtime, d.Amount и d.depth

Существуют сценарии, в которых «источник» и «цель» имеют несколько взаимодействий между собой.

 ["C2", "ID2", "Customer", "ID_Card", "2015-1-1", "2015-1-1", 500.0, 2],
 ["C2", "ID2", "Customer", "ID_Card", "2015-1-2", "2015-1-3", 700.0, 2]

Итак, при наведении на ссылки мне нужно отобразить

PayTime: 2015-1-3
  Amount: 700
  SendTime: 2015-1-2
  Depth: 3

   PayTime: 2015-1-1
  Amount: 500
  SendTime: 2015-1-1
  Depth: 2

Для этого внутри функции mouseover есть функция, которая подготавливает все данные между исходным и целевым узлами:

         .on('mouseover', function(d) {
        var thisSource = d.source.id,
            thisTarget = d.target.id;
        var filteredLinks = d3GraphData.links.filter(function(e) {
            return (e.source.id === thisSource && e.target.id === thisTarget) 
                || (e.source.id === thisTarget && e.target.id === thisSource);
        });

После этого мне нужно заполнить всплывающую подсказку, используя массив отфильтрованных данных. Но это выходит за мои рамки, так как я новичок в javascript/d3.js.

Вот скрипта


person optimus_prime    schedule 22.12.2016    source источник


Ответы (1)


Это мое предложение: на основе filteredLinks создайте выделение, которое добавит HTML к вашему tooltip div:

var list = tooltip.selectAll(".list")
    .data(filteredLinks)
    .enter()
    .append("div");

list.html(function(d) {
    return "Paytime: " + d.paytime + "<br>Sendtime: " + d.sendtime 
    + "<br>Amount: " + d.total_amt + "<br>Depth: " + d.depth + "<br><br>";
});

tooltip.transition()
    .duration(300)
    .style("opacity", .8);

tooltip.style("left", (d3.event.pageX) + "px")
    .style("top", (d3.event.pageY + 10) + "px");

Вот ваша обновленная скрипта: https://jsfiddle.net/4av3ctea/

PS: Подумайте о том, чтобы сделать эти линии шире... сейчас очень сложно навести на них курсор. Простая альтернатива — создать более широкую прозрачную линию, чтобы ловить события мыши.

person Gerardo Furtado    schedule 22.12.2016
comment
большое спасибо .. Вся часть объекта списка - это что-то вроде кривой обучения. - person optimus_prime; 22.12.2016