-
Notifications
You must be signed in to change notification settings - Fork 42
Getting started
Wiki ▸ Getting Started
#Getting Started
Polychart.js is a flexible library for plotting interactive charts. This tutorial will go through the basics of how to create a chart, and how to tweak it to your liking. We will do this by examples: each example contains a plot, the code, and an explanation of what the code does.
Notice that all charts here are actually PNG images, so to view interactive charts, go to the demo page.
##1. A Simple Bar Chart
Let's start with creating a simple bar chart.
var searchterms = polyjs.data({
term: ["Flower", "Chocolate", "Candy", "Valentine"],
count: [16600000, 9140000, 7480000, 5000000]
});
polyjs.chart({
layer: {
data: searchterms,
type: "bar",
x: "term",
y: "count"
},
title: "Monthly Google Search",
dom: "chart",
width: 300,
height: 250
});
The first function call is to the polyjs.data()
function, which
creates a wrapper on a dataset. This function takes a dataset in
JSON or other formats, and turns it into a data object that
Polychart.js can recognize.
The second function call actually creates the chart.
The polyjs.chart()
function takes a specification
and uses it to determine how to render the appropriate chart.
A layer contains information about what is to be plotted. We pass in the
data set object created earlier, and also tells Polychart.js that we would like
to plot a bar chart, with the variable term
mapped to the x-axis and
the variable count
mapped to the y-axis.
If we had changed the chart type to a line
or a point
, we would get
one of the below charts:
If you want to create a simple chart, then that is all there is!
##2. Aesthetic Mappings and Guides
One different between Polychart and most charting libraries is how easy it is to map data directly to some feature of items in a chart, like color, size, or opacity. We bind data to these features called aesthetics much like we do to the x and y-axes:
var countries = polyjs.data([
{ country: "Canada", population: 33476688, area: 9984670, GDP: 1770000000 },
{ country: "United States", population: 315591000, area: 9826675, GDP: 15609700000},
{ country: "Australia", population: 21507717 , area: 7692024, GDP: 915098000000},
{ country: "China", population: 1353821000, area: 9706961, GDP: 8250000000000}
]);
polyjs.chart({
layer: {
data: countries,
type: "point",
x: "population",
y: "area",
color: "country",
size: "GDP"
},
guide: {
x: { min: -50000000, max: 1500000000 },
y: { min: 7000000, max: 10500000 }
},
title: "Selected Countries",
dom: "chart",
width: 500,
height: 250
});
Notice that in the layer
definition, we mapped the aesthetic color
to the
data column country
, and the aestehtic size
to the data column GDP
.
Legends were generated automatically by Polychart.js.
Notice also the specification of guides. Whereas layers contain information about what is to be plotted, guides specify how that information should look like on the screen. In this example we specified the minimum and maximum value of the x- and y-axes. We can also use it to specify ticks on the axes, axes titles, the scales or actual method in which data is mapped to the aesthetics, and other options. We will see more examples of guide specifications shortly.
##3. Multiple Layers, Statistics & Aggregation
With Polychart, multiple layers can be rendered, one on top of another. Here is an example:
var sales = polyjs.data({
date: ["2013-01-02", "2013-01-06", "2013-01-08", "2013-01-21", "2013-01-28",
"2013-02-01", "2013-02-17", "2013-02-21", "2013-03-11", "2013-03-12",
"2013-04-10", "2013-04-17", "2013-04-21"],
sale: [23, 23, 20, 13, 43, 33, 53, 62, 108, 98, 22, 22, 13]
});
polyjs.chart({
layers: [
{
data: sales,
type: "bar",
x: "bin(date, 'month')",
y: "sum(sale)",
color: { const: "steelblue"},
opacity: { const: 0.8}
} , {
data: sales,
type: "point",
x: "date",
y: "sale",
color: { const: "green"},
size: { const: 3 }
}
],
title: "Sales",
dom: "chart",
width: 500,
height: 250
});
There are several new concepts here. Notice first that instead of specifying a single
layer, we specified an array layers
, where each item specifies one layer. Each layer
has its own data set (which could be different, even though in this example it is the
same), its own type, and its own mappings.
This gives you, the developer, a lot of flexibility in terms of the types of visualizations that can be made. But with great power comes great responsibility. You must ensure that different layers map the same type of data to each aesthetic. That is, x-axis mapping of all layers must have the same type (numeric, string/categorical, or datetime), and similarily for y-axis mapping, colour, size, etc.
Another new concept is the idea of aggregation. Notice in the bar chart that we are displaying the sum of sales for each month. This aggregation is done by the Polychart.js library. Notice also that we are binning the x-axis by month, so that Polychart.js knows how wide each bar of the bar chart should be. For more information on how data aggregation and transformation works, read Data Transforms and Statistics here.
A third concept is that of assigning constants to aesthetics. For example here, we are
fixing the colour of the bars to "steelblue". (Notice that if we simply wrote
color: "steelblue"
, Polychart.js will interpret this as mapping the aesthetic
to a data column called steelblue
).
##4. Interaction
Because all of the charts here are actually static images (which cannot be interactive), we will take a look at one of the charts on our demo page.
Ok, deep breath, I chose perhaps the most complicated example on the demo page, so we will go through the example in stages. (You do not have to read all the code at once!)
In the first section of the code, we prepare the data by turning it into a Polychart.js
data object. We also create a new data column called type
using the data.derive()
function.
In the second section, we specify the charts. Notice that the polyjs.chart()
function
actually returns a chart object that we can store and later use, and that the three
charts are called subcontinent
, yearly
, and breakdown
.
We are also storing the chart specifications in addition to the chart objects.
This is because later on, we will be referring
to the specification, and changing the chart by changing the specifications.
Now, part three is where the real magic happens. Let us first look at the show_breakdown
function. This function is the second to be defined, and it is used at the very bottom
of the code yearly.addHandler(show_breakdown);
. The function yearly.addHandler()
presumes that the parameter is passed in is an event handler, and will call the event
handler every time a user interacts with the chart yearly
in some way.
The show_breakdown
function (the event handler) takes two arguments, the event type
,
and the underlying Raphael object e
with which the user interacted with. The object e
,
if it exists, has an attribute e.evtData
that describes, in Polychart.js
filter notation, the subset of data represented by the object.
In the definition of the show_breakdown
function, we see that this function
does something only whne the event type is click
(when a user clicks on
some object), and when the clicked object filters the data based on the
data column year
. When both conditions hold, the spec for the breakdown
chart is changed, and we call breakdown.make()
with the new specification
to animate the chart to the new state.
The event handler show_country
works in a similar faction. When
the event type is either click
(a chart item is clicked) or guide-click
(a legend item is clicked), then the specification for both yearly
and
subcontinent
are changed (data is filtered, y-axis max and min are reset,
and color scale function is changed). Likewise when the event type
is reset
(a click occured in a blank space), changes to the
same charts are made.
The yscale_toggle
function is simplist of the three, acting only on
a the single chart whose event the handler listens to. Unlike the other
two functions, however, this handler has some state attached to it: when
the max/min values are set, the function unsets it; when the max/min
values are not set, the function sets it to the saved values.
##5. Faceting, AJAX
The example below shows the concept of faceting - or dividing a chart into multiple, smaller charts based on some variable. Here, the chart is subdivided into three, one for each category/specie of flowers.
var iris = polyjs.data('/some/ajax/endpoint.json');
// var iris = [
// {"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.2,"category":"setosa"},
// {"sepalLength":4.9,"sepalWidth":3,"petalLength":1.4,"petalWidth":0.2,"category":"setosa"},
// ...
// ];
polyjs.chart({
layer: {
data: iris,
type: "point",
x: "sepalLength",
y: "sepalWidth",
color: "category",
opacity: { const: 0.5 }
},
facet: {
type: "wrap",
var: "category",
formatter: function(facetObject) {
var title = facetObject.category;
return title;
}
},
dom: "chart",
width: 700,
height: 250
});
The example also shows that data can be retrieved from an AJAX endpoint. In this example the endpoint supposedly provides JSON formatted data. CSV data will do just as well.
##6. Coordinates
Thus far, all of our plots have been plotted on a cartesian coordinate system, with data mapped primarily to the x- and y-axes. For other chart types such as pie chart, spider plots, and map projects (eventually when it is supported), we may wish to use a different coordinate system. Currently, polar coordinates are supported.
Pie chart is an example of a chart that uses polar coordinates. Here is a very simple example of a pie chart (which with Polychart.js is actually a stacked bar chart in polar coordinates).
var data = polyjs.data([
{ category: "A", percent: 25 },
{ category: "B", percent: 75 }
]);
polyjs.chart({
layer: {
data: data,
type: 'bar',
color: "category",
y: "percent"
},
coord: {
type: "polar",
},
guide: {
x: { position: 'none', padding: 0.5 },
y: { position: 'none' }
},
dom: "chart",
width: 300,
height: 250
});