-
Notifications
You must be signed in to change notification settings - Fork 87
chart attach
When creating a new d3.chart based chart constructor, you may want to use charts that already exist by composing them together. For example, if one has the following two charts:
-
BarChart
- It draws a basic bar chart -
PieChart
- It draws a basic pie chart
You may combine them so that both charts are rendered together with one draw call with a new chart called PieBars
that you can instantiate like so:
var data = {
totals: [
{ name : "Red", value : 40, p : 0.4 },
{ name : "Blue", value : 80, p : 0.23 },
{ name : "Pink", value : 30, p : 0.37 }
]
};
var chart = d3.select("#chart")
.chart('PieBars')
.height(400)
.width(400);
chart.draw(data.totals);
Now in order to define our new PieBars
chart, we would want to initialize our pie chart and our bar chart, and then use the attach
method to attach them to their parent chart.
The attach
method takes two arguments, a unique string name that identifies the chart and an instance of a chart to attach. For example:
(function() {
d3.chart("PieBars", {
initialize: function() {
var chart = this;
var svg = chart.base.append("svg");
// create new containers for each of the charts
var bases = {
bar: svg.append("g").classed("bar", true),
pie: svg.append("g").classed("pie", true)
};
// initialize the charts with their required setters/getters.
chart.charts = {
bargraph : bases.bar
.chart('Barchart')
.yFormat(d3.format("d")),
piechart : bases.pie
.chart('PieChart')
.colors(d3.scale.category10())
};
// attach the charts under a specific name to the parent chart
chart.attach("bar", chart.charts.bargraph);
chart.attach("pie", chart.charts.piechart);
}
});
When defining a chart that contains attached charts, you may need to transform your data for those specific charts. For example our original data looks like so:
[
{ name : "Red", value : 40, p : 0.4 },
{ name : "Blue", value : 80, p : 0.23 },
{ name : "Pink", value : 30, p : 0.37 }
]
Our BarChart
expects our data to look like so:
[
{ name : "someName", value : 40 }, ...
]
And our PieChart
expects our data to look like so:
[
{ name : "someName", value : 0.4 }, ...
]
Unfortunetly, we already have our "value" property defined correctly for BarChart
but not for PieChart
. In order to fix that as a chart author, you can add a demux
method that takes in a chart name and the original data. It should return the set of data that would be appropriate for that chart. In our case, we could:
demux: function(name, data) {
// for a bar chart, we can just return the data as is since it has the
// "value" property we need.
if (name === "bar") {
return data;
} else {
// for the pie chart, we need to remap the data so that our "p" attribute
// is actually mapped to a "value" property.
return data.map(function(d) {
return { name : d.name, value: d.p };
});
}
},