【问题标题】:How to implement the html variables for a graphic from d3.js如何从 d3.js 实现图形的 html 变量
【发布时间】:2020-10-30 18:46:39
【问题描述】:

我想在 d3.js 中做一个圆环图。基本上这个想法是写 3 个输入,它应该以这种方式显示:

不幸的是我做不到,我不确定如何在 javascript 代码中实现变量fuel、fuel 2 和fuel 3,我不确定它是否必须在html 代码或javascript 代码中指示.提前致谢。


<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<div>
        <input type="number" id="fuel" style="text-align:center"> 
</div>  

<div>
        <input type="number" id="fuel2" style="text-align:center"> 
</div>  

<div>
        <input type="number" id="fuel3" style="text-align:center"> 
</div>  




<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>


var fuel = document.getElementById('fuel');
var fuel2 = document.getElementById('fuel2');
var fuel3 = document.getElementById('fuel3');



// set the dimensions and margins of the graph
var width = 450
    height = 450
    margin = 40

// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin

// append the svg object to the div called 'my_dataviz'
var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// Create dummy data
var data = {fuel,fuel2,fuel3}

// set the color scale
var color = d3.scaleOrdinal()
  .domain(data)
  .range(["#98abc5", "#8a89a6", "#7b6888"])

// Compute the position of each group on the pie:
var pie = d3.pie()
  .value(function(d) {return d.value; })
var data_ready = pie(d3.entries(data))

// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
svg
  .selectAll('whatever')
  .data(data_ready)
  .enter()
  .append('path')
  .attr('d', d3.arc()
    .innerRadius(100)         // This is the size of the donut hole
    .outerRadius(radius)
  )
  .attr('fill', function(d){ return(color(d.data.key)) })
  .attr("stroke", "black")
  .style("stroke-width", "2px")
  .style("opacity", 0.7)
``

【问题讨论】:

    标签: javascript html css d3.js


    【解决方案1】:

    这个答案使用 d3v6

    方法 1

    您可以使用数据数组来表示输入框和切片。这可能具有优势,尤其是从数据源加载图表时。尝试类似:

    // Date representing your slices:
    var data = [
      {name:"A",value:1},
      {name:"B",value:1},
      {name:"B",value:1}
    ];
    
    // Create the fields based on the data:
    d3.select("#my_inputs")
      .selectAll(null)
      .data(data)
      .enter()
      .append("input")
      .attr("value",function(d) { return d.value; })
      .on("keyup", function(_,d) { 
        d.value = d3.select(this).node().value;
        update();
      })
    

    在这里,我们创建一个数据数组来表示我们的输入字段和切片。我们将数据绑定到输入字段,并在每次字段值更改时更新绑定的数据。

    现在我们可以在每次值更改时更新图表,最初,使用如下函数:

    function update() {
    
      var pie = d3.pie()
        .value(function(d) {return d.value; })(data);
    
      svg
       .selectAll('path')
        .data(pie)
        .join('path') 
        .attr(.....
        
    }
    

    我在下面做了一些更改,因为我们需要注意,如果切片的数量是恒定的,则在第一次绘制切片后输入选择将为空。所以我使用selection.join() 虽然selection.merge() 单独处理更新和输入也可以。

    这两个在一起:

    var width = 450
        height = 450
        margin = 40
    
    var radius = Math.min(width, height) / 2 - margin
    
    // Date representing your slices:
    var data = [
      {name:"A",value:1},
      {name:"B",value:1},
      {name:"C",value:1}
    ];
    
    // Create the fields based on the data:
    d3.select("#my_inputs")
      .selectAll(null)
      .data(data)
      .enter()
      .append("input")
      .attr("value",function(d) { return d.value; })
      .on("keyup", function(_,d) { 
        d.value = d3.select(this).node().value;
        update();
      })
    
    // Create an SVG
    var svg = d3.select("#my_dataviz")
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    
    // set the color scale
    var color = d3.scaleOrdinal()
      .domain(data.map(function(d) { return d.name; }))
      .range(["#98abc5", "#8a89a6", "#7b6888"])
    
    update();
    
    function update() {
    
      // Compute the position of each group on the pie:
      var pie = d3.pie()
        .value(function(d) {return d.value; })(data);
    
    
      // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
      svg
       .selectAll('path')
        .data(pie)
        .join('path') 
        .attr('d', d3.arc()
          .innerRadius(100)        
          .outerRadius(radius)
        )
        .attr("stroke", "black")
        .style("stroke-width", "2px")
        .style("fill", function(d) { return color(d.data.name);})
        
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.0/d3.min.js"></script>
    <div id="my_inputs"></div>
    <div id="my_dataviz"></div>

    更进一步,通过一些调整,创建一个用户界面,用户可以在其中动态添加/删除饼图中的字段/切片并不困难,因为切片和字段都在数据数组中表示。

    方法 2

    或者,如果您想对输入字段进行硬编码,无论出于何种原因,您都可以一次选择它们并从中创建一个数据数组:

    var data = d3.selectAll("input").nodes();
    

    然后您可以像使用其他任何 D3 数据数组一样使用它。这不是一个选择, .nodes() 返回一个元素数组。您需要使用 .nodes,因为您需要一个数组才能正确使用输入/更新周期,而 D3 选择不是数组。

    我们像这样添加事件监听器:

    d3.selectAll("input")
      .on("keyup", function() { 
        update();
      })
    

    这更符合你最初的想法:

    var width = 450
        height = 450
        margin = 40
    
    var radius = Math.min(width, height) / 2 - margin
    
    // Add an event listener
    d3.selectAll("input")
      .on("keyup", function() { 
        update();
      })
    
    // Create an SVG
    var svg = d3.select("#my_dataviz")
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    
    // set the color scale
    var color =["#98abc5", "#8a89a6", "#7b6888"];
    
    update();
    
    function update() {
    
      var data = d3.selectAll("input").nodes();
    
      var pie = d3.pie()
        .value(function(d) {return d.value; })(data);
    
      svg
       .selectAll('path')
        .data(pie)
        .join('path') 
        .attr('d', d3.arc()
          .innerRadius(100)        
          .outerRadius(radius)
        )
        .attr('fill', function(d,i){ return color[i] })
        .attr("stroke", "black")
        .style("stroke-width", "2px")
        
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.0/d3.min.js"></script>
    <div id="my_inputs">
    <input value="1"></input>
    <input value="1"></input>
    <input value="1"></input>
    </div>
    <div id="my_dataviz"></div>

    【讨论】:

    • 简直太棒了。请问这个 var pie 是干什么用的?
    • 我将:var pie = d3.pie().value(function(d) {return d.value; }) var data_ready = pie(d3.entries(data)) 浓缩为:var pie = d3.pie().value(function(d) {return d.value; })(data),所以pie 替换了sn-ps 中的data_ready,我们仍然需要将它传递给selectAll().data()
    猜你喜欢
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    相关资源
    最近更新 更多