Reputation: 525
I am using d3.js to create a stacked bar chart similar to http://mbostock.github.com/d3/ex/stack.html with some additional features.i I was able to add labels and a grid, but I am having some issues implementing a log scale. I am using
d3.scale.log().domain([minNum,maxNum]).range([height,0])
but I can not figure out how to implement it with a stacked graph, with the following code:
var vis = d3.select("#chart")
.append("svg")
.attr("width", width)
.attr("height", height + margin);
var layers = vis.selectAll("g.layer")
.data(data)
.enter().append("g")
.style("fill", function(d, i) { return color(i / (n - 1)); })
.attr("class", "layer");
var bars = layers.selectAll("g.bar")
.data(function(d) { return d; })
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
bars.append("rect")
.attr("width", x({x: .9}))
.attr("x", 0)
.attr("y", y1)
.attr("height", function(d) { return y0(d) - y1(d); });
I know it deals with: .attr("height", function(d) { return y0(d) - y1(d); });
Any help would be great.
Upvotes: 3
Views: 10203
Reputation: 2137
I ran into this super old thread, here's info on why a log scale almost never makes sense for stacked bars, and rarely for regular bar charts or area charts (ie. charts with shapes that have a base)
Upvotes: 3
Reputation: 23
The short guide.
stack
for the original data set.scale
to create a second data set with logarithmic values.stack
again for the resulting set.// Original linear data
var linData = [
[
{ x: 0, y: 0.1 },
{ x: 1, y: 1.0 },
{ x: 2, y: 100.0 },
{ x: 3, y: 10000.0 }
],
[
{ x: 0, y: 0.2 },
{ x: 1, y: 2.0 },
{ x: 2, y: 200.0 },
{ x: 3, y: 20000.0 }
],
[
{ x: 0, y: 0.3 },
{ x: 1, y: 3.0 },
{ x: 2, y: 300.0 },
{ x: 3, y: 30000.0 }
]
];
// Calculating y0 for linear data
var stack = d3.layout.stack();
stack(linData);
// Setting conversion values from linear to logarithmic without scaling
var yScaleLog = d3.scale.log()
.domain([0.01,
d3.max(linData, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
])
.range([0,
d3.max(linData, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
]);
// Creating new set of data with logarithmized values
var logData = [];
for (var i = 0; i < linData.length; i++) {
logData[i] = [];
for (var j = 0; j < linData[i].length; j++) {
logData[i][j] = {
x: linData[i][j].x,
y: yScaleLog(linData[i][j].y)
};
}
}
// Calculating y0 for logarithmic data
stack(logData);
Full code: http://jsfiddle.net/romanshamin/5vF6a/2/
Upvotes: 0
Reputation: 5470
I think it would be helpful for you to start out with a basic (non-stacked) bar chart with a logarithmic scale --
You will want to give your scale representation a name, such as:
var myscale = d3.scale.log().domain([minNum,maxNum]).range([height,0]);
Then use this scale later to change to screen space, for example:
.attr("height", function(d) {return myscale(d);})
Here is a basic example for you to look over: http://jsfiddle.net/jsl6906/qAHC2/10/
Upvotes: 1