【问题标题】:D3 Updating a data arrayD3 更新数据数组
【发布时间】:2018-03-20 00:16:02
【问题描述】:

我想知道你是否可以帮助我了解 D3 中的一般更新模式...

我正在尝试将一个非常基本的数据数组显示为条形图,并使用输入表单将新数据添加到数组并在图表上动态更新。

有很多重复,因为我正在尝试重构向 svg 添加新矩形的过程,但没有任何运气......

如果有人可以向我解释我如何将一个新对象放入数据数组中,然后刷新 svg,那就太好了。我希望这个问题也符合版主指南...

到目前为止,这是我的代码:

app.js:

// set a width and height for the svg

var height = 500;
var width = 1000;
var barPadding = 10;
var barWidth = width / data.length - barPadding;

var maxPoints = d3.max(data, function(d){
    return d.score;
});

var myScale = d3.scaleLinear()
    .domain([0, maxPoints])
    .range([height, 0]);


var svg = d3.select('svg')
    .attr("height", height) //setting the height 
    .attr("width", width) // setting the width
    .style("display", "block") // svgs are inline, hence needs to be block
    .style("margin", "100px auto") // centering
    .selectAll("rect") // creating nodes 
    .data(data) // binds data to the nodes
    .enter() // goes into the enter selection
    .append("rect") 
        .attr("width", barWidth) 
        .attr("height", function(d){
            return height - myScale(d.score);
        })
        .attr("x", function(d, i){
            return (barWidth + barPadding) * i;
        })
        .attr("y", function(d, i){
            return myScale(d.score);
        })

        .attr("fill", "green");

// INPUT NEW DATA

var nameInput = "input[name='name']";
var scoreInput = "input[name='score']";

function addRect(){
    barWidth = width / data.length - barPadding;
    svg
    .append("rect") 
        .attr("height", function(d){
            return height - myScale(d.score);
        })

        .attr("x", function(d, i){
            return (barWidth + barPadding) * i;
        })

        .attr("y", function(d, i){
            return myScale(d.score);
        })

        .attr("fill", "green");
};


d3.select("form")
    .on("submit", function() {
        d3.event.preventDefault();
        var firstInput = d3.select(nameInput)
            .property("value");
        var secondInput = d3.select(scoreInput)
            .property("value");
        data.push({player: firstInput, score: secondInput });
        console.log(data);

        svg
            .data(data)
            .enter();
            addRect();
    });

html:

 <body>
    <div class="display">
        <svg 
        version="1.1"
        baseProfile="full"
        xmlns="http://www.w3.org/2000/svg"
        id="letters">
    </svg>
</div>
<div class="form">
    <form action="">
        <input type="text" placeholder="Name" name="name">
        <input type="text" placeholder="Score" name="score">
        <input type="submit">
    </form>
</div>


<script src="https://d3js.org/d3.v4.js"></script>
<script src="data.js"></script>
<script src="app.js"></script>
</body>

data.js:

var data = [
    {player: "Raph", score: 12},
    {player: "Henry", score: 43},
    {player: "James", score: 29},
    {player: "Andrew", score: 200},
    {player: "Ella", score: 87},
    {player: "Bob", score: 3},
    {player: "Lil", score: 19},
    {player: "Jenny", score: 223},
    {player: "Dad", score: 33},
    {player: "Rhys", score: 45}

];

非常感谢您提前提供的任何帮助,

拉夫

【问题讨论】:

    标签: javascript arrays d3.js


    【解决方案1】:

    在添加新矩形时,您还必须更新现有矩形的属性。

    如下图试试——

    var data = [
        {player: "Raph", score: 12},
        {player: "Henry", score: 43},
        {player: "James", score: 29},
        {player: "Andrew", score: 200},
        {player: "Ella", score: 87},
        {player: "Bob", score: 3},
        {player: "Lil", score: 19},
        {player: "Jenny", score: 223},
        {player: "Dad", score: 33},
        {player: "Rhys", score: 45}
    
    ];
    // set a width and height for the svg
    var height = 200;
    var width = 400;
    var barPadding = 10;
    var barWidth = width / data.length - barPadding;
    
    var maxPoints = d3.max(data, function(d) {
      return d.score;
    });
    
    var myScale = d3.scaleLinear()
      .domain([0, maxPoints])
      .range([height, 0]);
    
    var svg = d3.select("svg")
      .attr("height", height)
      .attr("width", width)
      .style("display", "block")
      .style("margin", "10px 0px"); //changed for look and feel
      //.style("margin", "100px auto");
    
    drawRect(); //Creating rects
    
    //Moved the code to create rectangles and style into a function.
    function drawRect() {
      var rect = svg
        .selectAll("rect")
        .data(data)
        .enter()
        .append("rect");
    
      svg
        .selectAll("rect")
        .attr("width", barWidth)
        .attr("height", function(d) {
          return height - myScale(d.score);
        })
        .attr("x", function(d, i) {
          return (barWidth + barPadding) * i;
        })
        .attr("y", function(d, i) {
          return myScale(d.score);
        })
        .attr("fill", "green");
    }
    
    // INPUT NEW DATA
    var nameInput = "input[name='name']";
    var scoreInput = "input[name='score']";
    
    d3.select("form")
      .on("submit", function() {
        d3.event.preventDefault();
        var firstInput = d3.select(nameInput)
          .property("value");
        var secondInput = d3.select(scoreInput)
          .property("value");
        data.push({
          player: firstInput,
          score: secondInput
        });
        barWidth = width / data.length - barPadding;
        drawRect(); //Adding new rects and update others
      });
    <script src="https://d3js.org/d3.v4.js"></script>
    
    <body>
      <div class="display">
        <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" id="letters">
        </svg>
      </div>
      <div class="form">
        <form action="">
          <input type="text" placeholder="Name" name="name">
          <input type="text" placeholder="Score" name="score">
          <input type="submit">
        </form>
      </div>
    
    </body>

    【讨论】:

    • 很高兴它有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2018-08-03
    • 2015-02-20
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    相关资源
    最近更新 更多