微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在d3折线图中显示多条线?

如何解决如何在d3折线图中显示多条线?

我希望在d3折线图中绘制多条线,并用动画过渡每条线。这是一个工作示例,但一次只显示1行。

https://www.d3-graph-gallery.com/graph/line_change_data.html

我正在尝试将其扩展为同时显示多行。然后,当单击“数据集2”按钮时,它将显示一组新的行,并转换每行。我的尝试是here

// Create 2 datasets
var data1 = [
  [{
      ser1: 0.3,ser2: 4
    },{
      ser1: 2,ser2: 16
    },{
      ser1: 3,ser2: 8
    }
  ],[{
      ser1: 1,ser2: 7
    },{
      ser1: 4,ser2: 1
    },{
      ser1: 6,ser2: 8
    }
  ]
];

var data2 = [
  [{
      ser1: 4,ser2: 5
    },ser2: 3
    }
  ],ser2: 10
    },{
      ser1: 5,ser2: 8
    },{
      ser1: 7,ser2: 3
    }
  ]
];

// set the dimensions and margins of the graph
var margin = {
    top: 10,right: 30,bottom: 30,left: 50
  },width = 460 - margin.left - margin.right,height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width",width + margin.left + margin.right)
  .attr("height",height + margin.top + margin.bottom)
  .append("g")
  .attr("transform","translate(" + margin.left + "," + margin.top + ")");

// Initialise a X axis:
var x = d3.scaleLinear().range([0,width]);
var xAxis = d3.axisBottom().scale(x);
svg.append("g")
  .attr("transform","translate(0," + height + ")")
  .attr("class","myXaxis")

// Initialize an Y axis
var y = d3.scaleLinear().range([height,0]);
var yAxis = d3.axisLeft().scale(y);
svg.append("g")
  .attr("class","myYaxis")

// Create a function that takes a dataset as input and update the plot:
function update(data) {

  // Create the X axis:
  x.domain([0,d3.max(data,function(d) {
    return d3.max(d,function(d) {
      return d.ser1;
    });
  })]);
  svg.selectAll(".myXaxis").transition()
    .duration(3000)
    .call(xAxis);

  // create the Y axis
  y.domain([0,function(d) {
      return d.ser2;
    });
  })]);
  svg.selectAll(".myYaxis")
    .transition()
    .duration(3000)
    .call(yAxis);

  data.forEach(function(data,i) {

    // Create a update selection: bind to the new data
    var u = svg.selectAll(`.lineTest${i}`)
      .data([data],function(d) {
        return d.ser1
      });

    // Update the line
    u
      .enter()
      .append("path")
      .attr("class",`.lineTest${i}`)
      .merge(u)
      .transition()
      .duration(3000)
      .attr("d",d3.line()
        .x(function(d) {
          return x(d.ser1);
        })
        .y(function(d) {
          return y(d.ser2);
        }))
      .attr("fill","none")
      .attr("stroke","steelblue")
      .attr("stroke-width",2.5);

  });
}

// At the beginning,I run the update function on the first dataset:
update(data1);
<script src="https://d3js.org/d3.v5.min.js"></script>

<!-- Add 2 buttons -->
<button onclick="update(data1)">Dataset 1</button>
<button onclick="update(data2)">Dataset 2</button>

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

但是问题是,当我单击“数据集2”按钮时,它会绘制新行,仍然显示旧行,并且它们之间没有过渡。

有人知道这是怎么回事吗?

谢谢

解决方法

一些注意事项:

  1. 正如@Ryan Morton指出的那样,只需将整个行集传递​​给d3,其余的就由它来处理。不需要forEach;
  2. 您使用了attr('class','.lineTest'),但这给了它一个以点开头的类。这使得无法使用d3.select('.lineTest')进行选择。删除固定的点;
  3. 由于键函数选择了d.ser1,但是d是对象数组,因此ser1是未定义的。我将键功能更新为只使用索引。

// Create 2 datasets
var data1 = [
  [{
      ser1: 0.3,ser2: 4
    },{
      ser1: 2,ser2: 16
    },{
      ser1: 3,ser2: 8
    }
  ],[{
      ser1: 1,ser2: 7
    },{
      ser1: 4,ser2: 1
    },{
      ser1: 6,ser2: 8
    }
  ]
];

var data2 = [
  [{
      ser1: 4,ser2: 5
    },ser2: 3
    }
  ],ser2: 10
    },{
      ser1: 5,ser2: 8
    },{
      ser1: 7,ser2: 3
    }
  ]
];

// set the dimensions and margins of the graph
var margin = {
    top: 10,right: 30,bottom: 30,left: 50
  },width = 460 - margin.left - margin.right,height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width",width + margin.left + margin.right)
  .attr("height",height + margin.top + margin.bottom)
  .append("g")
  .attr("transform","translate(" + margin.left + "," + margin.top + ")");

// Initialise a X axis:
var x = d3.scaleLinear().range([0,width]);
var xAxis = d3.axisBottom().scale(x);
svg.append("g")
  .attr("transform","translate(0," + height + ")")
  .attr("class","myXaxis")

// Initialize an Y axis
var y = d3.scaleLinear().range([height,0]);
var yAxis = d3.axisLeft().scale(y);
svg.append("g")
  .attr("class","myYaxis")

// Create a function that takes a dataset as input and update the plot:
function update(data) {

  // Create the X axis:
  x.domain([0,d3.max(data,function(d) {
    return d3.max(d,function(d) {
      return d.ser1;
    });
  })]);
  svg.selectAll(".myXaxis").transition()
    .duration(3000)
    .call(xAxis);

  // create the Y axis
  y.domain([0,function(d) {
      return d.ser2;
    });
  })]);
  svg.selectAll(".myYaxis")
    .transition()
    .duration(3000)
    .call(yAxis);

  // Create a update selection: bind to the new data
  var lines = svg.selectAll(`.lineTest`)
    .data(data,function(d,i) {
      return i;
    });

  lines.exit()
    .remove();

  // Update the line
  lines.enter()
    .append("path")
    .attr("class","lineTest")
    .merge(lines)
    .transition()
    .duration(3000)
    .attr("d",d3.line()
      .x(function(d) {
        return x(d.ser1);
      })
      .y(function(d) {
        return y(d.ser2);
      }))
    .attr("fill","none")
    .attr("stroke","steelblue")
    .attr("stroke-width",2.5);
}

// At the beginning,I run the update function on the first dataset:
update(data1);
<script src="https://d3js.org/d3.v5.min.js"></script>

<!-- Add 2 buttons -->
<button onclick="update(data1)">Dataset 1</button>
<button onclick="update(data2)">Dataset 2</button>

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?