如何将动态图例添加到 Apex 中的 D3 力定向图?

How to add a dynamic legend to a D3 force directed graph in Apex?

我在 Apex 中构建了一个基本类似于 http://bl.ocks.org/mbostock/1093130 or http://bl.ocks.org/mbostock/4062045 的 D3 力图。不同之处在于,我使用应用程序进程从数据库的地址 table 提取数据。效果很好。

节点的颜色由地址类型定义(如联系人、支付办公室、被许可人...)。现在我想在页面的一侧添加一个图例,其中包含图表使用的不同颜色和连接的地址类型。

我是在 CSS 内联部分的页面属性中执行此操作,还是必须在 D3 图形 JavaScript 代码中添加一些内容。

这是我的代码:

var graph;

function get_chart_data() {
var get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=AddressData',$v('pFlowStepId'));  
var data_all = get.get(); 
var obj = eval ("(" + data_all + ")"); 
return obj;
}


function showChart2() {

graph = get_chart_data();

var width = 1000,
    height = 800;

var color = d3.scale.category20();

var force = d3.layout.force()
    .gravity(0)
    .charge(-400)
    .linkDistance(90)
    .size([width, height]);


var svg = d3.select("#chart2").append("svg")
    .attr("width", width)
    .attr("height", height);

var nodeById = d3.map();

    graph.nodes.forEach(function(node) {
    nodeById.set(node.id, node);
  });

  graph.links.forEach(function(link) {
    link.source = nodeById.get(link.source);
    link.target = nodeById.get(link.target);
  });

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

  var link = svg.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

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

  node.append("circle")
      .attr("r", 8)
      .style("fill", function(d) { return color(d.type); })

  node.append("text")
      .attr("x", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.first_name; });

  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 + ")"; });

  });

};

我希望我解释得足够好让你理解它。

你猜怎么着,我刚刚解决了我自己的问题:)

我在function showChart2()末尾的Page Attributes的JavaScript部分添加了代码,但还是在里面

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("rect")
    .attr("x", width - 18)
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", color);

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

这里是完整的工作代码:

var graph;

function get_chart_data() {
var get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=AddressData',$v('pFlowStepId'));  
var data_all = get.get(); 
var obj = eval ("(" + data_all + ")"); 
return obj;
}


function showChart2() {

graph = get_chart_data();

var width = 1000,
    height = 800;

var color = d3.scale.category20();

var force = d3.layout.force()
    .gravity(0)
    .charge(-400)
    .linkDistance(90)
    .size([width, height]);


var svg = d3.select("#chart2").append("svg")
    .attr("width", width)
    .attr("height", height);

var nodeById = d3.map();

    graph.nodes.forEach(function(node) {
    nodeById.set(node.id, node);
  });

  graph.links.forEach(function(link) {
    link.source = nodeById.get(link.source);
    link.target = nodeById.get(link.target);
  });

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

  var link = svg.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

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

  node.append("circle")
      .attr("r", 8)
      .style("fill", function(d) { return color(d.type); })

  node.append("text")
      .attr("x", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.first_name; });

  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 + ")"; });

  });
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("rect")
    .attr("x", width - 18)
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", color);

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

};

我从没想过我可以回答我自己的问题,但它有效 ;)

我希望它对其他人也有帮助...