代码之家  ›  专栏  ›  技术社区  ›  Datacrawler

在调整大小时重新创建D3多折线图(响应)

  •  0
  • Datacrawler  · 技术社区  · 7 年前

    为了有一个响应性的D3多折线图,我添加了一个调整大小的函数,但它似乎不起作用,尽管调用了该函数:

      var data = [{
        Date: "2016-10-10",
        ValueOne: 1,
        ValueTwo: 0
      }, {
        Date: "2016-10-17",
        ValueOne: 23,
        ValueTwo: 2
      }, {
        Date: "2016-10-24",
        ValueOne: 32,
        ValueTwo: 17
      }, {
        Date: "2016-10-31",
        ValueOne: 57,
        ValueTwo: 40
      }, {
        Date: "2016-11-07",
        ValueOne: 74,
        ValueTwo: 56
      }];
    
    
    var  margin = {top: 10, right: 50, bottom: 100, left: 50},
    // Set default width and height
        widther = (window.innerWidth),
        width = widther - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;
    
        
    // Determine current size, which determines vars
    function set_vars() {
    
        var width = window.innerWidth - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;
            
    }
    
    function drawGraphic() {
    
        var svg = d3.select('#charts')
          .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 + ")");
    
        //Parses date for correct time format
        var formatTime = d3.timeFormat("%Y-%m-%d");
    
        data.forEach(function(d) {
          d.Date = new Date(d.Date)
        });
    
        var valueOneData = data.map(function(d) {
          return {
            date: d.Date,
            value: d.ValueOne
          }
        });
    
        var valueTwoData = data.map(function(d) {
          return {
            date: d.Date,
            value: d.ValueTwo
          }
        });
    
        var xScale = d3.scaleTime()
          .range([0, width])
          .domain(d3.extent(data, function(d) {
            return d.Date
          }));
    
        var yScale = d3.scaleLinear()
          .range([height, 0])
          .domain([0, d3.max(data, function(d) {
            return d.ValueOne
          }) * 1.05]);
    
        var lineGenerator = d3.line()
          .x(function(d) {
            return xScale(d.date)
          })
          .y(function(d) {
            return yScale(d.value)
          });
    
        var gX = svg.append("g")
          .attr("transform", `translate(0,${height})`)
          .call(d3.axisBottom(xScale).tickFormat(function(d) {
            return formatTime(d)
          }).tickValues(data.map(function(d) {
            return d.Date
          })))
          .selectAll("text")
          .style("text-anchor", "end")
          .attr("transform", "rotate(-65)")
          .attr("y", 4)
          .attr("x", -10)
          .attr("dy", ".35em");
    
        var gY = svg.append("g")
          .call(d3.axisLeft(yScale));
    
        var valueOneLine = svg.append("path")
          .datum(valueOneData)
          .attr("d", lineGenerator)
          .style("fill", "none")
          .style("stroke", "#124");
    
        var valueTwoLine = svg.append("path")
          .datum(valueTwoData)
          .attr("d", lineGenerator)
          .style("fill", "none")
          .style("stroke", "#c7003b");
    
      //RESPONSIVENESS ATTEMPT NO1
      d3.select(window).on("resize", resized);
    
    }
    
    //Resize function
    function resized() {
        d3.select("svg").remove();
        set_vars();
        drawGraphic();
        console.log("FUNCTION IS BEING CALLED")
    }
    
    set_vars();
    drawGraphic();
    
     //RESPONSIVENESS ATTEMPT NO2
     window.addEventListener("resize", function(){ d3.select("svg").remove(); set_vars(); drawGraphic(); });
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <div id="charts"></div>

    在这个片段中,我尝试了两种方法。它们都不能让图表从头开始重新创建。同样的问题也适用于这一领域 jsfiddle .

    1 回复  |  直到 7 年前
        1
  •  1
  •   Shashank    7 年前

    问题在于每次调整窗口大小时对数据的解析。

    日期 在第一次解析数据时,调用 parseDate(d.date) 将在每次调用时失败,因为它已被解析为有效日期。你明白了吗?

    // parse data just once
    data.forEach(function(d) {
      d.date = parseDate(d.date);
      d.value = +d.value;
    });
    

    小提琴链接: https://jsfiddle.net/a5rqt0L1/

    建议:

    1. 就一次 但是移动 drawBars 进入、退出和更新 选择逻辑。
    2. .call(xAxis)... 打电话给警察就行了 功能。