score:1

The approach I'd take is:

  1. extract all x values, where at least one line has a value specified.
  2. create scale for each line, where domain is its all x points, and range is its all y points
  3. loop through the x list, get interpolated y value on each line, and add together.

Admittedly I'm not too familiar with d3-interpolation package, so there might be a more preferable way to execute this. Still, this works.

const server1 = [
  { date: '2019-06-15T00:22:25.000Z', online: 451 },
  { date: '2019-06-15T01:08:58.000Z', online: 499 },
  { date: '2019-06-15T02:25:35.000Z', online: 464 },
  { date: '2019-06-15T13:25:42.000Z', online: 252 },
  { date: '2019-06-15T15:45:24.000Z', online: 247 },
  { date: '2019-06-15T17:02:09.000Z', online: 254 },
  { date: '2019-06-15T20:11:00.000Z', online: 300 },
  { date: '2019-06-15T21:22:33.000Z', online: 296 },
  { date: '2019-06-15T22:24:58.000Z', online: 298 },
  { date: '2019-06-15T22:58:18.000Z', online: 270 }
];

const server2 = [
  { date: '2019-06-15T00:14:18.000Z', online: 599 },
  { date: '2019-06-15T00:58:56.000Z', online: 554 },
  { date: '2019-06-15T02:15:13.000Z', online: 505 },
  { date: '2019-06-15T13:32:19.000Z', online: 221 },
  { date: '2019-06-15T15:19:08.000Z', online: 265 },
  { date: '2019-06-15T16:04:55.000Z', online: 277 },
  { date: '2019-06-15T17:31:16.000Z', online: 275 },
  { date: '2019-06-15T18:41:16.000Z', online: 303 },
  { date: '2019-06-15T20:05:41.000Z', online: 333 },
  { date: '2019-06-15T21:39:44.000Z', online: 288 },
  { date: '2019-06-15T22:46:01.000Z', online: 277 },
  { date: '2019-06-15T23:29:16.000Z', online: 264 }
];

const server3 = [
  { date: '2019-06-15T00:10:18.000Z', online: 321 },
  { date: '2019-06-15T00:54:56.000Z', online: 300 },
  { date: '2019-06-15T02:11:13.000Z', online: 280 },
  { date: '2019-06-15T13:28:19.000Z', online: 110 },
  { date: '2019-06-15T15:15:08.000Z', online: 130 },
  { date: '2019-06-15T16:01:55.000Z', online: 133 },
  { date: '2019-06-15T17:25:16.000Z', online: 140 },
  { date: '2019-06-15T18:37:16.000Z', online: 172 },
  { date: '2019-06-15T20:01:41.000Z', online: 180 },
  { date: '2019-06-15T21:35:44.000Z', online: 201 },
  { date: '2019-06-15T22:41:01.000Z', online: 210 },
  { date: '2019-06-15T23:23:16.000Z', online: 197 }
];

var x_list = [].concat(server1, server2, server3)
  .map(d => new Date(d.date))
  .sort(d3.ascending);
  
var servers_scales = [server1, server2, server3].map(s => {
  return d3.scaleLinear()
    .domain(s.map(d => new Date(d.date)))
    .range(s.map(d => d.online));
});

var combinedData = x_list.map(x => {
  var val = 0;
  for (var i = 0; i < servers_scales.length; i++)
    val += servers_scales[i](x);
  return {
    date: x,
    online: val
  };
});


const combined = [].concat(server1, server2, server3);

const margin = {top: 50, right: 50, bottom: 50, left: 50};
const width = window.innerWidth - margin.left - margin.right;
const height = window.innerHeight - margin.top - margin.bottom;

const dateMin = d3.min(combined, d => new Date(d.date));
const dateMax = d3.max(combined, d => new Date(d.date));
const onlineMin = d3.min(combined, d => d.online);
const onlineMax = d3.max(combined, d => d.online);

const xScale = d3
  .scaleTime()
  .domain([dateMin, dateMax])
  .range([0, width]);

const yScale = d3
  .scaleLinear()
  .domain([0, onlineMax * 3])
  .range([height, 0]);
  
const line = d3
  .line()
  .x(d => xScale(new Date(d.date)))
  .y(d => yScale(d.online))
  .curve(d3.curveMonotoneX);
  
const svg = d3
  .select('body')
  .append('svg')
  .attr('width', width + margin.left + margin.right)
  .attr('height', height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
svg
  .append('path')
  .datum(server1)
  .attr('class', 'line')
  .attr('fill', 'none')
  .attr('stroke', 'blue')
  .attr('d', line);
  
svg
  .append('path')
  .datum(server2)
  .attr('class', 'line')
  .attr('fill', 'none')
  .attr('stroke', 'red')
  .attr('d', line);
  
svg
  .append('path')
  .datum(server3)
  .attr('class', 'line')
  .attr('fill', 'none')
  .attr('stroke', 'green')
  .attr('d', line);

svg
  .append('path')
  .datum(combinedData)
  .attr('class', 'line')
  .attr('fill', 'none')
  .attr('stroke', 'orange')
  .attr('d', line);

svg
	.append("g")
  .attr("class", "y axis")
  .call(d3.axisLeft(yScale));
  
svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(xScale));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


Related Query

More Query from same tag