无法显示折线图的较小倍数

时间:2019-06-20 06:01:45

标签: javascript d3.js graph line

我想使多个折线图看起来像Mike Bostock的设计(https://bl.ocks.org/mbostock/1157787)。

我觉得我的代码合适,但是没有折线图出现。 HTML元素和类出现(“ svg”,“ g”,“ line”和“ path”)。当我从chrome开发人员执行“检查”时,没有错误。

// Define SVG area dimensions
var svgWidth = 960;
var svgHeight = 300;

// Define the chart's margins as an object
var margin = {
  top: 60,
  right: 60,
  bottom: 60,
  left: 60
};

// Define dimensions of the chart area
var chartWidth = svgWidth - margin.left - margin.right;
var chartHeight = svgHeight - margin.top - margin.bottom;

//dataset
var fake_data = [{type: "gdp", year: 2014, value: 78.9}, {type: "gdp", year: 2013, value: 78.8}, {type: "gdp", year: 2012, value: 78.8}, 
  {type: "gdp", year: 2011, value: 78.7}, {type: "gdp", year: 2010, value: 78.7}, {type: "gdp", year: 2009, value: 78.5},
  {type: "gdp", year: 2008, value: 78.2}, {type: "gdp", year: 2007, value: 78.1}, {type: "gdp", year: 2006, value: 77.8}, 
  {type: "gdp", year: 2005, value: 77.6}, {type: "gdp", year: 2004, value: 77.5}, {type: "gdp", year: 2003, value: 77.6},
  {type: "gdp", year: 2002, value: 77}, {type: "gdp", year: 2001, value: 77}, {type: "gdp", year: 2000, value: 76.8},
  {type: "gdp", year: 1999, value: 76.7}, {type: "gdp", year: 1998, value: 76.7}, {type: "gdp", year: 1997, value: 76.5},
  {type: "gdp", year: 1996, value: 76.1}, {type: "gdp", year: 1995, value: 75.8}, {type: "gdp", year: 1994, value: 75.7},
  {type: "pop", year: 1993, value: 75.5}, {type: "pop", year: 1992, value: 75.8}, {type: "pop", year: 1991, value: 75.5}, 
  {type: "pop", year: 1990, value: 80.4}, {type: "pop", year: 1989, value: 75.1}, {type: "pop", year: 1988, value: 74.9}, 
  {type: "pop", year: 1987, value: 74.9}, {type: "pop", year: 1986, value: 74.7}, {type: "pop", year: 1985, value: 74.7}, 
  {type: "pop", year: 1984, value: 74.7}, {type: "pop", year: 1983, value: 74.6}, {type: "pop", year: 1982, value: 74.5}, 
  {type: "pop", year: 1981, value: 74.1}, {type: "pop", year: 1980, value: 73.7}, {type: "pop", year: 1979, value: 73.9},
  {type: "pop", year: 1978, value: 73.5}, {type: "pop", year: 1977, value: 73.3}, {type: "pop", year: 1976, value: 72.9},
  {type: "le", year: 1975, value: 72.6}, {type: "le", year: 1974, value: 72}, {type: "le", year: 1973, value: 71.4},
  {type: "le", year: 1972, value: 71.2}, {type: "le", year: 1971, value: 71.1}, {type: "le", year: 1970, value: 70.8},
  {type: "le", year: 1969, value: 70.5}, {type: "le", year: 1968, value: 70.2}, {type: "le", year: 1967, value: 70.5},
  {type: "le", year: 1966, value: 70.2}, {type: "le", year: 1965, value: 70.2}, {type: "le", year: 1964, value: 70.2},
  {type: "le", year: 1963, value: 69.9}, {type: "le", year: 1962, value: 70.1}, {type: "le", year: 1961, value: 70.2},
  {type: "le", year: 1960, value: 69.7}, {type: "le", year: 1959, value: 69.9}, {type: "le", year: 1958, value: 69.6}];

// Nest data by symbol-- groups by type
  var symbols = d3.nest()
      .key(function(d) { return d.type; })
      .entries(fake_data);

// Add an SVG element for each symbol, with the desired dimensions and margin.
var svg = d3.select("body").selectAll("#graphic_area2")
.data(symbols)
.enter().append("svg")
.attr("id", "graphic_area2")
.attr("width", svgWidth)
.attr("height", svgHeight)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);

