2017-07-19 75 views
0

我跟D3版本4力试验向图,并看着吉姆Vallandingham的教程和代码为出发点。力向图中d3v4

http://vallandingham.me/bubble_chart_v4/

和我试图从内森悠

https://flowingdata.com/2016/08/23/make-a-moving-bubbles-chart-to-show-clustering-and-distributions/

我剥去吉姆Vallandingham的代码气泡图什么,我想我需要在这里产生类似的例子动画并且可以通过改变指标值显示各个州,但由于某些原因的代码不想要的不同状态之间进行动画处理。我想重绘功能无法正常工作。这可能是一个明显的错误,或者通过一个完全不知道做,但是如果你能帮助将是巨大的。

这里是我的代码:

function bubbleChart() { 
    var width = 940; 
    var height = 600; 
    var center = { x: width/2, y: height/3 }; 

    var years = ["0","2008", "2009", "2010"]; 

    var yearCenters = { 
    2008: { x: width/3, y: 2 * height/3 }, 
    2009: { x: width/2, y: 2 * height/3 }, 
    2010: { x: 2 * width/3, y: 2 * height/3 } 
    }; 

    // @v4 strength to apply to the position forces 
    var forceStrength = 0.03; 

    // These will be set in create_nodes and create_vis 
    var svg = null; 
    var bubbles = null; 
    var nodes = []; 
    var index= 0; 

    function charge(d) { 
    return -Math.pow(d.radius, 2.3) * forceStrength; 
    } 

    // Here we create a force layout 
    var simulation = d3.forceSimulation() 
    .velocityDecay(0.2) 
    .force('x', d3.forceX().strength(forceStrength).x(center.x)) 
    .force('y', d3.forceY().strength(forceStrength).y(center.y)) 
    .force('charge', d3.forceManyBody().strength(charge)) 
    .on('tick', ticked); 

    // @v4 Force starts up automatically, which we don't want as there aren't any nodes yet. 
    simulation.stop(); 

    // Nice looking colors 
    var fillColor = d3.scaleOrdinal() 
    .domain(['low', 'medium', 'high']) 
    .range(['#d84b2a', '#beccae', '#7aa25c']); 

    function createNodes(rawData) { 
    var myNodes = rawData.map(function (d) { 
     return { 
     id: d.id, 
     radius: 5, 
     value: +d.total_amount, 
     name: d.grant_title, 
     org: d.organization, 
     group: d.group, 
     year: d.start_year, 
     x: Math.random() * 900, 
     y: Math.random() * 800 
     }; 
    }); 

    // sort them to prevent occlusion of smaller nodes. 
    myNodes.sort(function (a, b) { return b.value - a.value; }); 

    return myNodes; 
    } 

    /* 
    * Main entry point to the bubble chart. 
    */ 
    var chart = function chart(selector, rawData) { 
    // convert raw data into nodes data 
    nodes = createNodes(rawData); 

    // Create a SVG element inside the provided selector 
    // with desired size. 
    svg = d3.select(selector) 
     .append('svg') 
     .attr('width', width) 
     .attr('height', height); 

    // Bind nodes data to what will become DOM elements to represent them. 
    bubbles = svg.selectAll('.bubble') 
     .data(nodes, function (d) { return d.id; }); 

    // Create new circle elements each with class `bubble`. 
    // There will be one circle.bubble for each object in the nodes array. 
    // Initially, their radius (r attribute) will be 0. 
    // @v4 Selections are immutable, so lets capture the 
    // enter selection to apply our transtition to below. 
    var bubblesE = bubbles.enter().append('circle') 
     .classed('bubble', true) 
     .attr('r', 0) 
     .attr('fill', function (d) { return fillColor(d.group); }) 
     .attr('stroke', function (d) { return d3.rgb(fillColor(d.group)).darker(); }) 
     .attr('stroke-width', 2) 

    // @v4 Merge the original empty selection and the enter selection 
    bubbles = bubbles.merge(bubblesE); 

    // Fancy transition to make bubbles appear, ending with the 
    // correct radius 
    bubbles.transition() 
     .duration(2000) 
     .attr('r', function (d) { return d.radius; }); 

    // Set the simulation's nodes to our newly created nodes array. 
    // @v4 Once we set the nodes, the simulation will start running automatically! 
    simulation.nodes(nodes); 

    chart.redraw(); 
    }; 

    // Callback function that is called after every tick of the force simulation. 
    // These x and y values are modified by the force simulation. 
    function ticked() { 
    bubbles 
     .attr('cx', function (d) { return d.x; }) 
     .attr('cy', function (d) { return d.y; }); 
    } 

    chart.redraw = function (index){ 
    simulation.force('x', d3.forceX().strength(forceStrength).x(nodePosX)); 
    simulation.force('y', d3.forceY().strength(forceStrength).y(nodePosY)); 
    simulation.alpha(1).restart(); 
    } 

    function nodePosX(d) { 
    if (+d.year <= +years[index]) { 
     return yearCenters[d.year].x; 
    } else { 
     return center.x; 
    } 
    } 
    function nodePosY(d) { 
    if (+d.year <= +years[index]) { 
     return yearCenters[d.year].y; 
    } else { 
     return center.y; 
    } 
    } 

    // return the chart function from closure. 
    return chart; 
} 

var myBubbleChart = bubbleChart(); 

myBubbleChart('#vis', data); 

for (i=0;i<4;i++){ 
    setInterval(function(){myBubbleChart.redraw(i);}, 100); 
} 
+1

你能创建一个可运行的计算器片段?这将会使你更容易看到发生了什么事情? – Ian

回答

0

我误解了如何用setInterval来重新绘制图表,所以应该如下:

var i = 0; 
setInterval(function(){myBubbleChart.redraw(i++);}, 1000);