Arash Howaida
Arash Howaida

Reputation: 2617

Threshold scale for position

I would like to have an x-axis whereby the data to pixel position is calculated by thresholds. I know there are thresholds for colors as seen here, but I have not been able to find an equivalent for x/y axes.

My data looks like this:

{'aum':50,'inject':0,'sub':0},
{'aum':26,'inject':1,'sub':0},
{'aum':15,'inject':1,'sub':1}

aum can range anywhere from 0 to to over 70. So I want to have bins -- namely bins marked at three thresholds of my choosing. Consider my code below:

var xScale = d3.scaleThreshold()
    .domain([7,69,70])
    .range([0,width]);

In my dot plot (still in progress), I wanted to have three categories with 7,69,70+ as thresholds, but the result was just all the circles were slammed together. It seems my code above does not function as a proper scale.

Question

Aside from recoding the data into overt categories (0 for less than 7, 1 for 8-69, and 2 for 70+) can I construct a scale that d3 understands while still keeping my data in number/float format?

Upvotes: 2

Views: 144

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102194

You can use a threshold scale with almost anything in the range, be it colours (that is, strings) or coordinates (that is, numbers).

In your case, you just need to pass the adequate range array. Bear in mind that, if you have N elements in the domain, you need to have N + 1 elements in the range. Also, you don't need that [7,69,70] in your domain: the values mark the start of the next bin. So, in your case, the domain must be [8, 70].

Here is a demo:

var xScale = d3.scaleThreshold()
  .domain([7, 70])
  .range([0, 250, 500]);

console.log(xScale(4))
console.log(xScale(7))
console.log(xScale(30))
console.log(xScale(69))
console.log(xScale(100))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Also, since you have a width variable and you want to divide the space from 0 to width, you can create the range dynamically. For instance:

var width = 500;
var xScale = d3.scaleThreshold()
.domain([7, 20, 40, 55, 70]);

xScale.range(d3.range(xScale.domain().length + 1).map(d=>d*(width/xScale.domain().length)));

console.log(xScale(4))
console.log(xScale(7))
console.log(xScale(22))
console.log(xScale(45))
console.log(xScale(69))
console.log(xScale(300))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Upvotes: 2

Related Questions