簡體   English   中英

在面積圖上繪制折線圖

[英]Draw line chart on top of area chart

我正在使用 D3js v5.12.0 構建圖表。

我已經完成了在 X 軸上有變量year和在 Y 軸上有變量earth_footprint的面積圖。

數據在這個鏈接: https://raw.githubusercontent.com/cvrnogueira/CODWorkData/master/database/final_data_set.json

我想在面積圖的頂部畫一個折線圖。 這個折線圖應該在 X 軸上有變量 year,在 Y 軸上有 pop_total。 pop_total是數據上的另一個變量。

但是我不知道怎么做,我看到了一些關於如何在條形圖中畫一條線的教程,但是當我適應我的面積圖代碼時,它就不起作用了。

提前致謝

CSS

#area-chart {
  text-align: center;
  margin-top: 40px;
}

.selection {
  fill: none;
}

HTLM

<!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


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");

});

為了顯示該行,您需要一個行生成器:

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

但是,您的yScale獲得earth_footprint的最大值,並且pop_total值將超出比例。 因此,您需要為該線生成器提供另一個比例:

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

之后,只需 append 路徑:

grp.append("path")
    .attr("d", line);

現在最大的問題是您有兩個具有不同比例的視覺編碼(區域和線)。 因此,您需要為該線添加一個附加軸。 我會把這項工作留給你。

這是生成的代碼:

 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"); });
 #area-chart { text-align: center; margin-top: 40px; }.selection { fill: none; }
 <: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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM