Как исправить проблему с отображением на многострочном графике. svg.append («путь») ничего не отображает

#d3.js #data-visualization

#d3.js #данные-визуализация

Вопрос:

Я пытаюсь создать многострочный график для моего веб-приложения angular, чтобы визуализировать некоторые данные, которые будут добавлять строки в соответствии с элементами в переменной data. Поскольку я пытаюсь добавить строку path в элемент svg, мне не удается ее отобразить. Прямо сейчас корректно отображаются только две оси.

     var margin = {
        top: 20,
        right: 80,
        bottom: 30,
        left: 50
      },
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    var x = d3.scaleTime().domain([new Date(2000, 0, 0), new Date(2017, 0, 0)]).range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);

    var svg = d3.select(this.htmlElement).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   ")");


    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0,"   height   ")")
      .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%Y")).ticks(d3.timeYear, 1));

    // Add the Y Axis 
    svg.append("g")
      .call(d3.axisLeft(y))
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end");

    // define the line
    var line = d3.line()
      .x(function(d) {
        return d.name;
      })
      .y(function(d) {
        return d.value;
      });

    data.forEach(function(d) {
      svg.append("path")
        .attr("class", "line")
        .attr('d', line(d.series))
        .attr('stroke', 'blue')
        .attr('stroke-width', 2)
        .attr('fill', 'none');
    });

  

структура данных такая

 var data = [{
      "key": "Germany",
      "series": [
        {
          "a": "Germany",
          "name": "2010",
          "value": 0.2
        },
        {
          "a": "Germany",
          "name": "2011",
          "value": 0.5
        }
      ]
    }, {
      "key": "uk",
      "series": [
        {
          "a":"uk",
          "name": "2010",
          "value": 0.3
        },
        {
          "a":"uk",
          "name": "2011",
          "value": 0.6
        }
      ]
    }];
  

я предполагаю, что проблема заключается в цикле data.foreach, но мне не удается его найти.

Комментарии:

1. Вы не используете свои шкалы в генераторе строк. Т.Е. вместо этого .x(function(d) { return d.name; }) должно быть .x(function(d) { return x(d.name); }) (аналогично для .y() части).

2. В дополнение к исправлениям @matthias.rocks, вы также не устанавливаете .domain в своей y-шкале.

3. Подождите, вам также необходимо преобразовать год, сохраненный в name свойствах, иначе scaleTime D3 интерпретирует его как временную метку (т. Е. через несколько секунд после эпохи). Что-то вроде .x(function(d) { return x(new Date(d.name, 0)); }) должно сработать.

4. @Mark True действительно — хороший улов.

5. да, спасибо, это были проблемы, я опубликовал рабочий код в качестве ответа ниже.

Ответ №1:

согласно комментариям выше, рабочий код можно увидеть ниже

       var margin = {
        top: 20,
        right: 80,
        bottom: 30,
        left: 50
      },
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    var x = d3.scaleTime().domain([new Date(2000, 0, 0), new Date(2017, 0, 0)]).range([0, width]);
    var y = d3.scaleLinear().domain([0,1]).range([height, 0]);

    var svg = d3.select(this.htmlElement).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   ")");


    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0,"   height   ")")
      .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%Y")).ticks(d3.timeYear, 1));

    // Add the Y Axis 
    svg.append("g")
      .call(d3.axisLeft(y))
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end");

    // define the line
    var line = d3.line()
      .x(function(d) { 
        return x(new Date(d.name, 0)); 
      })
      .y(function(d) {
        return y(d.value);
      });

    data.forEach(function(d) {
      svg.append("path")
        .attr("class", "line")
        .attr('d', line(d.series))
        .attr('stroke', 'blue')
        .attr('stroke-width', 2)
        .attr('fill', 'none');
    });