【问题标题】:D3 How to change dataset based on drop down box selectionD3 如何根据下拉框选择更改数据集
【发布时间】:2014-06-12 20:44:16
【问题描述】:

我正在尝试根据下拉框选择来更新/更改矩形的数据。我尝试了各种方法,但我对 D3 调度功能的理解还不够好。感谢有人可以更新此代码,以便我可以看到它在实践中是如何工作的。我有 3 个带有值的数据集,我只是想根据用户在菜单栏中选择的内容来更新矩形尺寸。

非常感谢,

<!DOCTYPE html>

<html>
<head>
    <title>Menu Bar</title>
    <script type="text/javascript" src="d3/d3.js">
    </script>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">             

</head>
<body>

<select id = "opts">
<option value="ds1">data1</option>
<option value="ds2">data2</option> 
<option value="ds3">data3</option>
  <!-- and so on... -->   
  </select>     

<script type="text/javascript">

var w = 100,
    h = 100
;

var color = d3.scale.ordinal()
            .range(["#1459D9", "#daa520"]);


var ds1 = [[{x:0,y:12}],[{x:0,y:45}]];
var ds2 = [[{x:0,y:72}],[{x:0,y:28}]];
var ds3 = [[{x:0,y:82}],[{x:0,y:18}]];


var canvas = d3.select("body")
    .append("svg")
    .attr("width",100)
    .attr("height",100)        
;

var appending = canvas.selectAll("body")
    .data(ds2)   ///trying to make this selection dynamic based on menubar selection                         
    .enter()                    
    .append("g")
    .style("fill", function(d,i){return color(i);})
    ;

   appending.selectAll("shape")
    .data(function (d) {return d;})
    .enter()
    .append("rect")
    .attr("x",10)
    .attr("y",10)
    .attr("width",function (d) {return d.y;})
    .attr("height",19)
    ;


 </script>      
</body>
</html>

【问题讨论】:

    标签: javascript svg d3.js


    【解决方案1】:

    脚本的主要问题是 d3 代码只执行一次。当您有多个数据集时,每次更新数据时都必须调用 d3 模式(绑定、添加、更新、删除)。

    以下是您想要完成的内容的粗略概述:

    // config, add svg
    var canvas = d3.select('body')
        .append('svg')
        .attr('width',100)
        .attr('height',100) 
        .appeng('g');
    
    
    // function that wraps around the d3 pattern (bind, add, update, remove)
    function updateLegend(newData) {
    
        // bind data
        var appending = canvas.selectAll('rect')
           .data(newData);
    
        // add new elements
        appending.enter().append('rect');
    
        // update both new and existing elements
        appending.transition()
            .duration(0)
            .attr("width",function (d) {return d.y; });
    
        // remove old elements
        appending.exit().remove();
    
    }
    
    // generate initial legend
    updateLegend(initialValues);
    
    // handle on click event
    d3.select('#opts')
      .on('change', function() {
        var newData = eval(d3.select(this).property('value'));
        updateLegend(newData);
    });
    

    这是一个工作小提琴,演示了数据随选择的变化(可能需要根据您的需要进行调整):

    http://jsfiddle.net/spanndemic/5JRMt/

    【讨论】:

    • 在我使用 eval(d3.select(this).property('value')) 而不是 d3.select(this).property('value') 之前,我无法运行我的代码。感谢您的回复!
    • 我对您在这部分代码中添加的 cmets 有疑问:appending.transition().duration(0).attr("width",function (d) {return d.y; }); 您对此发表了评论 - //update existing elements 但是这不会更新现有元素和输入元素(因为您正在追加在此之前输入()选择)??
    • @VSharma 是正确的,它将更新现有元素和输入元素。我会更新评论。在实际项目中,最好将输入元素和现有元素分开,分别处理基于数据的任何更新(例如:新与更新的不同动画),然后合并两组并处理任何常见更新(例如:大小基于数据值)......不过,这个解决方案仍然适用于 OP。
    猜你喜欢
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 2016-10-29
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多