Skip to content

Commit bd883a9

Browse files
OivalfMarquesgordonwoodhull
authored andcommitted
Grouped and Staked Bars
1 parent ddbc7eb commit bd883a9

File tree

1 file changed

+87
-17
lines changed

1 file changed

+87
-17
lines changed

src/bar-chart.js

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,21 @@
2727
dc.barChart = function (parent, chartGroup) {
2828
var MIN_BAR_WIDTH = 1;
2929
var DEFAULT_GAP_BETWEEN_BARS = 2;
30+
var DEFAULT_GAP_BETWEEN_BAR_SERIES = 5;
3031
var LABEL_PADDING = 3;
32+
var _type = "dc.BAR_CHART";
3133

3234
var _chart = dc.stackMixin(dc.coordinateGridMixin({}));
3335

3436
var _gap = DEFAULT_GAP_BETWEEN_BARS;
37+
var _serieGap = DEFAULT_GAP_BETWEEN_BAR_SERIES;
3538
var _centerBar = false;
3639
var _alwaysUseRounding = false;
3740

3841
var _barWidth;
3942

43+
44+
_chart.type = _type;
4045
dc.override(_chart, 'rescale', function () {
4146
_chart._rescale();
4247
_barWidth = undefined;
@@ -46,7 +51,7 @@ dc.barChart = function (parent, chartGroup) {
4651
dc.override(_chart, 'render', function () {
4752
if (_chart.round() && _centerBar && !_alwaysUseRounding) {
4853
dc.logger.warn('By default, brush rounding is disabled if bars are centered. ' +
49-
'See dc.js bar chart API documentation for details.');
54+
'See dc.js bar chart API documentation for details.');
5055
}
5156

5257
return _chart._render();
@@ -81,11 +86,24 @@ dc.barChart = function (parent, chartGroup) {
8186
});
8287
};
8388

84-
function barHeight (d) {
89+
function barHeight(d) {
8590
return dc.utils.safeNumber(Math.abs(_chart.y()(d.y + d.y0) - _chart.y()(d.y0)));
8691
}
8792

88-
function renderLabels (layer, layerIndex, d) {
93+
94+
function getCharts() {
95+
if (parent instanceof Object) {
96+
if (parent.children() instanceof Array) {
97+
return parent.children().filter(function (chart) {
98+
return chart.type === _type;
99+
});
100+
}
101+
}
102+
return [];
103+
104+
}
105+
106+
function renderLabels(layer, layerIndex, d) {
89107
var labels = layer.selectAll('text.barLabel')
90108
.data(d.values, dc.pluck('x'));
91109

@@ -102,8 +120,19 @@ dc.barChart = function (parent, chartGroup) {
102120
dc.transition(labels, _chart.transitionDuration(), _chart.transitionDelay())
103121
.attr('x', function (d) {
104122
var x = _chart.x()(d.x);
105-
if (!_centerBar) {
106-
x += _barWidth / 2;
123+
var charts = getCharts();
124+
if (charts.length > 1) {
125+
x += _chart.serieGap() / 2;
126+
x += layerIndex * (_barWidth + _gap);
127+
x += _gap / 2;
128+
}
129+
x += _barWidth / 2;
130+
if (_centerBar && !_chart.isOrdinal()) {
131+
if (charts.length > 1) {
132+
x -= ((_barWidth + _gap) * charts.length + _chart.serieGap()) / 2;
133+
} else {
134+
x -= _barWidth / 2;
135+
}
107136
}
108137
return dc.utils.safeNumber(x);
109138
})
@@ -125,7 +154,7 @@ dc.barChart = function (parent, chartGroup) {
125154
.remove();
126155
}
127156

128-
function renderBars (layer, layerIndex, d) {
157+
function renderBars(layer, layerIndex, d) {
129158
var bars = layer.selectAll('rect.bar')
130159
.data(d.values, dc.pluck('x'));
131160

@@ -147,8 +176,19 @@ dc.barChart = function (parent, chartGroup) {
147176
dc.transition(bars, _chart.transitionDuration(), _chart.transitionDelay())
148177
.attr('x', function (d) {
149178
var x = _chart.x()(d.x);
150-
if (_centerBar) {
151-
x -= _barWidth / 2;
179+
var charts = getCharts();
180+
var chartIndex = charts.indexOf(_chart);
181+
if (charts.length > 1) {
182+
x += _chart.serieGap() / 2;
183+
x += chartIndex * (_barWidth + _gap);
184+
x += _gap / 2;
185+
}
186+
if (_centerBar && !_chart.isOrdinal()) {
187+
if (charts.length > 1) {
188+
x -= ((_barWidth + _gap) * charts.length + _chart.serieGap()) / 2;
189+
} else {
190+
x -= _barWidth / 2;
191+
}
152192
}
153193
if (_chart.isOrdinal() && _gap !== undefined) {
154194
x += _gap / 2;
@@ -177,19 +217,31 @@ dc.barChart = function (parent, chartGroup) {
177217
.remove();
178218
}
179219

180-
function calculateBarWidth () {
220+
function calculateBarWidth() {
181221
if (_barWidth === undefined) {
182222
var numberOfBars = _chart.xUnitCount();
183-
184-
// please can't we always use rangeBands for bar charts?
185-
if (_chart.isOrdinal() && _gap === undefined) {
186-
_barWidth = Math.floor(_chart.x().rangeBand());
187-
} else if (_gap) {
188-
_barWidth = Math.floor((_chart.xAxisLength() - (numberOfBars - 1) * _gap) / numberOfBars);
223+
var charts = getCharts();
224+
if (charts.length > 1) {
225+
var numberOfCharts = charts.length;
226+
if (_chart.isOrdinal()) {
227+
_barWidth = Math.floor((_chart.x().rangeBand() - _chart.serieGap()) / numberOfCharts - _gap);
228+
} else {
229+
_barWidth = Math.floor((_chart.xAxisLength() - (_chart.xUnitCount() - 1) * _chart.serieGap() -
230+
(numberOfBars - 1) * (numberOfCharts) * _gap) / (numberOfBars * numberOfCharts));
231+
}
189232
} else {
190-
_barWidth = Math.floor(_chart.xAxisLength() / (1 + _chart.barPadding()) / numberOfBars);
233+
// please can't we always use rangeBands for bar charts?
234+
if (_chart.isOrdinal() && _gap === undefined) {
235+
_barWidth = Math.floor(_chart.x().rangeBand());
236+
} else if (_gap) {
237+
_barWidth = Math.floor((_chart.xAxisLength() - (numberOfBars - 1) * _gap) / numberOfBars);
238+
} else {
239+
_barWidth = Math.floor(_chart.xAxisLength() / (1 + _chart.barPadding()) / numberOfBars);
240+
}
191241
}
192242

243+
244+
193245
if (_barWidth === Infinity || isNaN(_barWidth) || _barWidth < MIN_BAR_WIDTH) {
194246
_barWidth = MIN_BAR_WIDTH;
195247
}
@@ -299,6 +351,24 @@ dc.barChart = function (parent, chartGroup) {
299351
return _chart;
300352
};
301353

354+
/**
355+
* Manually set fixed gap (in px) between bar groups instead of relying on the default auto-generated
356+
* gap. Only applicable for grouped bar charts.
357+
* @name serieGap
358+
* @memberof dc.barChart
359+
* @instance
360+
* @param {Number} [serieGap=5]
361+
* @return {Number}
362+
* @return {dc.barChart}
363+
*/
364+
_chart.serieGap = function (serieGap) {
365+
if (!arguments.length) {
366+
return _serieGap;
367+
}
368+
_serieGap = serieGap;
369+
return _chart;
370+
};
371+
302372
_chart.extendBrush = function () {
303373
var extent = _chart.brush().extent();
304374
if (_chart.round() && (!_centerBar || _alwaysUseRounding)) {
@@ -335,7 +405,7 @@ dc.barChart = function (parent, chartGroup) {
335405
return _chart;
336406
};
337407

338-
function colorFilter (color, inv) {
408+
function colorFilter(color, inv) {
339409
return function () {
340410
var item = d3.select(this);
341411
var match = item.attr('fill') === color;

0 commit comments

Comments
 (0)