首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在面积图的顶部绘制线图

在面积图的顶部绘制线图
EN

Stack Overflow用户
提问于 2019-09-27 12:14:22
回答 1查看 270关注 0票数 0

我正在使用D3js v5.12.0构建一个图表。

我已经做了面积图,在X轴上有变量year,在Y轴上有变量earth_footprint

数据在以下链接中:https://raw.githubusercontent.com/cvrnogueira/CODWorkData/master/database/final_data_set.json

我想在区域图的顶部画一张线图。这条线图应该在X轴上有变量年,在Y轴上有pop_total。pop_total是数据上的另一个变量。

但是我无法控制如何去做,我看到了一些关于如何在条形图中画线的教程,但是当我适应我的代码(即区域图)时,它就不起作用了。

提前感谢

CSS

代码语言:javascript
复制
#area-chart {
  text-align: center;
  margin-top: 40px;
}

.selection {
  fill: none;
}

HTLM

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div id="area-chart"></div>
</body>
</html>

JS

代码语言:javascript
复制
var url = "http://raw.githubusercontent.com/cvrnogueira/CODWorkData/master/database/final_data_set.json";


  d3.json(url)
      .then(function(data) {

      data =  data.filter(dataPoint => dataPoint.country_code == 'BRA');
      data =  data.filter(element =>  element.hasOwnProperty("earth_footprint"));

const heightValue = 300;
const widthValue = 600;

// Create SVG and padding for the chart
const svg = d3
  .select("#area-chart")
  .append("svg")
  .attr("viewBox", `0 0 ${widthValue} ${heightValue}`)
;

const strokeWidth = 1.5;
const margin = { top: 0, bottom: 20, left: 30, right: 20 };
const chart = svg.append("g").attr("transform", `translate(${margin.left},0)`);
const width = 600 - margin.left - margin.right - (strokeWidth * 2);
const height = 300 - margin.top - margin.bottom;
const grp = chart
  .append("g")
  .attr("transform", `translate(-${margin.left - strokeWidth},-${margin.top})`);

// Create scales
const yScale = d3
  .scaleLinear()
  .range([height, 0])
  .domain([0, d3.max(data, dataPoint => dataPoint.earth_footprint)]);

const xScale = d3
  .scaleLinear()
  .range([0, width])
  .domain(d3.extent(data, dataPoint => dataPoint.year));

const area = d3
  .area()
  .x(dataPoint => xScale(dataPoint.year))
  .y0(height)
  .y1(dataPoint => yScale(dataPoint.earth_footprint));

// Add area
grp
  .append("path")
  .attr("transform", `translate(${margin.left},0)`)
  .datum(data)
  .style("fill", "lightblue")
  .attr("stroke", "steelblue")
  .attr("stroke-linejoin", "round")
  .attr("stroke-linecap", "round")
  .attr("stroke-width", strokeWidth)
  .attr("d", area);

// Add the X Axis
chart
  .append("g")
  .attr("transform", `translate(0,${height})`)
  .call(d3.axisBottom(xScale).ticks(data.length));

// Add the Y Axis
chart
  .append("g")
  .attr("transform", `translate(0, 0)`)
  .call(d3.axisLeft(yScale)); 


chart.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0 - margin.left)
      .attr("x",0 - (height / 2))
      .attr("dy", "1em")
      .style("text-anchor", "middle")
      .text("Number of Earths");

chart.append("text")             
      .attr("transform",
            "translate(" + (width/2) + " ," + 
                           (height + margin.top + 20) + ")")
      .style("text-anchor", "middle")
      .text("Year");

});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-27 13:47:22

要显示这一行,您需要一个行生成器:

代码语言:javascript
复制
const line = d3.area()
    .x(dataPoint => xScale(dataPoint.year))
    .y(dataPoint => yScale(dataPoint.pop_total));

但是,您的yScale获得了earth_footprint的最大值,并且pop_total值将超出规模。因此,您将需要另一个规模的线路生成器:

