Hacker News new | past | comments | ask | show | jobs | submit login
C3.js: D3-based reusable chart library (c3js.org)
350 points by nekgrim on Aug 27, 2014 | hide | past | web | favorite | 80 comments

Out of raw d3.js, nvd3.js, cubism, and rickshaw.js, I've by far had the best experience with nvd3.

I was particularly pleased with the way nvd3 supports sliding data off line charts without any extra work.

D3.js is an excellent, low level visualization library. But you will find yourself spending days to a couple weeks with custom styling, tooltips, legends, etc. Many high level charting libraries are nice because they have this out of the box.

However, I want a library that lets me make visualizations that I can run on my monitor for 10 days straight without running into obscure bugs. Rickshaw failed me in this regard. I have a caching scheme in my client-side application. Rickshaw has its own local copy of data which requires the developer to write custom, messy javascript to evict. I found that rickshaw actually has some custom 'sliding window' logic. I was unhappy because I had to go to stackoverflow to discover that feature rather than using the documentation.

nvd3.js simply worked for me.

  > rickshaw actually has some custom 'sliding window' logic. 
  > I was unhappy because I had to go to stackoverflow to
  > discover that feature
The third example[0] on the Rickshaw "examples" page[1] is called "Interactive Real-Time Data", and shows the RangeSlider extension (and many more extensions) in use.

The rickshaw docs are heavy on usage, light on specification. That's a style I very much appreciate, but I also appreciate that it's not for everyone.

I also appreciate that its API doesn't make you take the range slider with you, if you don't want it. It's all additive, and you can go both directions (keep adding bits and blobs to the interface via plugins, or reach down into the D3 and SVG bits, or your data. Nothing is opaque there.)

What was your obscure bug with a long running Rickshaw? I have long running sliding window time series stuff that I typically run for as long as a Chrome release lasts, and it stays snappy.

0: http://code.shutterstock.com/rickshaw/examples/extensions.ht...

1: http://code.shutterstock.com/rickshaw/examples/

Does anyone know of a chart lib has the ability to make a "stacked" area chart where each series gets its own Y-axis, similar to cubism.js?

I like how cubism visualizes streams of data where each needs its own Y-axis but they are related on the X axis (usually a time domain.) However cubism's mechanism of updating is sort of weird, and each value needs to be one pixel. I tried to use d3's "streams" example but quickly got lost there.

On another note, I've had good luck using Rickshaw and updating the `graph.series[i].data` array using shift and push then re-calling `graph.render()`. This is what Rickshaw's `FixedDuration` appears to do under the covers (see source of this example http://code.shutterstock.com/rickshaw/examples/fixed.html) - but I don't actually use FixedDuration, just update the data array.

I think of those stacked charts as a stack of multiple charts that happen to share a timeline. With rickshaw I just stack a bunch of graphs on top of each other in the page, and give the bottom one an X axis.

Yup that's what I'm doing now as well.

The only downside to that strategy is you can't e.g. show a single y-axis with values for each chart when you hover over one the way cubism can. This is really handy for comparing values across series. Actually I just found a d3.horizon module which might do what I want, but I need to see if I could get multiple charts to share the same axis.

Maybe I should just go back to cubism but it doesn't really make sense when you don't have thousands of values that you want to be 1px wide.

We use nvd3 in an analytics dashboard with some success, and some troubles. Simple Excel-like behaviour, such as rotating the axis labels so they don't overlap, require lots and lots of tweaking.

Default bar/column chart settings occasionally give mystifying results, like the highest value in the chart plotting above the highest axis value (e.g. 23,600 plots above 22,000 instead of between 22-24k).

I'm sure we'll solve these issues, but they are eating up a bit of developer time for things we're used to having work out-of-the-box in something like Excel.

Does nvd3 have any documentation besides some basic examples? while c3 doesn't have a completely documented API atm, it atleast has a very extensive set of examples.

Check out c3 v0.3.0's source code. It's the closest thing to self documenting code I've seen so far. Any holes in the docs have been cleared up by grepping the source really quick.

Awesome post. I've been trying to learn D3 on weekends and it's been more than a little difficult to get everything behaving and looking exactly like I want.

We made a similar decision - evaluated many, chose nvd3.js. It needed a new custom chart definition, but it has been responding well for our use case (enterprise monitoring software).

have you tried dimple.js yet ? I used to use nvd3.js but switch to dimple because the charts seem to look more professional. it is definitely not as mature as nvd3.js though

nvd3.js is awesome. However It always crashes for very large dataset. I had to reduce my dataset size for nvd3.js to not crash, however programs like MATLAB has no problem visualising really large dataset where you can zoom to individual data point. Its in my TODO list to make nvd3.js handle large data set so that it can compete with MATLAB/Python.

Just happen to come by this today: http://i.imgur.com/5zE08DX.png

MATLAB gets more hate then it deserves. Do you know some of the language stuff in MATLAB are being adopted in the next iterating of javascript ? MATLAB has amazing consistency and a really good learning tool. It is really good for fast prototyping for numerical algorithms, its just very old.

Do you have any suggestions for alternatives for large datasets? I currently use Highstock, but it's pretty bad around ~100,000 individual points.

With those many points you'll probably need something that makes use of HTML Canvas, and not SVG which slows down if you plot that many elements.

Do you happen to have any recommendations?

For a simple scatterplot with many points I would probably simply use Canvas directly, and perhaps borrow elements from D3 like d3.scale to plot the axis labels. It is possible to use Canvas underneath to plot the 100,000 points, and SVG on top for other stuff like tooltips and brush selecting.

For dense data like that, you might give dygraphs a try.

The type of chart I've found most useful is heat map charts, and none of the charting library I've looked at provide that:

Here's an example from a Datadog dashboard: https://cloud.githubusercontent.com/assets/1189716/4064956/6...

I wish such a chart style was more common, it's so much more useful than a typical line chart of the median/p9x. Unfortunately, I'm not familiar enough with D3 and such to write my own; it would likely be crap.

I don't think it should be too difficult (not saying that d3 doesn't have a learning curve). There are some examples on the d3 gallery that would probably be close.

