API Overview

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 and height 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. Use restyle() 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:

...
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; },
...
Because each visualization type may need slightly different configuration options, please refer to the API Reference documentation for details.

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 raw innerHTML 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.

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.