dc
Version:
A multi-dimensional charting library built to work natively with crossfilter and rendered using d3.js
133 lines (111 loc) • 4.36 kB
JavaScript
/**
* A concrete implementation of a general purpose bubble chart that allows data visualization using the
* following dimensions:
* - x axis position
* - y axis position
* - bubble radius
* - color
*
* Examples:
* - {@link http://dc-js.github.com/dc.js/ Nasdaq 100 Index}
* - {@link http://dc-js.github.com/dc.js/vc/index.html US Venture Capital Landscape 2011}
* @class bubbleChart
* @memberof dc
* @mixes dc.bubbleMixin
* @mixes dc.coordinateGridMixin
* @example
* // create a bubble chart under #chart-container1 element using the default global chart group
* var bubbleChart1 = dc.bubbleChart('#chart-container1');
* // create a bubble chart under #chart-container2 element using chart group A
* var bubbleChart2 = dc.bubbleChart('#chart-container2', 'chartGroupA');
* @param {String|node|d3.selection} parent - Any valid
* {@link https://github.com/d3/d3-3.x-api-reference/blob/master/Selections.md#selecting-elements d3 single selector} specifying
* a dom block element such as a div; or a dom element or d3 selection.
* @param {String} [chartGroup] - The name of the chart group this chart instance should be placed in.
* Interaction with a chart will only trigger events and redraws within the chart's group.
* @returns {dc.bubbleChart}
*/
dc.bubbleChart = function (parent, chartGroup) {
var _chart = dc.bubbleMixin(dc.coordinateGridMixin({}));
_chart.transitionDuration(750);
_chart.transitionDelay(0);
var bubbleLocator = function (d) {
return 'translate(' + (bubbleX(d)) + ',' + (bubbleY(d)) + ')';
};
_chart.plotData = function () {
_chart.calculateRadiusDomain();
_chart.r().range([_chart.MIN_RADIUS, _chart.xAxisLength() * _chart.maxBubbleRelativeSize()]);
var data = _chart.data();
var bubbleG = _chart.chartBodyG().selectAll('g.' + _chart.BUBBLE_NODE_CLASS)
.data(data, function (d) { return d.key; });
if (_chart.sortBubbleSize()) {
// update dom order based on sort
bubbleG.order();
}
renderNodes(bubbleG);
updateNodes(bubbleG);
removeNodes(bubbleG);
_chart.fadeDeselectedArea();
};
function renderNodes (bubbleG) {
var bubbleGEnter = bubbleG.enter().append('g');
bubbleGEnter
.attr('class', _chart.BUBBLE_NODE_CLASS)
.attr('transform', bubbleLocator)
.append('circle').attr('class', function (d, i) {
return _chart.BUBBLE_CLASS + ' _' + i;
})
.on('click', _chart.onClick)
.attr('fill', _chart.getColor)
.attr('r', 0);
dc.transition(bubbleG, _chart.transitionDuration(), _chart.transitionDelay())
.select('circle.' + _chart.BUBBLE_CLASS)
.attr('r', function (d) {
return _chart.bubbleR(d);
})
.attr('opacity', function (d) {
return (_chart.bubbleR(d) > 0) ? 1 : 0;
});
_chart._doRenderLabel(bubbleGEnter);
_chart._doRenderTitles(bubbleGEnter);
}
function updateNodes (bubbleG) {
dc.transition(bubbleG, _chart.transitionDuration(), _chart.transitionDelay())
.attr('transform', bubbleLocator)
.select('circle.' + _chart.BUBBLE_CLASS)
.attr('fill', _chart.getColor)
.attr('r', function (d) {
return _chart.bubbleR(d);
})
.attr('opacity', function (d) {
return (_chart.bubbleR(d) > 0) ? 1 : 0;
});
_chart.doUpdateLabels(bubbleG);
_chart.doUpdateTitles(bubbleG);
}
function removeNodes (bubbleG) {
bubbleG.exit().remove();
}
function bubbleX (d) {
var x = _chart.x()(_chart.keyAccessor()(d));
if (isNaN(x)) {
x = 0;
}
return x;
}
function bubbleY (d) {
var y = _chart.y()(_chart.valueAccessor()(d));
if (isNaN(y)) {
y = 0;
}
return y;
}
_chart.renderBrush = function () {
// override default x axis brush from parent chart
};
_chart.redrawBrush = function () {
// override default x axis brush from parent chart
_chart.fadeDeselectedArea();
};
return _chart.anchor(parent, chartGroup);
};