Juri
Juri

Reputation: 1741

D3js: scale an axis on every bar chart

I'm building a d3js chart with horizontal bars and an axis on every bar. Here is the jsfiddle http://jsfiddle.net/juri33/r5tkL8L1/

Now the scaling is done by this function

xScale.domain([0, d3.max(data, function(d) {
return d.initvalue * 2;
})]);

I would like to scale on every bar with different values -> every bar should get an another axis.

How can i do this? Any ideas?

Upvotes: 1

Views: 711

Answers (1)

Mark
Mark

Reputation: 108512

Here's a quick fix which scales each axis separately:

// an array of scales
// that's 5% larger then the data is representing
var xs = data.map(function(d,i){
    return d3.scale
    .linear()
    .range([0, width])
    .domain([0, d.restlifetime + (d.restlifetime * 0.05)]);
});

// set width with appropriate scale
bar.append("rect")
  .attr("width", function(d,i) {
    return xs[i](d.restlifetime);
  })
  .attr("height", barHeight - 1);

// draw an axis for each scale
bar.append("g")
  .attr("class", "x axis")
  .attr("transform", function(d, i) {
    return "translate(0, " + scaleOffset + ")";
  })
  .each(function(d,i){
    d3.select(this)
        .call(d3.svg.axis()
        .scale(xs[i])
        .orient("bottom"));
  });

Full code:

var margin = {
    top: 50,
    right: 50,
    bottom: 50,
    left: 50
  },
  width = 500 - margin.left - margin.right,
  barHeight = 20,
  barOffset = 30,
  scaleOffset = 19;

var data = [{
  bearingname: "B1",
  restlifetime: 1000
}, {
  bearingname: "B2",
  restlifetime: 100
}, {
  bearingname: "B3",
  restlifetime: 400
}, {
  bearingname: "B4",
  restlifetime: 300
}];

var x = d3.scale.linear()
  .range([0, width]);

var chart = d3.select(".chart")
  .attr("width", width + margin.left + margin.right + 300)
  .attr("height", function(d, i) {
    return (barHeight + barOffset) * data.length + margin.top + margin.bottom;
  })
.append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var xs = data.map(function(d,i){
	return d3.scale
  	.linear()
  	.range([0, width])
    .domain([0, d.restlifetime + (d.restlifetime * 0.05)]);
});

var bar = chart.selectAll("g")
  .data(data)
  .enter().append("g")
  .attr("transform", function(d, i) {
    return "translate(0," + i * (barHeight + barOffset) + ")";
  });

bar.append("rect")
  .attr("width", function(d,i) {
    return xs[i](d.restlifetime);
  })
  .attr("height", barHeight - 1);

bar.append("g")
  .attr("class", "x axis")
  .attr("transform", function(d, i) {
    return "translate(0, " + scaleOffset + ")";
  })
  .each(function(d,i){
    d3.select(this)
    	.call(d3.svg.axis()
  		.scale(xs[i])
  		.orient("bottom"));
  });

bar.append("text")
  .attr("x", function(d,i) {
    return xs[i](d.restlifetime) - 3;
  })
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .text(function(d) {
    return d.restlifetime + " h";
  });

bar.append("text")
  .attr("x", 520)
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .style("fill", "black")
  .text(function(d) {
    return d.bearingname;
  });

bar.append("text")
  .attr("x", 600)
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .style("fill", "black")
  .html("S 0, min");
.chart rect {
  fill: green;
}

.chart text {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}

.bar text {
  fill: black;
}

.axis text {
  font: 10px sans-serif;
  fill: black;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg class="chart"></svg>

Upvotes: 1

Related Questions