多个折线图直接附加路径

时间:2019-05-11 04:20:24

标签: javascript d3.js

我想绘制多个折线图。我直接附加路径。 不过,它会引发错误:

  

“错误:解析d =“ MNaN,253.83 ...时出现问题”

此错误发生在.attr("d", line)上。

在追加之前解析数据。而且我已经使用调试器检查了数据,这没有错。

这是我的代码:

<body style="overflow: hidden;height: 100%;">
    <script>

    // ===========================================================

    let x, y;
    let Line_chart;
    let xAxis, yAxis;
    let xAxisSub;
    let line;
    let focus;
    let svg;
    let width, hwight, aspect;
    let xAxisGrid;
    let parseTime = d3.timeParse("%H:%M:%SZ");
    var rect;


    let orgData = [
        [
            {"logtime":"15:01:38Z","Param":"10.0"},
            {"logtime":"15:01:39Z","Param":"11.0"},
            {"logtime":"15:01:40Z","Param":"12.0"},
            {"logtime":"15:01:41Z","Param":"13.0"},
            {"logtime":"15:01:42Z","Param":"14.0"}
        ],
        [
            {"logtime":"15:01:38Z","Param":"0.0"},
            {"logtime":"15:01:39Z","Param":"1.0"},
            {"logtime":"15:01:40Z","Param":"2.0"},
            {"logtime":"15:01:41Z","Param":"3.0"},
            {"logtime":"15:01:42Z","Param":"4.0"}
        ],
        [
            {"logtime":"15:01:38Z","Param":"4.0"},
            {"logtime":"15:01:39Z","Param":"5.0"},
            {"logtime":"15:01:40Z","Param":"6.0"},
            {"logtime":"15:01:41Z","Param":"7.0"},
            {"logtime":"15:01:42Z","Param":"8.0"}
        ]
    ];





    function initSVG(divid, _width, _height) {

        let margin = { top: 30, right: 30, bottom: 50, left: 80 };
        width = document.getElementById("graph").clientWidth; //-margin.left - margin.right;
        height = document.getElementById("graph").clientWidth * (_height / _width);

        aspect = _width / _height;

        var cWidth = width + margin.left + margin.right,
            cHeight = height - margin.top - margin.bottom;

        svg = d3.select("#" + divid)
            .append("svg")
            .attr("width", width).attr("height", width * aspect)
            .attr("viewBox", "0 0 " + cWidth + " " + cHeight + "")
            .attr("preserveAspectRatio", "xMinYMin meet");

        x = d3.scaleTime().range([0, width])
        y = d3.scaleLinear().range([height, 0]);

        focus = svg.append("g")
            .attr("class", "focus")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        xAxis = d3.axisBottom(x)
            .tickFormat(d3.timeFormat('%H:%M'))
            .tickSize(-height, 0)
            .tickPadding(5)
            .ticks(6);

        yAxis = d3.axisLeft(y)
            .ticks(6);

        line = d3.line()
            .defined(function(d) { return d.time != null; })
            .x(function(d) { return x(d.time); })
            .y(function(d) { return y(d.val); });

        Line_chart = svg.append("g")
            .attr("class", "focus")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr("clip-path", "url(#clip)");
    }

    // ===========================================================


    function bindData() {

        var parameter="Param";

        let tmp = [];
        let data = [];
        let myData =[];

        let yMax = 15;
        let yMin = 0;

        var duration = 0;
        var nullObj = [];
        nullObj["Time"] = null;

        for (let i = 0; i < orgData.length; i++) {
            myData[i]=[];
            tmp = orgData[i];

            for (let j = 0; j < tmp.length; j++) {
                if (tmp[j][parameter]) {
                    let obj = {};
                    obj["time"] =parseTime(tmp[j].logtime);
                    obj["val"] = tmp[j][parameter];
                    myData[i].push(obj);
                }
            }
        }
        let xScale = d3.scaleBand()
            .domain(data.map(function(d) { return d.time; }));

        let yScale = d3.scaleLinear()
            .domain([yMin, yMax])
            .range([height, 0]);

        x.domain(d3.extent(myData, function(d) { return d.time; })).nice(); 
        y.domain([yMin, yMax]);

        var h = height;
        focus.append("g")
            .attr("class", ".x.axis axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        focus.append("g")
            .attr("class", "axis axis--y")
            .call(yAxis);

        for (let i = 0; i < myData.length; i++) {
            Line_chart.append("path")
                .datum(myData[i])
                .attr("class", "line" + i)
                .attr("d", line)
                .attr("fill", "none")
                .attr("stroke", d3.schemeCategory10[i])
                .attr("stroke-width", 1.8)
                .attr("stroke-linejoin", "round")
                .attr("stroke-linecap", "round");

        }
    }

    // ===========================================================

    </script>
    <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
    <div id="graph" class="svg-container" style="background-color:#ffffff; ">
        <script>

        initSVG("graph", 300, 150);
       bindData();
        </script>
    </div>

</body>

我希望图表上有三行。你能让我知道怎么了吗?

1 个答案:

答案 0 :(得分:1)

您的域计算...

x.domain(d3.extent(myData, function(d) { return d.time; })).nice();

...不正确,因为您有一个数组数组,而不仅仅是平面数组。

有几种方法可以展平数组。例如:

x.domain(d3.extent(myData.reduce(function(a, c) {
    return a.concat(c);
  }, []), function(d) {
    return d.time;
  })).nice();

这是您所做的更改的代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<body style="overflow: hidden;height: 100%;">
  <script>
    // ===========================================================

    let x, y;
    let Line_chart;
    let xAxis, yAxis;
    let xAxisSub;
    let line;
    let focus;
    let svg;
    let width, hwight, aspect;
    let xAxisGrid;
    let parseTime = d3.timeParse("%H:%M:%SZ");
    var rect;

    let orgData = [
      [{
          "logtime": "15:01:38Z",
          "Param": "10.0"
        },
        {
          "logtime": "15:01:39Z",
          "Param": "11.0"
        },
        {
          "logtime": "15:01:40Z",
          "Param": "12.0"
        },
        {
          "logtime": "15:01:41Z",
          "Param": "13.0"
        },
        {
          "logtime": "15:01:42Z",
          "Param": "14.0"
        }
      ],
      [{
          "logtime": "15:01:38Z",
          "Param": "0.0"
        },
        {
          "logtime": "15:01:39Z",
          "Param": "1.0"
        },
        {
          "logtime": "15:01:40Z",
          "Param": "2.0"
        },
        {
          "logtime": "15:01:41Z",
          "Param": "3.0"
        },
        {
          "logtime": "15:01:42Z",
          "Param": "4.0"
        }
      ],
      [{
          "logtime": "15:01:38Z",
          "Param": "4.0"
        },
        {
          "logtime": "15:01:39Z",
          "Param": "5.0"
        },
        {
          "logtime": "15:01:40Z",
          "Param": "6.0"
        },
        {
          "logtime": "15:01:41Z",
          "Param": "7.0"
        },
        {
          "logtime": "15:01:42Z",
          "Param": "8.0"
        }
      ]
    ];





    function initSVG(divid, _width, _height) {

      let margin = {
        top: 30,
        right: 30,
        bottom: 50,
        left: 80
      };
      width = document.getElementById("graph").clientWidth; //-margin.left - margin.right;
      height = document.getElementById("graph").clientWidth * (_height / _width);

      aspect = _width / _height;

      var cWidth = width + margin.left + margin.right,
        cHeight = height - margin.top - margin.bottom;

      svg = d3.select("#" + divid)
        .append("svg")
        .attr("width", width).attr("height", width * aspect)
        .attr("viewBox", "0 0 " + cWidth + " " + cHeight + "")
        .attr("preserveAspectRatio", "xMinYMin meet");

      x = d3.scaleTime().range([0, width])
      y = d3.scaleLinear().range([height, 0]);

      focus = svg.append("g")
        .attr("class", "focus")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

      xAxis = d3.axisBottom(x)
        .tickFormat(d3.timeFormat('%H:%M'))
        .tickSize(-height, 0)
        .tickPadding(5)
        .ticks(6);

      yAxis = d3.axisLeft(y)
        .ticks(6);

      line = d3.line()
        .defined(function(d) {
          return d.time != null;
        })
        .x(function(d) {
          return x(d.time);
        })
        .y(function(d) {
          return y(d.val);
        });

      Line_chart = svg.append("g")
        .attr("class", "focus")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
        .attr("clip-path", "url(#clip)");
    }

    // ===========================================================


    function bindData() {

      var parameter = "Param";

      let tmp = [];
      let data = [];
      let myData = [];

      let yMax = 15;
      let yMin = 0;

      var duration = 0;
      var nullObj = [];
      nullObj["Time"] = null;

      for (let i = 0; i < orgData.length; i++) {
        myData[i] = [];
        tmp = orgData[i];

        for (let j = 0; j < tmp.length; j++) {
          if (tmp[j][parameter]) {
            let obj = {};
            obj["time"] = parseTime(tmp[j].logtime);
            obj["val"] = tmp[j][parameter];
            myData[i].push(obj);
          }
        }
      }
      let xScale = d3.scaleBand()
        .domain(data.map(function(d) {
          return d.time;
        }));

      let yScale = d3.scaleLinear()
        .domain([yMin, yMax])
        .range([height, 0]);

      x.domain(d3.extent(myData.reduce(function(a, c) {
        return a.concat(c);
      }, []), function(d) {
        return d.time;
      })).nice();
      y.domain([yMin, yMax]);

      var h = height;
      focus.append("g")
        .attr("class", ".x.axis axis axis--x")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

      focus.append("g")
        .attr("class", "axis axis--y")
        .call(yAxis);

      for (let i = 0; i < myData.length; i++) {
        Line_chart.append("path")
          .datum(myData[i])
          .attr("class", "line" + i)
          .attr("d", line)
          .attr("fill", "none")
          .attr("stroke", d3.schemeCategory10[i])
          .attr("stroke-width", 1.8)
          .attr("stroke-linejoin", "round")
          .attr("stroke-linecap", "round");

      }
    }

    // ===========================================================
  </script>
  <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
  <div id="graph" class="svg-container" style="background-color:#ffffff; ">
    <script>
      initSVG("graph", 300, 150);
      bindData();
    </script>
  </div>

</body>

PS:您的代码中还有其他几个问题,最重要的一个问题是使用for循环来附加元素。根据经验,不要在D3代码中这样做。