Forced d3 chart to ignore null values

I have a timeline containing null values ​​and thus leaving a space in my lines. What I want to do is not have the d3 line generator ignore the null values ​​and cover the space.

As you can see in the image, the blue series has spaces.

As you can see in the image, the blue series has spaces.

Part of my problem is that I am standardized in this data format:

[
  {"x":1397102460000,"y0":11.4403,"y1":96.5},
  {"x":1397139660000,"y0":13.1913,"y1":96.5},
  {"x":1397522940000,"y1":96.5},
  ...
]

Therefore, when one series has a reading for a specific time stamp, the other series has a zero value.

Ultimately, I could try to solve this by filtering my data before drawing, but I hope for a smarter solution, perhaps around a line generator.

My string generator is pretty simple:

line = d3.line()
         .x(function(d) {
           return ~~_this.x(d[xKey]);
         })
         .y(function(d) {
           return ~~_this.y(d[yKey]);
         })
         .defined(function(d) {
           return d[yKey] || d[yKey] === 0;
         });

defined, , null y 0px, .

enter image description here

?

, d3 v4.x.

+4
2

, , , , , .

line.defined , , .

, , ( defined), . , , .

:

var counter;

(!= null), . , , :

var line = d3.line()
    .x((d, i) => {
        if (data[i].y) {
            return xScale(d.x)
        } else {
            return xScale(data[counter].x)
        }
    })
    .y((d, i) => {
        if (d.y) {
            counter = i;
            return yScale(d.y)
        } else {
            return yScale(data[counter].y)
        }
    });

( ) ( ):

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

var data = [{
    x: 10,
    y: 50
}, {
    x: 20,
    y: 70
}, {
    x: 30,
    y: 20
}, {
    x: 40,
    y: 60
}, {
    x: 50,
    y: 40
}, {
    x: 60,
    y: null
}, {
    x: 70,
    y: null
}, {
    x: 80,
    y: null
}, {
    x: 90,
    y: 90
}, {
    x: 100,
    y: 20
}];

var xScale = d3.scaleLinear()
    .domain([0, 100])
    .range([30, w - 20]);

var yScale = d3.scaleLinear()
    .domain([0, 100])
    .range([h - 20, 20]);

var counter;

var line = d3.line()
    .x((d, i) => {
        if (data[i].y) {
            return xScale(d.x)
        } else {
            return xScale(data[counter].x)
        }
    })
    .y((d, i) => {
        if (d.y) {
            counter = i;
            return yScale(d.y)
        } else {
            return yScale(data[counter].y)
        }
    });

svg.append("path")
    .attr("d", line(data))
    .attr("stroke-width", 2)
    .attr("stroke", "teal")
    .attr("fill", "none");

var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);

svg.append("g")
    .attr("transform", "translate(0," + (h - 20) + ")")
    .call(xAxis);

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

.

var line = d3.line()
.x(function(d){ return xScale(d[0]);})
.y(function(d){ return yScale(d[1]);})
.defined(function(d) {
        return d[1] || d[1] === '0';
     });

var filteredData = data.filter(line.defined());

svg.append("path")
.attr("d", line(filteredData)

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

var data = [
  [10, 50],
  [20, 70],
  [30, 20],
  [40, 60],
  [50, 40],
  [60, null],
  [70, null],
  [80, null],
  [90, 90],
  [100, 20]
];

var xScale = d3.scaleLinear()
  .domain([0, 100])
  .range([30, w - 20]);

var yScale = d3.scaleLinear()
  .domain([0, 100])
  .range([h - 20, 20]);

var counter;

var line = d3.line()
  .x(function(d) {
    return xScale(d[0]);
  })
  .y(function(d) {
    return yScale(d[1]);
  })
  .defined(function(d) {
    return d[1] || d[1] === '0';
  });

var filteredData = data.filter(line.defined());

svg.append("path")
  .attr("d", line(filteredData))
  .attr("stroke-width", 2)
  .attr("stroke", "teal")
  .attr("fill", "none");

var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);

svg.append("g")
  .attr("transform", "translate(0," + (h - 20) + ")")
  .call(xAxis);

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

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


All Articles