The C3 API focuses on a declaritve style API where most options and functionality callbacks
are specified in an options object. A visualization is created by instantiating one of the
visualization types from the C3 collection. When constructing with new
, pass in
a single argument that is the options object. The specific options supported vary based on
the type of visualization and are documented in the API Reference.
During creation, options in this options object become properties of your instantiated
visulization object for future reference or modification. Once you have created your object,
then just call render()
on it to actually render the chart.
That's all you need to do!
There are a few other standard methods available to update the chart if you want to make it
more dynamic such as resizing, updating the dataset, restyling it, etc.
For example:
var my_chart = new c3.Plot({ anchor: '#scatter_plot_example', height: 300, width: '50%', data: student_data, ... // Options to specify what the new chart should be }); my_chart.render(); // Render your new chart!
Attaching to the DOM
A visualization object needs to be attached to the DOM to actually be visible in your document.
There are a few of ways of doing this. The anchor
option can specify
an HTML DOM element which the visualization will attach to as a child when rendering.
Alternatively the anchor
option could specify a string which represents a CSS
selector that specifies the DOM node that should be attached to when rendering.
Example anchor
option values:
- '#my_node'
- document.querySelector('#my_node')
- $('my_node')[0]
- $('<div id="my_node"></div>').appendTo('#your_node')[0]
- d3.select('#my_node').node()
- d3.select('#your_node').append('div').attr('id','my_node').node()
If no anchor
option is specified, then C3 will create a new <div>
element to contain the visualiztion. This element will not be attached to the DOM, but
will be accessible as the anchor
property of the visualization object for you
to attach to the DOM when and where you wish.
The visualization will be sized based on the size you specify via the height
and width
options. If you do not specify a size then it will use the size
of anchor element. If the anchor element is not attached to the DOM it may not have a size,
in this case you may need to resize the chart after attaching to the DOM.
Methods
The standard visualization API contains the following methods:
render([options])
-
The primary method used to actually render the visualization.
This should generally only be called once to initialize the visualization object. However, some visualizations with multiple layers may need to have
render()
called again if the set of layers changes.The
render
call optionally takes an additional options object that will be merged for additional options or potentially override options used when the object was created. resize([width, height])
-
Resize the visualization.
The visualization will be resized to match the current size of the anchor element. Optionally, a
width
andheight
can be specified to explicitly set a new size for the anchor element.For performance reasons, a
resize
operation will attempt to perform minimal work resizing and repositioning elements. Therefore, it may not reflect changes in the data set or other changed options. Use the other methods below for those types of changes.// Resize your chart when the window resizes window.onresize = function() { my_chart.resize(); }
redraw([origin])
-
A method to redraw the visualization to reflect a modified dataset or added/removed
dataset elements. It should also be used after modifying the some of the visualization object's
options after initial rendering, such as modified scales, modified accessors, etc.
Some visualizations support animations for modified/added/removed data. These animations generally need to be explicitly enabled in the C3 selection options.
An optional
origin
string may be used by some visualizations for optimizations. For performance reasons,redraw()
may not update the styles of existing elements. Userestyle()
for this.student_data.push({ name: "Bella", gender: "female", age: 27, grade: 3.4 }); my_chart.redraw();
restyle()
- Update the CSS styles and classes of all data elements to reflect what is specified in the C3 Selection Options. Use this either if you change the selection options or you change the data that might affect their dynamic styling based on the selection options.
Some visualizations may offer aditional methods.
For example, a selectable data table may offer a select()
method or
a zoomable chart may offer a zoom()
method.
These will be documented in the API Reference.
Data Sets
The data for a visualization is generally provided via a data
option.
It usually refers to an array of objects, but there isn't a restriction on the type
of objects. They could be simple numbers or complex nested structures.
Each visualization will have some set of appropriate options that allow you to specify
the shape of the data, or how to access that concept from the dataset.
For example, a scatter plot might have x
and y
options to
get the x and y positions of each data point and an r
option to get the radius
of the circle for each datapoint. These types of options can usually take constants as
values, such as saying all data point circles have a radius of 10. Or they can take
a callback function. The function you specify will be called for eash element in your
data
array and passed the data element as the first argument. Your callback
function should return the desired value for that data element.
Some visualization options also support calling the callback functions with additional
parameters. Often the second argument will be the index of the element in the
data
array. Though, some visualisations or combination of options do not
support this, such as enabling a filter
option.
So, a simple example scatter plot layer options might look like:
Because each visualization type may need slightly different configuration options, please refer to the API Reference documentation for details.... data: [ { name: "Joe", gender: "male", age: 16, grade: 3.2 }, { name: "Lisa", gender: "female", age: 18, grade: 2.3 }, { name: "Patrick", gender: "male", age: 28, grade: 1.2 }, { name: "Mandy", gender: "female", age: 32, grade: 3.8 }, { name: "Tommy", gender: "male", age: 9, grade: 1.7 }, ], x: function(d) { return d.age; }, y: function(d) { return d.grade; }, r: 10, filter: function(d) { return d.age >= 16; }, ...
Scales
Most visualizations contain a set of options for scales. XY plots have h
and v
for the horizontal and vertical scales. Polar charts have
r
and t
for the radial and angular scales.
C3 uses D3 scales for its scales.
A scale simply takes an input domain
value and provides an output range value. The extents of the domain and
range values are used to perform the conversion. So, if the x values of a scatter
plot might vary between 0 and 10 the domain of the horizontal scale may be
[0,10]
, this represents the x-axis. The range of the horizontal
dimension would be based on the current pixel width of the chart. C3 takes care of
properly setting the ranges of the scales, so you only have to worry about setting the domain.
The domains default to [0,1]
.
The most common scale type is linear
.
A linear scale performs a simple extrapolation from the input domain to the output range.
If the horizontal domain is [0,10]
and the chart width is 100 pixels,
then an x value of 2 will translate to 20 pixels, and so on.
But, D3 also provides other scale types such as
log
,
pow
,
and even ordinal
.
An example scatter plot may have the following scale options:
... h: d3.scale.linear().domain([0,50]), v: d3.scale.linear().domain([0,4]), ...
Layers
XY Plots and Polar charts support composition of multiple layers. For example, a plot might contain an area graph layer with a bar chart layer on top and a line layer on top of that.
Layers are specified as an array of layer objects. The order of the layers in the array
represents the z ordering of the layers.
Layers objects are created much like visualization objects. The desired layer type should
be instantiated with new
and the constructor should be passed an options object.
Layers can inherit some options from their parent chart such as the scales and some
dataset accessor options; or, they can override them.
Our scatter plot example might have two layers:
... layers: [ new c3.Plot.Layer.Scatter({ ... }), new c3.Plot.Layer.Line.Horizontal({ data: [2.67], value: function(d) { return d; }, }), ], ...
Similar to layers, plots also support configuring axes via the axes
option, which should be an array of c3.Axis
objects.
Selection Options
C3 creates and configures visual elements using C3 Selections, which are an abstraction of D3 Selections. The C3 Selections are user configurable using C3 Selection Options.
Visualization will expose options for the various visual elements that are part of that particular
visualization. For example, a table has options for table_options
for the
overall <table>
element, header_options
for the header
<th>
elements, row_options
for the <tr>
elements,
cell_options
for <td>
, and so forth.
A plot chart has an options
option for the overall chart <svg>
element,
layer_options
for the SVG <g>
element for each layer, and so on.
A scatter plot layer also has an overall options
option as well as
point_options
for the SVG <g>
element for each data point,
circle_options
for the SVG <circle>
element in each data point,
label_options
for the SVG <text>
element in each data point,
and so on and so forth. Each different visualization may use a different set of visual elements
so please refer to the API Reference for details on a particular visualization.
The C3 Selection Options is an object that
contains can contain a set of optional properties for you to configure.
Like the data set options, the selection options can generally be provided either as a
constant value or a callback function. The callback functions will be called for each
element in the selection. The first parameter it is called with is the data
assocated with that item in the selection. This varies based on the selection.
The layer_options
callbacks would call with the layer object, the
scatter plot circle_options
would call with the data element from the user
data set bound to that data point, while it isn't applicable to the overall options
.
Depending on the visualization, additional parameters might also be provided such as the
index of the data element into the dataset array, the associated column number for a
cell in the table, etc.
Some example selection options properties include:
text
-
The
innerText
content of the element. Useful for selections for SVG text labels, table cells, etc. html
-
Similar to the
text
option except that it specifies the rawinnerHTML
instead of just text. You can use this to create nested elements, such as styling with<b>
tags. Please be careful with this option as you may need to escape characters to properly render in HTML as appropriate and may need to guard against untrusted string sources which could expose you to creating<script>
tags and executing untrusted code. title
- Specify content for tooltips.
animate
-
A boolean value to
enable any animations for these visual elements that may be supported by the visualization.
For example, new datapoints could fade into existence or smoothly change locations if
their values change during a
redraw()
. duration
- A numeric value for the duration in milliseconds that any enabled animations should take.
class, classes, styles, events
- Additional selection option properties are available and discussed in later sections.
A scatter plot layer might include the following options:
... point_options: { animate: true, duration: 1000, }, label_options : { text: function(d) { return d.grade; }, }, ...
Styling
C3 offers a variety of mechanisms to style your visualizations. The end result is to style the visual elements from each C3 Selection with CSS styles as desired. Because everything is done directly with CSS styles, C3 automatically supports whatever CSS functionality the browser it is executing within supports. Different approaches have different performance and flexibility tradeoffs.
-
By including
c3.css
, various important default styles are set. Most of these are used for functional purposes. It is the intention of C3 to not impose opinionated styles. So, the default styles will be very minimal or nonexistant. -
You may include your own style sheets,
<style>
tags, orstyle
attributes to specify CSS styles. C3 visualizations have thec3
class as well as a set of classes based on the visualization type hierarchy to help constrain your CSS selector rules. For example, to style the fill color for all area graphs you could use the CSS rule:.c3.plot .layer.area path { fill: red; }
-
If you want to style some charts or layers in different ways, then you can setup
CSS rules for individual charts and layers. To aid this, charts and layers have a
class
option and C3 Selection Options include aclass
property to set a CSS class for those elements. Selection Options also offer aclasses
property for more sophisticated classing. This option should actually itself be a JavaScript object. The keys of the object represent possible CSS class names while the values are a boolean or a callback function returning a boolean that determines if the element has that class assigned to it.... class: 'average-grade', circle_options: { classes: { 'passing': function(d) { return d.grade >= 2; }, 'failing': function(d) { return d.grade < 2; } } }, ...
-
To individually set styles for each element based on the data, Selection Options offer
a
styles
property. This property should be assigned a JavaScript object. The keys represent the CSS styles that you would like to set for each element. The values can be constants or callback functions. As before, the first parameter of the callback function is the data bound to that element and additional paremeters may be also used for the index into the data set array, table column, etc.... circle_options: { styles: { 'opacity': 1, 'fill': function(d) { return d.gender==="male" ? 'blue' : 'pink'; } } }, ...
- Styles can also be adjusted manually using D3, JQuery, JavaScript DOM API, or your favorite DOM and CSS manipulation using the extensibility features desribed below.
Events
You can create customized interactive behavior by attaching event handlers to the visual
elements using the events
property of the Selection Options.
Like CSS styles, C3 follows the D3 philosophy of exposing native
DOM events.
So, C3 automatically supports whatever DOM events that your browser supports.
Set events for the options
or content_options
to attach
events to respond to the entire visualization or layer. Or, you can set events
for a more specific Selection Options to set behavior for those element types in the visualization.
The events
option should be set fo a JavaScript object. The keys in the object
represent the event name. Values should be the event handler callback function to attach
to the DOM element that will be called when the event is triggered. For the callback, the
this
context will be set to the DOM element. The first parameter will be
the data element bound to the DOM element. Additional parameters may also be provided
such as the index into the data array, etc.
Some examples:
... options: { events: { 'mousemove': function() { ... } }, }, circle_options: { events: { 'mouseenter': function() { d3.select(this).transition().duration(500).attr('r', 20); }, 'mouseleave': function() { d3.select(this).transition().duration(500).attr('r', 10); }, 'click': function(d) { alert("You clicked on " + d.name); } }, }, ...
Other Options
Different visualization types may have other options for enabling additional functionality, data decimation, performnace optimizations, etc. Please refer to the API Reference for each visualization type.
For example, straight line layers support enabling draggability:
... draggable: true, handlers: { drag: function(d) { ... } }, ...
Extensibility
If the built-in functionality is not sufficient C3 provides a mechanism for extending custom behavior. C3 visualizations and layers will fire events for which you can register callback handlers. With these callbacks you can manipulate the visualization's Selections using D3, JQuery, the raw JavaScript DOM API, or your other favorite DOM and CSS manipulation technique.
The handlers can be set declaratively by setting the
handlers
option for the
visualization or layer. Or, alternatively, you can set them imperatively by
calling on()
with your
instantiated visualization or layer. The visualization or layer object will also be the
this
context for the callback function.
Registering an event handler again with the same name will replace the original handler.
However, like D3, you can provide a namespace to the event name to allow multiple
handlers to trigger for the same event. For example, you can register both
redraw.foo
and redraw.bar
. You can remove an event handler by
using a value of null
in place of the callback function.
The following are the built-in base extension events:
render_start
- Called for one-time intialization. This event fires before any built-in actions are taken.
render
- Called for one-time intialization. This event fires after built-in initialization, but before the initial sizing and placement of the data elements.
rendered
- Called for one-time initialization. This event fires after the visualization is completely rendered.
resize_start
- This event fires when the visualization is resized, but before any built-in actions are taken.
resize
- This event fires after the visualization resizes.
redraw_start
- This event fires before the data elements are placed into the visualization. This can be caused by rendering, resizing, redrawing, or other actions such as zooming, rebasing, etc.
redraw
- This event fires after data elements are placed into the visualization. This can be caused by rendering, resizing, redrawing, or other actions such as zooming, rebasing, etc.
restyle_start
- This event fires before data elements are styled.
restyle
- This event fires after data elements are styled.
Some visualization may expose additional functionality that offers additional events.
For example a zoomable chart may offer zoomstart
, zoom
,
and zoomend
events while a draggable
layer may offer
dragstart
, drag
, and dragend
events.
Please refer to the various visualizations in the API Reference for more details.
Example
Pulling together all of the concepts discussed above, the following is a scatter plot example (view annotated source with axes, guidelines, and click events added):
var student_data = [ { name: "Joe", gender: "male", age: 16, grade: 3.2 }, { name: "Lisa", gender: "female", age: 18, grade: 2.3 }, { name: "Patrick", gender: "male", age: 28, grade: 1.2 }, { name: "Mandy", gender: "female", age: 32, grade: 3.8 }, { name: "Tommy", gender: "male", age: 9, grade: 1.7 }, ]; var my_chart = new c3.Plot({ anchor: '#scatter_plot_example', height: 300, width: '50%', h: d3.scale.linear().domain([0,50]), v: d3.scale.linear().domain([0,4]), layers: [ new c3.Plot.Layer.Scatter({ data: student_data, x: function(d) { return d.age; }, y: function(d) { return d.grade; }, r: 10, filter: function(d) { return d.age >= 16; }, point_options: { animate: true, duration: 1000, }, label_options : { text: function(d) { return d.grade; }, }, circle_options: { classes: { 'passing': function(d) { return d.grade >= 2; }, 'failing': function(d) { return d.grade < 2; }, } styles: { 'fill': function(d) { return d.gender==="male" ? 'blue' : 'pink'; } }, events: { 'mouseenter': function() { d3.select(this).transition().duration(500).attr('r', 20); }, 'mouseleave': function() { d3.select(this).transition().duration(500).attr('r', 10); }, 'click': function(d) { alert("You clicked on " + d.name); } }, }, }), new c3.Plot.Layer.Line.Horizontal({ data: [2.67], value: function(d) { return d; }, class: 'average-grade', handlers: { redraw_start: function () { var students = student_data.filter((student) => student.age >= 16); var average_grade = d3.sum(students, (student) => student.grade) / students.length; this.data = isNaN(average_grade) ? [] : [average_grade]; }, }, }), ], }); // Render your new chart! my_chart.render(); // Resize your chart when the window resizes window.onresize = function() { my_chart.resize(); } // Add a new student and redraw student_data.push({ name: "Bella", gender: "female", age: 27, grade: 3.4 }); my_chart.redraw();
View other C3 Examples.