javascript - 动态生成多个 d3 svg 图

标签 javascript d3.js

我有一个名为 graphData 的对象数组(大小不一)。每个元素都包含创建 d3 图所需的所有信息,如果我通过硬编码访问 graphData 元素(即 graphdata[0]graphdata[1] 等)。

当我尝试使用 for 循环为每个元素生成一个图时,问题就来了。环顾了 stackoverflow 和网络,但解决方案都是关于生成固定数量的多个图,而不是动态生成多个图。

下面是我生成一张图的工作代码。自动生成 x 个图的推荐方法是什么?

   var graphData = data.graph;

    var RADIUS = 15;

    var edgeData = graphData[0].edges;
    var nodeData = graphData[0].nodes;
    var stageNum = graphData[0].stage;


    var xScale = d3.scale.linear()
        .domain([d3.min(edgeData, function (d) {
            return d.start[0];
        }),
            d3.max(edgeData, function (d) {
                return d.start[0];
            })])
        .range([50, w - 100]);

    var yScale = d3.scale.linear()
        .domain([d3.min(edgeData, function (d) {
            return d.start[1];
        }),
            d3.max(edgeData, function (d) {
                return d.start[1];
            })])
        .range([50, h - 100]);

    var rScale = d3.scale.linear()
        .domain([0, d3.max(edgeData, function (d) {
            return d.start[1];
        })])
        .range([14, 17]);

    // already have divs with classes stage1, stage2... created.
    var svg = d3.select(".stage" + stageNum).append("svg")
        .attr({"width": w, "height": h})
        .style("border", "1px solid black");

    var elemEdge = svg.selectAll("line")
        .data(edgeData)
        .enter();

    var edges = elemEdge.append("line")
        .attr("x1", function (d) {
            return xScale(d.start[0]);
        })
        .attr("y1", function (d) {
            return yScale(d.start[1]);
        })
        .attr("x2", function (d) {
            return xScale(d.end[0]);
        })
        .attr("y2", function (d) {
            return yScale(d.end[1]);
        })
        .attr("stroke-width", 2)
        .attr("stroke", "black");


    var elemNode = svg.selectAll("circle")
        .data(nodeData)
        .enter();

    var nodes = elemNode.append("circle")
        .attr("cx", function (d) {
            return xScale(parseInt(d.x));
        })
        .attr("cy", function (d) {
            return yScale(parseInt(d.y));
        })
        .attr({"r": rScale(RADIUS)})
        .style("fill", "yellow")
        .style("stroke", "black");

最佳答案

Mike Bostock 推荐implementing charts as reusable closures with methods .这将是您想要的理想实现

  • 具有不同数据的多个图表
  • 可能重新加载新数据(希望这就是您所说的动态?)

概括地说,您想做的是将上面的代码包装成一个函数,其方式与 Mike 在上面的帖子中描述的方式非常相似,然后让 data 成为闭包的属性.所以这里有一些被严重黑客攻击的代码:

// your implementation here
var chart = function(){...}

var graphData = d3.json('my/graphdata.json', function(error, data){
  // now you have your data
});

// let's say you have a div called graphs
var myGraphs = d3.select('.graphs')
  .data(graphData)
  .enter()
  .append('g')
  //now you have g elements for each of your datums in the graphData array

//we use the saved selection above and call the chart function on each of the elements in the selection
myGraphs.call(chart);

//note that internally in your `chart` closure, you have to take in a selection
//object and process it(data is already bound to each of your selections from above):
function chart(selection) {
    selection.each(function(data) {
//...

还有一些good reading on the topic .

关于javascript - 动态生成多个 d3 svg 图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32458325/

相关文章:

javascript - 将数组对象 block 合并到单个数组

javascript - pie() 不接受对象数组

javascript - 没有提交按钮的单选按钮

javascript - Backbone.js 模型事件未触发

Javascript 图像预加载,我做错了什么

javascript - 如果函数中的语句不起作用

javascript - D3 中的平滑递归转换

javascript - 嵌入应用程序时从 D3 Observable 中删除单元格

javascript - D3.js - 如何将时域乘以标量?

javascript - 线的点 x1、x2、y1、y2 与径向树中的节点不重合