简体   繁体   English

力向图中的图例

[英]Legend in force-directed graph

I have a force-directed graph that grabs some php-generated json and displays it. 我有一个力导向图,它可以捕获一些php生成的json并显示出来。 It can be seen here: http://www.testbed.medievalgeek.com/test_forcedirect.php . 可以在这里看到: http : //www.testbed.medievalgeek.com/test_forcedirect.php

I'd like to add a legend to the graph, and attempted to do so via modifying the tail bit of the example here: How to add a dynamic legend to a D3 force directed graph in Apex? 我想在图上添加图例,并尝试通过在此处修改示例的尾部位来做到这一点: 如何在Apex中向D3力导向图添加动态图例?

My overall javascript is here: 我的整体JavaScript在这里:

function nearest(value, min, max, steps) {
    var zerone = Math.round((value - min) * steps / (max - min)) / steps; // bring to 0-1 range
    return zerone * (max - min) + min;
}

var clientHeight = document.getElementById('dropdown').clientHeight;

var width = window.innerWidth - 10,
    height = window.innerHeight - clientHeight;

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .style("background-color", "black");

var force = d3.layout.force()
    .gravity(0.8)
    .distance(100)
    .size([width, height]);

var index = -1;

force.charge(function (d) {return d.weight * -250;});

d3.json(<?php echo "\"" . $url_string . "\""?>, function(error, json) {
    if (error) throw error;

    force
       .nodes(json.nodes)
       .links(json.links)
       .start();

    var link = svg.selectAll(".link")
   .data(json.links)
   .enter().append("line")
   .attr("class", "link")
   .attr('stroke', function(d) {return d.color; })
   .attr('stroke-width', 1)      
   .on("mouseover", function(d) {
       d3.select(this).attr('stroke-width', 2);      
    })
   .on("mouseout", function(d) {
       d3.select(this).attr('stroke-width',1);
    });

   var node = svg.selectAll(".node")
  .data(json.nodes)
  .enter().append("g")
  .attr("class", "node")
  .call(force.drag);

node.append("circle")
  .attr("r", function (d) {return nearest((Math.log(d.weight) *10), 1, 50, 10) || 10;})
  .style('fill', function(d) { return d.color; })
  .on("mouseover", function(d) {
        link.style('stroke-width', function(l) {
        if (d === l.target || d === l.source)
        return 2;
      })
        link.style('stroke', function(l) {
        if (d === l.target || d === l.source)
        return 'aqua'; 
      })
      .duration(150);      
  })
  .on("mouseout", function(d) {
    link.style('stroke-width', 1)
    link.style('stroke', function(d) {return d.color; })
    .duration(150);
  });


node.append("text")
  .attr("dx", function(d) {return  (nearest((Math.log(d.weight) *10), 1, 50, 10) + 5);})
  .attr("dy", ".35em")
  .text(function(d) {return d.name})
  .style('fill', 'lightcyan');

var legend = svg.selectAll(".legend")
 .data(color.domain())
 .enter().append("g")
 .attr("class", "legend")
 .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("circle")
 .attr("r", 10)
 .style("fill", function(d) { return d.color; });

legend.append("text")
 .attr("dx", 10)
 .attr("dy", ".35em")
 .style("text-anchor", "end")
 .text(function(d) { return d.name; });
 .style('fill', 'lightcyan');

force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });



  });
});

However, this results in a blank screen. 但是,这导致空白屏幕。 If I try to more closely replicate the example by changing the legend text: 如果我尝试通过更改图例文本来更紧密地复制示例:

legend.append("text")
    .attr("x", width - 24)
    .attr("y", 9)
    .attr("dy", ".35em")
    .style("text-anchor", "end")
    .text(function(d) { return d; });

The nodes appear, but they no longer distribute themselves according to weight and instead just appear in the upper left corner. 出现节点,但是它们不再根据重量分配自己,而是仅出现在左上角。 There also appears to be no legend. 似乎也没有传说。

What would be the best way to lay the legend out and still have the force-directed aspects work? 布置图例并使力导向方面仍然有效的最佳方法是什么? Most of the examples don't seem to work with what I already have. 大多数示例似乎与我已经拥有的不兼容。

This is actually really simple and I'm dumb for asking the question. 这实际上非常简单,我很愚蠢地问这个问题。 But in case someone else is wondering, all you have to do is plot out each item. 但是如果其他人想知道,您要做的就是绘制每个项目。 The following code might serve as a basis for someone to start. 以下代码可以作为某人入门的基础。 d.type and d.color are values passed in from the json that represent the item and the color it is denoted by the the graph, respectively. d.type和d.color是从json传入的值,分别表示项目和图形表示的颜色。

 var listTypes = d3.set(json.nodes.map(function(d){return d.type})).values();

  listColors = [];

  listPositions = [];

  lineWidths = [];

  for(l = 0; l < listTypes.length; l++){
        for (var key in json.nodes){
          if (listTypes[l] === json.nodes[key].type) {
            if (listColors.indexOf(json.nodes[key].color) > -1)
            {}
            else
              {
                lineWidths.push(json.nodes[key].type.length);
                listColors.push(json.nodes[key].color);
                var xlegend = (Math.floor(l / 10) * 100 );
                var ycounter;
                var ylegend;
                var oldxlegend;

                if (l===0) {
                  ycounter = 1;
                }

                if (ycounter < 10) {
                    listPositions.push(ycounter * 20);
                    ycounter++;
                }
                else 
                {
                    listPositions.push(ycounter * 20);
                    ycounter = 1;                    
                }

              }
          }
          else {}
       }
      }

  console.log(listTypes);
  console.log(listColors);
  console.log(listPositions);

  svg.append("rect")
  .attr("class", "overlay")
  .attr("x",5)
  .attr("y", 10)
  .attr("width", Math.max.apply(Math,lineWidths) * 10.6)
  .attr("height", listTypes.length * 21.667)
  .style ("fill", "aliceblue")

  var legend = svg.selectAll(".legend")
          .data(listTypes)
        .enter().append("g")
          .attr("class", "legend")
          .attr("transform", function(d, i) { return "translate(" + (Math.floor(i / 10)  * 105) + ", " + listPositions[i] + ")"; })

        legend.append("rect")
          .attr("x", 10)
          .attr("width", 15)
          .attr("height", 15)
          .attr("fill", function(d,i) {return listColors[i];});

        legend.append("text")
          .attr("x", 30 )
          .attr("y", 6)
            .attr("dy", ".35em")
          .text(function(d,i){ return titleCase(listTypes[i].replace(/_/g, " "))});

          svg.append("g")
        .attr("class", "legend")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM