A multi-part graph is the time (year) of the x-axis interval overlaid over several years of data

Background

I use D3 4.x to build a series of several series ( see example ) to compare several years of annual data, where the Y axis represents the range of possible values ​​over the years, and the X axis represents the time interval between dates 01/01 - 12/31.

Questions

When constructing this diagram, it seems that the time intervals are specific to the year, preventing the transfer of data from different years to the same graph. I repeat, the current approach is to overlay each year on the same schedule; line for each year. And for this, with time intervals specific to the year, significant (and erroneous) data manipulation is required.

The example chart below shows that the year 2014 is approaching on the left (color: blue) and 2015 is continuing on the right (color: orange). What I would like to see are both of them for overlapping.

enter image description here

Confirmation / Caution

Some of the complexities of comparing the multi-year value of data by overlaying data on top of each other (i.e. multiple rows, each representing a year) are recognized. For example, how to deal with years with temporal days compared to those that do not. This complicates the task programmatically, but visually should not be a problem.

Questions

1) What is the best approach to using time slots when a year only gets in the way?

2) Is there a better, more elegant approach to creating multi-line line diagrams that are perennial layers on top of each other instead of breaking pieces?

3) ( ) (.. 2015) ()?

4) X (), (IMO, )?

+4
1

. , , . , . , - x.

, , : , . . , .

, 2013 2017 :

var years = [2013, 2014, 2015, 2016, 2017];

var scales = {};

years.forEach(d => {
    scales["scale" + d] = d3.scaleTime()
        .domain([new Date(+d, 0, 1), new Date(+d, 11, 31)])
        .range([30, 470]);
});

, x. , , : . , . .

, (2017 ) x. , , x.

. , ( 2013 2017 ), 1 31 :

var svg = d3.select("body").append("svg")
  .attr("width", 500)
  .attr("height", 200);

var color = d3.scaleOrdinal(d3.schemeCategory10);

var thisYear;

var line = d3.line()
  .x(d => scales[thisYear](d.x))
  .y(d => yScale(d.y))
  .curve(d3.curveMonotoneX);

var years = [2013, 2014, 2015, 2016, 2017];

var data = [];

years.forEach((d, i) => {
  data.push({
    year: d,
    points: []
  });
  for (var j = 0; j < 12; j++) {
    data[i].points.push({
      y: Math.random() * 80 + 20,
      x: new Date(d, j)
    })
  }
});

var scales = {};

var yScale = d3.scaleLinear()
  .domain([0, 100])
  .range([170, 30]);

years.forEach(d => {
  scales["scale" + d] = d3.scaleTime()
    .domain([new Date(+d, 0, 1), new Date(+d, 11, 31)])
    .range([30, 470]);
});

var paths = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("path");

paths.attr("stroke", (d, i) => color(i))
  .attr("d", d =>{
  thisYear = "scale" + d.year;
  return line(d.points);
  })
  .attr("fill", "none");
  
var xAxis = d3.axisBottom(scales.scale2017).tickFormat(d=>d3.timeFormat("%b")(d));
var yAxis = d3.axisLeft(yScale);

var gX = svg.append("g").attr("transform", "translate(0,170)").call(xAxis);

var gY = svg.append("g").attr("transform", "translate(30,0)").call(yAxis);
<script src="https://d3js.org/d3.v4.js"></script>
Hide result
+3

Source: https://habr.com/ru/post/1672612/


All Articles