javauser35
javauser35

Reputation: 1315

Find domain values in inner arrays

I have a dataset like this:

const dataset = [
      { 'color': 'red', 'data': [{ x: 0, y: 600 }, { x: 2, y: 900 }, { x: 4, y: 650 }, { x: 6, y: 700 }, { x: 9, y: 600 }] },
      { 'color': 'blue', 'data': [{ x: 0, y: 400 }, { x: 2, y: 300 }, { x: 4, y: 450 }, { x: 6, y: 900 }, { x: 9, y: 400 }] },
      { 'color': 'yellow', 'data': [{ x: 0, y: 200 }, { x: 2, y: 100 }, { x: 4, y: 550 }, { x: 6, y: 600 }, { x: 9, y: 400 }] }
    ];

I want to find domain values for max and min x-axis. I try this code but it doesn't work:

.domain([d3.min(arrangedata, (array) => array.x), d3.max(arrangedata, (array) => array.x)])

I also tried d3.extend, but I couldn't handle it. Any idea ?

Upvotes: 2

Views: 41

Answers (2)

Gerardo Furtado
Gerardo Furtado

Reputation: 102188

For using either d3.max/min or d3.extent, you have to merge the inner arrays, which you can do with Array.prototype.reduce. Then, specify the x property in the accessor.

All together, it's just this:

const extent = d3.extent(dataset.reduce((a, c) => a.concat(c.data), []), d => d.x);

Here is the demo:

const dataset = [{
    'color': 'red',
    'data': [{
      x: 0,
      y: 600
    }, {
      x: 2,
      y: 900
    }, {
      x: 4,
      y: 650
    }, {
      x: 6,
      y: 700
    }, {
      x: 9,
      y: 600
    }]
  },
  {
    'color': 'blue',
    'data': [{
      x: 0,
      y: 400
    }, {
      x: 2,
      y: 300
    }, {
      x: 4,
      y: 450
    }, {
      x: 6,
      y: 900
    }, {
      x: 9,
      y: 400
    }]
  },
  {
    'color': 'yellow',
    'data': [{
      x: 0,
      y: 200
    }, {
      x: 2,
      y: 100
    }, {
      x: 4,
      y: 550
    }, {
      x: 6,
      y: 600
    }, {
      x: 9,
      y: 400
    }]
  }
];

const extent = d3.extent(dataset.reduce((a, c) => a.concat(c.data), []), d => d.x);

console.log(extent)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Upvotes: 1

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48640

You can try applying Math. min/max to the mapped series data.

d3.minValue = function(dataset, field) {
  return d3.min(dataset, series => Math.min.apply(Math, series.data.map(data => data[field])))
}

d3.maxValue = function(dataset, field) {
  return d3.max(dataset, series => Math.max.apply(Math, series.data.map(data => data[field])))
}

const dataset = [{
  'color': 'red',
  'data': [{ x: 0, y: 600 }, { x: 2, y: 900 }, { x: 4, y: 650 }, { x: 6, y: 700 }, { x: 9, y: 600 }]
}, {
  'color': 'blue',
  'data': [{ x: 0, y: 400 }, { x: 2, y: 300 }, { x: 4, y: 450 }, { x: 6, y: 900 }, { x: 9, y: 400 }]
}, {
  'color': 'yellow',
  'data': [{ x: 0, y: 200 }, { x: 2, y: 100 }, { x: 4, y: 550 }, { x: 6, y: 600 }, { x: 9, y: 400 }]
}]


//let domain = d3.domain([ d3.minValue(dataset, 'x'), d3.maxValue(dataset, 'x') ])

console.log(d3.minValue(dataset, 'x'), d3.maxValue(dataset, 'x')) // 0, 9
console.log(d3.minValue(dataset, 'y'), d3.maxValue(dataset, 'y')) // 100, 900
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Upvotes: 0

Related Questions