// Create a scale for your independent (x) coordinates
var xScale = d3.scaleLinear()
.domain(1955, 2020)
.range([0, svgWidth]);

// Create a scale for your dependent (y) coordinates
var yScale = d3.scaleLinear()
.range([svgHeight, 0]);

// create a line generator function and store as a variable
// use the scale functions for x and y data
var createLine = d3.line()
.x(data => xScale(data.year))
.y(data => yScale(data.value))

// Add the line path elements. Note: the y-domain is set per element.
svg.append("path")
.attr("class", "line")
.attr("d", function(d) { 
  yScale.domain([0, d3.max(d, data => data.value)]);
  
  //function to create formatted array called
  var pass_arr = create_pass_arr (d.values)

  return createLine(pass_arr);

});

//Functions
function create_pass_arr(data){
  var pass_yr = [];
  var pass_val = [];

  console.log("length:", data.length)

  for (k = 0; k < data.length; k++) {
    // create array in format [[year:x,y,z...],[value:x,y,z]] to pass
    pass_yr.push(data[k].year);
    pass_val.push(data[k].value);
  };
  var formatted_arr = {
    "year": pass_yr, "value": pass_val
  }

  console.log(formatted_arr.value)

  return (formatted_arr);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

1 个答案:

答案 0 :(得分:0)

代码中最大的问题是传递给行生成器的数据:您已经具有正确的数据结构。但是,您正在将正确的数据结构传递给这个奇怪的create_pass_arr函数,并得到错误的数据结构作为回报。

解决方案很简单,只需删除该函数即可:

.attr("d", function(d) { 
  return createLine(d.values);
})

最重要的是,您有两个小问题。首先,您没有正确计算yScale域,它应该是:

yScale.domain([0, d3.max(d.values, data => data.value)]);

此外,您的xScale域不是数组。域必须是数组。

这是您的代码,其中包含以下三个更改:

var svgWidth = 500;
var svgHeight = 200;

// Define the chart's margins as an object
var margin = {
  top: 60,
  right: 60,
  bottom: 60,
  left: 60
};

// Define dimensions of the chart area
var chartWidth = svgWidth - margin.left - margin.right;
var chartHeight = svgHeight - margin.top - margin.bottom;

//dataset
var fake_data = [{
    type: "gdp",
    year: 2014,
    value: 78.9
  }, {
    type: "gdp",
    year: 2013,
    value: 78.8
  }, {
    type: "gdp",
    year: 2012,
    value: 78.8
  },
  {
    type: "gdp",
    year: 2011,
    value: 78.7
  }, {
    type: "gdp",
    year: 2010,
    value: 78.7
  }, {
    type: "gdp",
    year: 2009,
    value: 78.5
  },
  {
    type: "gdp",
    year: 2008,
    value: 78.2
  }, {
    type: "gdp",
    year: 2007,
    value: 78.1
  }, {
    type: "gdp",
    year: 2006,
    value: 77.8
  },
  {
    type: "gdp",
    year: 2005,
    value: 77.6
  }, {
    type: "gdp",
    year: 2004,
    value: 77.5
  }, {
    type: "gdp",
    year: 2003,
    value: 77.6
  },
  {
    type: "gdp",
    year: 2002,
    value: 77
  }, {
    type: "gdp",
    year: 2001,
    value: 77
  }, {
    type: "gdp",
    year: 2000,
    value: 76.8
  },
  {
    type: "gdp",
    year: 1999,
    value: 76.7
  }, {
    type: "gdp",
    year: 1998,
    value: 76.7
  }, {
    type: "gdp",
    year: 1997,
    value: 76.5
  },
  {
    type: "gdp",
    year: 1996,
    value: 76.1
  }, {
    type: "gdp",
    year: 1995,
    value: 75.8
  }, {
    type: "gdp",
    year: 1994,
    value: 75.7
  },
  {
    type: "pop",
    year: 1993,
    value: 75.5
  }, {
    type: "pop",
    year: 1992,
    value: 75.8
  }, {
    type: "pop",
    year: 1991,
    value: 75.5
  },
  {
    type: "pop",
    year: 1990,
    value: 80.4
  }, {
    type: "pop",
    year: 1989,
    value: 75.1
  }, {
    type: "pop",
    year: 1988,
    value: 74.9
  },
  {
    type: "pop",
    year: 1987,
    value: 74.9
  }, {
    type: "pop",
    year: 1986,
    value: 74.7
  }, {
    type: "pop",
    year: 1985,
    value: 74.7
  },
  {
    type: "pop",
    year: 1984,
    value: 74.7
  }, {
    type: "pop",
    year: 1983,
    value: 74.6
  }, {
    type: "pop",
    year: 1982,
    value: 74.5
  },
  {
    type: "pop",
    year: 1981,
    value: 74.1
  }, {
    type: "pop",
    year: 1980,
    value: 73.7
  }, {
    type: "pop",
    year: 1979,
    value: 73.9
  },
  {
    type: "pop",
    year: 1978,
    value: 73.5
  }, {
    type: "pop",
    year: 1977,
    value: 73.3
  }, {
    type: "pop",
    year: 1976,
    value: 72.9
  },
  {
    type: "le",
    year: 1975,
    value: 72.6
  }, {
    type: "le",
    year: 1974,
    value: 72
  }, {
    type: "le",
    year: 1973,
    value: 71.4
  },
  {
    type: "le",
    year: 1972,
    value: 71.2
  }, {
    type: "le",
    year: 1971,
    value: 71.1
  }, {
    type: "le",
    year: 1970,
    value: 70.8
  },
  {
    type: "le",
    year: 1969,
    value: 70.5
  }, {
    type: "le",
    year: 1968,
    value: 70.2
  }, {
    type: "le",
    year: 1967,
    value: 70.5
  },
  {
    type: "le",
    year: 1966,
    value: 70.2
  }, {
    type: "le",
    year: 1965,
    value: 70.2
  }, {
    type: "le",
    year: 1964,
    value: 70.2
  },
  {
    type: "le",
    year: 1963,
    value: 69.9
  }, {
    type: "le",
    year: 1962,
    value: 70.1
  }, {
    type: "le",
    year: 1961,
    value: 70.2
  },
  {
    type: "le",
    year: 1960,
    value: 69.7
  }, {
    type: "le",
    year: 1959,
    value: 69.9
  }, {
    type: "le",
    year: 1958,
    value: 69.6
  }
];

// Nest data by symbol-- groups by type
var symbols = d3.nest()
  .key(function(d) {
    return d.type;
  })
  .entries(fake_data);

// Add an SVG element for each symbol, with the desired dimensions and margin.
var svg = d3.select("body").selectAll("#graphic_area2")
  .data(symbols)
  .enter().append("svg")
  .attr("id", "graphic_area2")
  .attr("width", svgWidth)
  .attr("height", svgHeight)
  .append("g")
  .attr("transform", `translate(${margin.left}, ${margin.top})`);

// Create a scale for your independent (x) coordinates
var xScale = d3.scaleLinear()
  .domain([1955, 2020])
  .range([0, svgWidth]);

// Create a scale for your dependent (y) coordinates
var yScale = d3.scaleLinear()
  .range([svgHeight, 0]);

// create a line generator function and store as a variable
// use the scale functions for x and y data
var createLine = d3.line()
  .x(data => xScale(data.year))
  .y(data => yScale(data.value))

// Add the line path elements. Note: the y-domain is set per element.
svg.append("path")
  .attr("class", "line")
  .attr("d", function(d) {
    yScale.domain([0, d3.max(d.values, data => data.value)]);
    return createLine(d.values);
  })
  .style("fill", "none")
  .style("stroke", "black")
  .style("stroke-width", "2px")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>