How do I create my own scale() function in d3?
I am trying to replace the nice linear scale in d3 d3.scale.linear()
with a different function that I would like to create myself. My new scale would be based on a cumulative distribution function, so that the median value would appear in the center of the x axis, and a value that was two standard deviations from the median would appear twice as far from the center of the x axis as something that was one standard deviation from the mean.
Here is a link to my jsfiddle page: http://jsfiddle.net/tbcholla/kR2PS/3/ (I would appreciate any other comments you might have about my code as well!)
right now I have:
var x = d3.scale.linear()
.range([0, width])
.domain(d3.extent([0, data.length]));
I've seen scale.pow()
and scale.log()
. Now I'd like to create a new function!
Thanks!
EDIT: I found the function scale.quantile(), which might hold the solution for me. My related question: Plotting a line graph with scale.quantile()
This is an example how we can add new functionality in d3.scale.liner(). For null values my function returns null (d3.scale.liner() returns 0 in this case). The primary approach is to wrap the original scale and all his methods.
I didn't test this function for all cases. But for basic functionality it's working. Unfortunately I didn't found easier way to do it :(
/**
* d3.scale.linear() retrun 0 for null value
* I need to get null in this case
* This is a wrapper for d3.scale.linear()
*/
_getLinearScaleWithNull: function() {
var alternativeScale = function(origLineScale) {
var origScale = origLineScale ? origLineScale : d3.scale.linear();
function scale(x) {
if (x === null) return null; //this is the implementation of new behaviour
return origScale(x);
}
scale.domain = function(x) {
if (!arguments.length) return origScale.domain();
origScale.domain(x);
return scale;
}
scale.range = function(x) {
if (!arguments.length) return origScale.range();
origScale.range(x);
return scale;
}
scale.copy = function() {
return alternativeScale(origScale.copy());
}
scale.invert = function(x) {
return origScale.invert(x);
}
scale.nice = function(m) {
origScale = origScale.nice(m);
return scale;
}
scale.ticks = function(m) {
return origScale.ticks(m);
};
scale.tickFormat = function(m, Format) {
return origScale.tickFormat(m, Format);
}
return scale;
}
return alternativeScale();
},