D3js - Getting the maximum value from d3.line () for a specific domain

I am doing a multi-line graph, and I implemented a brush to be able to scale in a specific domain along the x axis. However, when I zoom in, I want the y axis scaled so that its domain goes from [0, maxY], where maxYis the maximum y value for the current x-axis selection. For generating strings I use d3.line()(which has a relationship between x and y values). This is how I calculate the value now maxY:

//Find max and min values in data to set the domain of the y-axis
var maxArray = updatedData.map(function(variable){
  //First map the values in the array to a new array
  var valuesArray = variable.values.map(function(d){
    return d.value;
  })
  //Find max value in array
  return Math.max(...valuesArray);
});
var maxY = Math.max(...maxArray);

And this is where I set the scales and create d3.line():

var xScale = d3.scaleTime()
  .range([0, chartWidth]);
var yScale = d3.scaleLinear()
  .domain([0, maxY])
  .range([chartHeight, 0]);

var brush = d3.brushX()
  .on("end", brushend);

var line = d3.line()
  .curve(d3.curveBasis)
  .x(function(d) {return xScale(d.date)})
  .y(function(d) {return yScale(d.value)})

//Save this to be able to zoom back out
var originalDomain = [new Date(data[0].Timestamp), new Date(data[data.length-1].Timestamp)];
xScale.domain(originalDomain);

Here is the code in which I install a new one xScale.domain()and increase it at this interval (which is called when cleaning is completed):

function brushend(){
  //sourceEvent - the underlying input event, such as mousemove or touchmove.
  if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
  var brushInterval = d3.event.selection; //The interval of the current brushed selection
  //If the function is called with no selection: ignore
  if(!brushInterval) return;
  //Enable reset button
  resetButton.attr("disabled", null)
    .on("click", resetAxis);

  var newDomain = brushInterval.map(xScale.invert, xScale);

  //TODO: Find max and min values in data to set the domain of the y-axis

  xScale.domain(newDomain);
  chart.selectAll(".line")
    .transition()
    .duration(1000)
      .attr("d", function(d){ return line(d.values)});
  chart.select(".x-axis")
    .transition()
    .duration(1000)
      .call(xAxis);
  //Remove the visual brush
  d3.select(".brush").call(brush.move, null);
}

, y . , , , , (, ). , . d3.line(), .

d3.line()?

+4
1

, , , x. , d3.max(), , , , .filter(). d3.max() null, , null, x. , - :

const maxY = xDomain => d3.max(updatedData, variable => 
  d3.max(
    variable.values,
    v => v.Timestamp >= xDomain[0] && v.Timestamp <= xDomain[1] ? v.value : null
  )
);

:

var updatedData = [{
  values: [{Timestamp:0, value:1},{Timestamp:1, value:5},{Timestamp:2, value:10},{Timestamp:3, value:3},{Timestamp:4, value:30}]
}, {
  values: [{Timestamp:0, value:19},{Timestamp:1, value:12},{Timestamp:2, value:13},{Timestamp:3, value:8},{Timestamp:4, value:50}]
}];

const maxY = xDomain => d3.max(updatedData, variable => 
  d3.max(
    variable.values,
    v => (!xDomain || v.Timestamp >= xDomain[0] && v.Timestamp <= xDomain[1]) ? v.value : null
  )
);

console.log(maxY());       // Default, check all values: max 50
console.log(maxY([1,3]));  // Max 13
console.log(maxY([0,3]));  // Max 19
<script src="https://d3js.org/d3.v4.js"></script>
Hide result
+2

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


All Articles