首页 > 解决方案 > D3 图表显示不正确

问题描述

我花了几个小时试图理解为什么我的图表应该看起来像这样,但看起来却大不相同,正如您根据下面的代码所看到的那样。仅供参考,这是 FCC 在数据可视化方面的挑战之一。我在这里犯了什么错误?

const svg_width = 1000;
const svg_height = 750;
const margin = {
  'top':40,
  'bottom':40,
  'left':60,
  'right': 60,
}

var svg = d3.select("#chart-container")
.append("svg")
.attr("width", svg_width)
.attr("height", svg_height)
.style("border", "solid")

d3.json("https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json", function (data) {
  var dataset = data.data
  var parseDates = d3.timeParse("%Y-%m-%d")
  
  var xScale = d3.scaleTime()
  .domain([d3.min(dataset, (d) => parseDates(d[0])),
          d3.max(dataset, (d) => parseDates(d[0]))])
  .range([margin.left, svg_width - margin.right])
  
  var xAxis = d3.axisBottom()
  .scale(xScale)
  .tickSizeOuter(0)
  
  svg.append("g")
  .attr("transform", ("translate(0," + (svg_height- margin.bottom)+")"))
  .call(xAxis.ticks(d3.timeYear).ticks(10))
  
  var yScale = d3.scaleLinear()
  .domain([d3.min(dataset, (d) => d[1]), 
          d3.max(dataset, (d) => d[1])])
  .range([svg_height - margin.bottom, margin.bottom])
  
  var yAxis = d3.axisLeft()
  .scale(yScale)
  .tickSizeOuter(0)
  
  svg.append("g")
  .call(yAxis)
  .attr("transform", "translate (60, 0)")
  
  svg.selectAll("rect")
  .data(dataset)
  .enter()
  .append("rect")
  .attr("x", (d) => xScale(parseDates(d[0])))
  .attr("y", (d) => (svg_height - margin.top) - yScale(d[1]))
  .attr("width", 1)
  .attr("height", (d) => yScale(d[1]))
  .attr("fill", "green")
});
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<div id="chart-container"></div>

标签: javascriptd3.js

解决方案


当您绘制条形图时,您的height计算y结果是相反的。

const svg_width = 1000;
const svg_height = 750;
const margin = {
  'top':40,
  'bottom':40,
  'left':60,
  'right': 60,
}

var svg = d3.select("#chart-container")
.append("svg")
.attr("width", svg_width)
.attr("height", svg_height)
.style("border", "solid")

d3.json("https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json", function (data) {
  var dataset = data.data
  var parseDates = d3.timeParse("%Y-%m-%d")
  
  var xScale = d3.scaleTime()
  .domain([d3.min(dataset, (d) => parseDates(d[0])),
          d3.max(dataset, (d) => parseDates(d[0]))])
  .range([margin.left, svg_width - margin.right])
  
  var xAxis = d3.axisBottom()
  .scale(xScale)
  .tickSizeOuter(0)
  
  svg.append("g")
  .attr("transform", ("translate(0," + (svg_height- margin.bottom)+")"))
  .call(xAxis.ticks(d3.timeYear).ticks(10))
  
  var yScale = d3.scaleLinear()
  .domain([d3.min(dataset, (d) => d[1]), 
          d3.max(dataset, (d) => d[1])])
  .range([svg_height - margin.bottom, margin.bottom])
  
  var yAxis = d3.axisLeft()
  .scale(yScale)
  .tickSizeOuter(0)
  
  svg.append("g")
  .call(yAxis)
  .attr("transform", "translate (60, 0)")
  
  svg.selectAll("rect")
  .data(dataset)
  .enter()
  .append("rect")
  .attr("x", (d) => xScale(parseDates(d[0])))
  .attr("y", (d) => yScale(d[1]))
  .attr("width", 1)
  .attr("height", (d) => (svg_height - margin.top) - yScale(d[1]))
  .attr("fill", "green")
});
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<div id="chart-container"></div>


推荐阅读