http://bl.ocks.org/mbostock/4060606 http://www.trulia.com/trends/2011/09/house-hunter-by-day-not... http://prcweb.co.uk/circularheatchart/ http://bl.ocks.org/tjdecke/5558084

Heck if you point me to a stock dataset I could probably code up a simple example that you could tweak. (no promises though ;)

For work, we had to fork jqplot to add features like heatmaps, zooming, etc.: https://github.com/scattering/jqplot.science

We also have the notion of "interactors" which allow you to add draggable widgets to a plot: http://ncnr.nist.gov/instruments/magik/calculators/calcR_wf....

To see the heatmap in action, you can look at: http://ncnr.nist.gov/ipeek/singleplotwindow.html?instrument=...

There are of course glitches, but hopefully you find some of this useful!

phpChart (http://phpchart.org) is a higher level charting library for jqplot if you don't wan to spend days to learn custom styling and scripting.

We made a decision to go with phpChart in June. It works well in our use case. We can still add custom javascript when something is outside its offered feature set.

Heatmaps are fairly easy to do with Bokeh, for instance: http://bokeh.pydata.org/docs/gallery/unemployment.html

Eh. In D3, just transform the data into X/Y coordinates, create a DIV for each one, and then change the background color based on the desired value.

I think it's d3.scale.color to automatically set up a gradient you plug a value into and get a color out.

Epoch can do realtime heatmaps: http://fastly.github.io/epoch/real-time/#heatmap

Looks pretty much like what I'm looking for, thanks!

Highcharts (free for non-commercial) has heat maps:


you may be able to reproduce a heatmap using this d3 extension.. it's called bubble matrix but both heatmaps and this bubble matrix are meant for displaying two dimensions of data


This totally goes against the whole point Mike Bostock (creator of D3) laid out when he talks about creating reusable charts...


"To sum up: implement charts as closures with getter-setter methods. Conveniently, this is the same pattern used by D3’s other reusable objects, including scales, layouts, shapes, axes, etc."

You get none of that with C3.js...

There are some things that you can't easily do with Mike Bostock's method. Namely, it's not a good format for storing, examining, and modifying charts. And that's perfectly fine. It's good for what it's good for. But not everyone has the same needs.

I build visualizations with d3.js for my clients (http://muyueh.com/42/), and I have always wonders whether I will be one day replaced by library such as c3.js.

I have been watching closely different library, and felt that most of the library are just providing default value to d3.js, plus adding some nice plug-in (such as tooltips). If we are looking for a bar chart, then it's very fast to use a bar chart library to build what we want. Yet some problems may occur:

1. Control, we thought that we need bar chart, but we actually need bar chart’. In my process of developing effective visual, I often need to access different part of the API.

2. Choice, currents charts provided by most of the library are available in Google Charts and Excel. This might a question of time: these library are fairly new, and maybe in the near future these library will provide all visualization available in the d3.js page. But maybe it’s not because of time, but of complexity. If these library were providing better abstraction, it should be easier to develop more complex charts.

3. Extendability: We probably don't just need the bar-chart as a stand alone visual, but as building block that can interact with other component (texts or maps).

An interesting question is to ask why d3.js was designed so “low level”, why not directly releasing a “high level library”? My hypothesis is that maybe this is the right level of abstraction. When you tried to get “higher”, you actually lose power/control over your visual. Maybe that’s the reason why people are sharing a lot of their work on http://bost.ocks.org/, doing some small experiments, laying down some building block, perhaps currently that is the most efficient way of building re-usable chart.

I shared my thought on the issue, in hope that people challenge my hypothesis: my current work depends on it.

I agree with your points, which is why I have been hesitant to try out these wrappers around d3.

It is nice to have tool tips and other bells and whistles outbid the box though. I wonder if anybody has tried to do a more complex visualization (hierarchical bar chart for example) in one of these wrappers?

Nice work. I really like http://muyueh.com/30/hexagon/

First find attempt I got 85 seconds Second 23 seconds Third 185

Thanks, that one together with Chernoff's facial hairs (http://muyueh.com/30/chernoff/) are two visuals that I really enjoyed doing, but a bit too "geek" for the average user (Your compliments was actually the first one I get from that graph).

It was part of my initiative 30 days of d3.js, a pretty solid way to learn d3.js by the way.

I don't intend to diminish the hard work you put into this. It looks clean and useable. Congratulations.

If you (people in general) are using d3 for simple charts you are doing it wrong.

d3 is a visualization library. It excels at helping you make non-trivial things. For the trivial there are some great chart libraries such as Highcharts. I build visualizations at work and for those I use d3. Whenever I need something as simple as a stacked area chart I simply use Excel or Highcharts. Everytime I've tried to use Highcharts for a complex viz, or d3 for a simple chart, it's been a waste of time. I've used NVD3 as well as some other D3 based charting packages. None of them are as simple as Excel or Highcharts IMHO.

Highcharts is amazing, but it is not distributable with open source software. My team at edX recently migrated away from Highcharts to nvd3 for this very reason. The state of charting is such that good packages are expensive. There are some mediocre packages for free. D3 is the only package we found that met our needs.

Using D3 for simple charts is not necessarily a waste of time -- I have a small collection of code for D3 charts I've made that I keep around and reuse as needed. Although they are simple they are tailored to the way I like simple charts to look like.

Careful, this has pretty much zero documentation and inconsistent options available for each chart type. I started a project with it and after a great start realised I had to scrap it all and start from scratch with some more complete alternative (haven't started looking yet).

I think thats why it's still at version 0.3

But they do have a lot of examples, a lot more than eg. nvd3.

It just got a lot better with v0.3.0. The code is much more organized and is basically documentation on its own. They also added the ability to call/modify/add internal functions externally so its much easier to build off of.

I like C3, but I discovered it has some major performance issues with thousands of data points a couple months back. It has something to do with the pie chart rendering code: https://github.com/masayuki0812/c3/issues/172#issuecomment-4...

I've been evaluating HighCharts, Vega, Rickshaw, NVD3, C3, but the one I've been impressed with in terms of performance thus far is Epoch: http://fastly.github.io/epoch/

I also like http://nvd3.org/. We almost now need an index of the various D3 based charting libraries.

How about a... chart?

We evaluated Rickshaw and Dimple (http://dimplejs.org/) for awhile (to migrate some custom charts initially built with D3.Chart http://misoproject.com/d3-chart/). We went with Dimple and I've been very pleased with it. There is ample documentation, the source code is readable, and the developer behind it is responsive to questions and issues. Also, it's very easy to get access to the underlying axes/series/legends/etc if you want to do more complicated work not provided out of the box and are familiar with d3. I would highly recommend it if you're looking for a d3 chart library.

I'm currently using this for a project. My only complaint is that there is no API documentation, so you just have to look for a relevant example every time you want to do something.

This is nice, easy to use. It is however only using an extremely limited subset of d3 capabilities, which makes me wonder what added value is brought by the fact of making this d3 based compared to other "pure" and lightweight chart libraries which have the same functions [1]

My usual go to library: Flot http://www.flotcharts.org/

I find it's usually easier to roll my own solution, because these libraries often don't provide the level of customisation I need (or may need in the future). The cost of moving away from them is also nonzero.

I like flotcharts too. The Canvas2D rendering has some advantages too. Though, I would like to remove the jquery dependency. I tried to use zepto instead of jquery, it worked but zepto's codebase is ugly and it relies on outdated JS features that emit warnings in Firefox.

Great, but I dislike the combined JS filesize. 267kb is simply still too big for mobile websites, given that it is only a part of a website. It seems to consume a bit too much memory for my iPad2, the first time I saw a blank demo; had to re-open Safari. (combined: c3 is 120kb and d3 is 147kb) c3.min: https://github.com/masayuki0812/c3/blob/master/c3.min.js , d3.min: https://github.com/mbostock/d3/blob/master/d3.min.js

A charts library that has no dependecies (no d3, no jquery, etc), has a filesize of less than 100kb and still looks great and offers useful features would be awesome. SVG vs. Canvas2D is another hot topic.

This looks like an interesting project. The struggle I've had in the past with similar libraries is the level of extensibility provided by the API. It's not clear from he docs how to add your own custom viz. I would love a d3 based chart library that would provide an easy to use chart api,such as we see in c3js. Which I do like. But also a DSL that is not as low level as D3 but provides enough flexiblity for creating new visualizations. There have been some nice declarative charting libs posted on HN, which links I can't find right now. Keep up the good work, I'll be following this project closely.

I'm not familiar with all the available chart libraries built on top of d3.js,but having used vanilla d3 on several projects, my first response to this article was that c3 looks really useful/cool... That said, it's probably worth mentionting that there are some useful examples of "reusable charts" on mr. bostock's website, and constructing a customized version of this JSON chart format probably wouldn't be too difficult, although making it performant on large datasets might be.

This is how demos are supposed to be done. Seriously. Spare me your video, your soundtrack, and all of your BS. Just show me the thing working and let me play with it.

I'm a long-time highcharts user. What are the advantages of this over highcharts?

It appears to support more data formats than highcharts. It allows you to pass data in both column oriented or row oriented forms. Highcharts didn't have that ability last I checked.

Also, C3 is MIT licensed. I'm sure there are other differences as well.

Cost, licensing.

Few, if any. Highcharts is an awesome package.

I could have sworn there was a ClojureScript wrapper for D3 that was also called C3.

Taking a quick search shows that it is actually called C2[1], from Keming Labs.

[1]: http://keminglabs.com/c2/

I just switched a project from dimple to c3. Dimple's requirements for data organization were very rigid and it was extremely slow on datasets more than a couple MB. Docs are sub-par for both but c3's examples were much more relevant and understandable (at least for my case).

C3 looks nice, but it'd be really great if the library didn't demand passing things in object format. Why can't we have something that implements chaining like D3? It seems a bit counter-intuitive...

I actually prefer passing a declarative configuration object rather than issuing a series of API calls. It is one of the things that had me switch a project from D3 to C3 + crossfilter a while back.

Really? Perhaps it's just a matter of preference, but this coding style drives me up a fucking wall. Clutters the hell out of your code.

I guess that depends on whether the settings you are passing to the chart are coming from somewhere else (say, an API call). If you can just get a JSON object from a backend and pass it directly to the chart, things become much simpler in your code.

I actually prefer builders,now it doesnt mean it has to be one or the other,a lib can implement such an api under the hood.

dc.js has similar goals (though more focused on large, multi-dimensional data sets), with 1 extra year to mature


Note my comment elsewhere in this thread about switching from DC to C3 + Crossfilter.

Since we wanted the set of charts to be driven by dynamic data, we were looking at either implementing functions to take a configuration object and translate that into a series of DC API calls, or switching to a charting library that already took configuration objects and hooking the charts together with Crossfilter ourselves.

The latter approach won out, largely because the C3 default look and feel was closer to what we wanted as well, compared to the DC defaults.

I like hearing about other options, but I wish the top rated posts were about the OP, not alternatives....

I'm looking for a chart library that can plot real-time data, can anyone give any suggestions?

I guess it would depend on your throughput rate. We've been using a port of jqplot: https://github.com/scattering/jqplot.science

You can see it in action at: http://ncnr.nist.gov/ipeek/

We developed this to allow people to monitor experiments from the comfort of their hotel room. Our rates are relatively slow on most instruments (no faster than 1 pt/sec, where a pt may be effectively an image, or just a single datapoint).

Right now, we're not running, but it's fun to watch when it's updating.

I have used HighCharts before for this. You'll want to look at their "Dynamic Charts" section: http://www.highcharts.com/demo/dynamic-update

That looks pretty nifty, thanks

I'm using Amcharts right now, here's the example with rt data http://www.amcharts.com/tutorials/real-time-data/

annnd it suffers from the same problem as other javascript libraries: the documentation is awful.

If you want your reusable library to be adopted widely, you have to write good docs. I was hoping I could replace NVD3.js with C3.js but the docs are on par.

The documentation is nice... it's just incomplete.

Right and that incompleteness will leave you taking hours to do what should be done in minutes because you're digging through the source code.

/said as someone who's had to do that with multiple libraries :(

How does this compare with nvd3?

Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact