-
Notifications
You must be signed in to change notification settings - Fork 0
axisChartCustom
Wiki › Charts › Axis Chart › Custom
By using the following example, you can create your own custom axisChart-type.
Before creating your own, you will need a basic understanding of the d3-workflow. To learn some of the d3 basics, visit Mike Bostock's Let's Make a Bar Chart tutorial.
There are several reasons to create your own axisChart-type rather than starting a d3 visualization from scratch:
- Consistency - if you are already using the d2b.js library for other visualizations, the custom axisChart api will help maintain consistency between this chart and the other d2b charts. Also, the new axisChart-type will automatically be supported by d2b dashboards and other d2b features that might use the axisChart.
- Built in Functionality - the axisChart has a suite of built in functions readily available. These include a legend, axes, custom axes/legend positioning, hiding/showing individual graphs, auto plane re-scaling.
- Easy Transitions - easily transition your custom chart type from one state to the next with each new data set using
axisChart.update(). - Overlay Different Graphs - overlay multiple axisChart-types on top of one another for easy comparison.
To create a custom axisChart-type you need to clone the template constructor and define it as your custom constructor. For this tutorial the custom constructor will be called customLine, it will be used to graph a simple d3 line and dots corresponding to each {x,y} point.
d2b.UTILS.AXISCHART.TYPES.customLine = d2b.UTILS.AXISCHART.TYPES.template.clone();Then 3 chart helpers need to be defined.
d2b.UTILS.AXISCHART.TYPES.customLine.xValues = function(chart){
// This is where the x-values are returned to the main axisChart to
// define the x domain
}d2b.UTILS.AXISCHART.TYPES.customLine.yValues = function(chart){
// This is where the y-values are returned to the main axisChart to
// define the y domain
}d2b.UTILS.AXISCHART.TYPES.customLine.update = function(chart){
// This is where you will update the graph containers 'this.background'
// and 'this.foreground' with the custom visualization
}The helper functions above are given several attributes to help with the graph creation and customization.
-
chart- axisChart-type constructor object. -
chart.update- useful if you need to update the custom axisChart-type, used likechart.update().
-
this- axisChart-type variable store. -
this.currentChartData- an array of different graph data that falls under this custom axisChart-type. This is contains 'customLine'graphsarray in the example below. -
this.background- d3.selection of the axisChart-type backgrounds, this is where the larger less vital graph components may reside, each background has the corresponding graph data bound to it. -
this.foreground- d3.selection of the axisChart-type foregrounds, this is where the smaller more vital graph components may reside, each foreground has the corresponding graph data bound to it. -
this.animationDuration- the general (ms) animation duration used for the axisChart. -
this.xFormat- the format helper for x values, used likethis.xFormat(x). -
this.yFormat- the format helper for y values, used likethis.yFormat(y). -
this.color- the color scale to hash the graph labels for corresponding colors. -
this.x- contains several properties for retrieving information regarding the x-axis. -
this.x.customScale- the scale to map x values into the visual space, used likethis.x.customScale(x[,boolean]). If boolean is supplied return the inverse position, this is the same as usingthis.width - this.x.customScale(x). -
this.x.type- scale type (e.g. 'time', 'ordinal', 'quantitative,linear', ..). -
this.x.orientation- orientation of the axis (e.g. 'bottom', 'top', 'left', 'right'). -
this.x.hide- flag indicating whether the x-axis is hidden or not. -
this.x.label- x-axis label. -
this.x.rangeBand- a custom rangeband that may be used for setting a maximum horizontal span. -
this.x.scale- the original d3 scale, recommended to use the customScale instead. -
this.y- contains several properties for retrieving information regarding the y-axis. -
this.y.customScale- the scale to map x values into the visual space, used like.this.y.customScale(y[,boolean]). If boolean is supplied return the inverse position, this is the same as usingthis.height - this.y.customScale(y). -
this.y.customBarScale- the y property has an optional bar scale which helps with placing vertical bars, used likethis.y.customBarScale(y). This will return an object of the desired y position and height of the bar{y: , height: }. Has support for negative values, but currently does not support non-quantitative y-scales. -
this.y.type- scale type (e.g. 'time', 'ordinal', 'quantitative,linear', ..). -
this.y.orientation- orientation of the axis (e.g. 'bottom', 'top', 'left', 'right'). -
this.y.hide- flag indicating whether the y-axis is hidden or not. -
this.y.label- y-axis label. -
this.y.rangeBand- a custom rangeband that may be used for setting a maximum horizontal span. -
this.y.scale- the original d3 scale, recommended to use the customScale instead.
-
this.width- the context area (px) width. -
this.height- the context area (px) height. -
this.on- the event object for binding 'elementClick', 'elementMouseover', 'elementMouseout' events on the individual chart components. -
this.control- the controls object to see if the chart controls (e.g. checkboxes, radio-buttons) are asserted. -
this.axisChart- the master axisChart that is registering all of the axisChart-types including this one, useful if you need to update the entire axisChart withthis.axisChart.update().
This tutorial shows you how to create a custom line-chart with circle indicators at the specified points. If you include the necessary libraries and copy this code example into an HTML page, it should display 2 simple line graphs on top of each other.
Make sure to have d2b.js, d2b.css, d3, and jQuery installed for the example below.

<script>
// clone the template axisChart-type into your own custom axisChart type
// in this case, the new axisChart-type is denoted by 'customLine'
d2b.UTILS.AXISCHART.TYPES.customLine = d2b.UTILS.AXISCHART.TYPES.template.clone();
// return the set of discrete x-values that are used by your chart
// this allows the axisChart to properly auto-scale the domain
d2b.UTILS.AXISCHART.TYPES.customLine.xValues = function(chart){
var values = [];
//iterate through each graph if the current axisChart-type
this.currentChartData.forEach(function(d){
//map the x values stored in d.values to a single array
values = values.concat(d.values.map(function(v){return v.x}));
});
return values;
};
// do the same for the y-values
d2b.UTILS.AXISCHART.TYPES.customLine.yValues = function(chart){
var values = [];
//iterate through each graph if the current axisChart-type
this.currentChartData.forEach(function(d){
//map the x values stored in d.values to a single array
values = values.concat(d.values.map(function(v){return v.y}));
});
return values;
};
// define the update function
d2b.UTILS.AXISCHART.TYPES.customLine.update = function(chart){
// save the current chart variable store as _self
var _self = this;
// defind the d3 line
// note: I am using the custom x scale provided by '_self' to translate the
// specified x and y value for each point in the data to the visual
// space.
var line = d3.svg.line()
.x(function(d) { return _self.x.customScale(d.x); })
.y(function(d) { return _self.y.customScale(d.y); });
// iterate through each of the background containers
// note: this example places the line itself to be in the 'background'
// and the circles representing each point to be in the 'foreground'
_self.background.each(function(graphData){
var graph = d3.select(this);
// note: now graphData has the specified data for each graph, and graph
// holds the d3 selection of the current background container.
// using d3 perform the common selectAll -> data workflow to setup the
// enter->update->exit
var path = graph.selectAll('path').data([graphData.values]);
// enter on the unmatched path, if any
// note: The stroke color is set to the provided _self.color scale hashed
// by the label if the current graph.
path.enter()
.append('path')
.style('stroke',_self.color(graphData.label))
.style('fill','none');
// transition the path to the new 'd' attribute
path
.transition()
.duration(_self.animationDuration)
.attr('d',line);
});
// iterate through each of the foreground containers
// again the point-circles will go in the foreground container
_self.foreground.each(function(graphData){
var graph = d3.select(this);
// setup the enter->update->exit for the circles
var circle = graph.selectAll('circle').data(graphData.values);
// enter new circles with the proper graph fill and a radius of 4
circle.enter()
.append('circle')
.style('fill',_self.color(graphData.label))
.attr('r','4');
// update the position of each circle by using the _self.x.customScale
circle
.transition()
.duration(_self.animationDuration)
.attr('cx',function(d){
return _self.x.customScale(d.x);
})
.attr('cy',function(d){
return _self.y.customScale(d.y);
});
// exit and remove any mismatched circles
circle.exit()
.transition()
.duration(_self.animationDuration)
.style('opacity',0)
.remove();
});
};
/*Now the new axisChart-type has been created, let's use it.*/
$(document).ready(function(){
// setup the data for the new customLine
var data = {
data:{
labels:{
x:'x',
y:'y'
},
types:[
{
type:'customLine',
graphs:[
{
// when creating your custom axisChart-type, you may place
// any data that might be required in here. The only thing that
// is mandatory is the label
label:'Custom Line 1',
values:[
{x:0, y:50},
{x:20, y:63},
{x:34, y:89}
]
},
{
label:'Custom Line 2',
values:[
{x:3, y:20},
{x:30, y:74},
{x:58, y:39},
{x:74, y:22}
]
}
]
}
]
}
}
// create the new axisChart
var axisChart = new d2b.CHARTS.axisChart();
// setup the axis chart with the data, selection, width, and height
axisChart
.data(data)
.select('.custom-axis-chart')
.width($(window).width())
.height($(window).height())
.update();
});
</script>
<body style='margin:0px;'>
<div class = 'custom-axis-chart'></div>
</body>
</html>