D3更新数据阵列

时间:2018-03-20 00:16:02

标签: javascript arrays d3.js

我想知道你是否可以帮我解决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}

];

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

拉​​夫

1 个答案:

答案 0 :(得分:0)

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

尝试如下所示 -

&#13;
&#13;
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
  });
&#13;
<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>
&#13;
&#13;
&#13;