代码语言:javascript
复制
const yScale2 = d3.scaleLinear()
    .range([height, 0])
    .domain([0, d3.max(data, dataPoint => dataPoint.pop_total)]);

在此之后,只需追加路径:

代码语言:javascript
复制
grp.append("path")
    .attr("d", line);

现在最大的问题是,您有两个可视编码(区域和线),它们具有不同的尺度。因此,您将需要一个额外的轴线为这条线。我把那份工作留给你。

以下是生成的代码:

代码语言:javascript
复制
var url = "https://raw.githubusercontent.com/cvrnogueira/CODWorkData/master/database/final_data_set.json";


d3.json(url)
  .then(function(data) {

    data = data.filter(dataPoint => dataPoint.country_code == 'BRA');
    data = data.filter(element => element.hasOwnProperty("earth_footprint"));

    const heightValue = 300;
    const widthValue = 600;

    // Create SVG and padding for the chart
    const svg = d3
      .select("#area-chart")
      .append("svg")
      .attr("viewBox", `0 0 ${widthValue} ${heightValue}`);

    const strokeWidth = 1.5;
    const margin = {
      top: 0,
      bottom: 20,
      left: 30,
      right: 20
    };
    const chart = svg.append("g").attr("transform", `translate(${margin.left},0)`);
    const width = 600 - margin.left - margin.right - (strokeWidth * 2);
    const height = 300 - margin.top - margin.bottom;
    const grp = chart
      .append("g")
      .attr("transform", `translate(-${margin.left - strokeWidth},-${margin.top})`);

    // Create scales
    const yScale = d3
      .scaleLinear()
      .range([height, 0])
      .domain([0, d3.max(data, dataPoint => dataPoint.earth_footprint)]);

    const yScale2 = d3
      .scaleLinear()
      .range([height, 0])
      .domain([0, d3.max(data, dataPoint => dataPoint.pop_total)]);

    const xScale = d3
      .scaleLinear()
      .range([0, width])
      .domain(d3.extent(data, dataPoint => dataPoint.year));

    const area = d3
      .area()
      .x(dataPoint => xScale(dataPoint.year))
      .y0(height)
      .y1(dataPoint => yScale(dataPoint.earth_footprint));

    const line = d3.area()
      .x(dataPoint => xScale(dataPoint.year))
      .y(dataPoint => yScale2(dataPoint.pop_total));

    // Add area
    grp
      .append("path")
      .attr("transform", `translate(${margin.left},0)`)
      .datum(data)
      .style("fill", "lightblue")
      .attr("stroke", "steelblue")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", strokeWidth)
      .attr("d", area);

    grp
      .append("path")
      .attr("transform", `translate(${margin.left},0)`)
      .datum(data)
      .style("fill", "none")
      .attr("stroke", "red")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", strokeWidth)
      .attr("d", line);

    // Add the X Axis
    chart
      .append("g")
      .attr("transform", `translate(0,${height})`)
      .call(d3.axisBottom(xScale).ticks(data.length));

    // Add the Y Axis
    chart
      .append("g")
      .attr("transform", `translate(0, 0)`)
      .call(d3.axisLeft(yScale));


    chart.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0 - margin.left)
      .attr("x", 0 - (height / 2))
      .attr("dy", "1em")
      .style("text-anchor", "middle")
      .text("Number of Earths");

    chart.append("text")
      .attr("transform",
        "translate(" + (width / 2) + " ," +
        (height + margin.top + 20) + ")")
      .style("text-anchor", "middle")
      .text("Year");

  });
代码语言:javascript
复制
#area-chart {
  text-align: center;
  margin-top: 40px;
}

.selection {
  fill: none;
}
代码语言:javascript
复制
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <title>JS Bin</title>
  </head>

  <body>
    <div id="area-chart"></div>
  </body>

</html>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58134349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档