# Flotr2 draws charts on a canvas, with the plugin and type system doing the work

> Flotr2 is a Canvas-based JavaScript charting library whose API is a single Flotr.draw call plus a configuration object, extended through registered chart types and plugins rather than through subclassing. It fits a team that wants a self-contained charting file with no runtime framework, and it does not fit a project that needs reactive data binding, SVG output or a maintained type definition.

**HumbleSoftware/Flotr2** — Graphs and Charts for Canvas in JavaScript.

- Repository: https://github.com/HumbleSoftware/Flotr2
- Website: http://www.humblesoftware.com/flotr2/
- Stars: 2,437 · Forks: 520
- Language: JavaScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/humblesoftware-flotr2

## The whole API is one draw call and a configuration object

Flotr2 describes itself as the Canvas graphing library, and its API consists of a primary draw method which accepts a configuration object, helper methods, and several microlibs.

The example in the README is short enough to be the whole mental model. You get a container element, one or more data series as arrays of x and y pairs, and an options object, and you call Flotr.draw:

```javascript
  var
    // Container div:
    container = document.getElementById("flotr-example-graph"),
    // First data series:
    d1 = [[0, 3], [4, 8], [8, 5], [9, 13]],
    // Second data series:
    d2 = [],
    // A couple flotr configuration options:
    options = {
      xaxis: {
        minorTickFreq: 4
      }, 
      grid: {
        minorVerticalLines: true
      }
    },
    i, graph;

  // Draw the graph:
  graph = Flotr.draw(
    container,  // Container element
    [ d1, d2 ], // Array of data series
    options     // Configuration options
  );
```

Data is plain arrays of coordinate pairs, and the second series in the example is generated with a loop pushing [i, Math.sin(i)]. The options object is nested, with xaxis and grid as named sub-objects, so the shape of the configuration is the shape of the chart.

The microlibs are two small libraries: a general-purpose utility library and bean.js. The Makefile does something specific with these: it wraps the concatenated utility library in a function so that AMD is hidden from it and it always sets the global _, which the comment ties to an issue number in the tracker.

The project is MIT licensed, the last push was on 2026-10-16, and the released versions are v2.0.2 from 2025-08-31 and v2.0.1 from 2025-08-26.

## Chart types and plugins are registered, not subclassed

Flotr2 may be extended by adding new plugins and graph types, and the extension mechanism is a pair of registration functions rather than an inheritance hierarchy.

Graph types define how a particular chart is rendered, and the examples given are line, bar and pie. They live in js/types/. Plugins extend the core of Flotr with new functionality, and they can add interactions, new decorations and similar things, with the examples given being titles, labels and selection. They live in js/plugins/.

The two registration calls are Flotr.addType(name, implementation) and Flotr.addPlugin(name, implementation). Plugins use lifecycle hooks such as beforedraw and afterdraw, which is how a plugin draws itself relative to the chart's own render pass.

This design has a consequence that is worth being explicit about. Because extension is registration rather than subclassing, a plugin cannot override a chart type's internals; it can only observe and add. For a chart library that ships a fixed set of visual components, that is exactly the right level of coupling, and it is why the plugin set can include things like download and spreadsheet, which are entirely separate concerns from drawing.

The full plugin set in js/plugins/ covers visual elements with grid, legend, labels and titles, interactions with selection, crosshair and hit, and data export with download and spreadsheet.

## The chart type catalogue is broader than line, bar and pie

The types directory holds more than the three examples the README mentions, and the range tells you what the library was built to do.

The basic charts are lines.js, bars.js, pie.js and points.js. The advanced ones are bubbles.js, candles.js and radar.js, which are the financial and multivariate cases. And there are two timeline visualisations, gantt.js and timeline.js.

Candles and gantt are worth pausing on, because they are the two chart types that require the library to get non-cartesian axes right. A candlestick chart needs a time axis with irregular intervals, and a gantt chart needs a time axis with bars that have start and end positions rather than a single x value. Both push against the assumption that a series is a list of points with one x and one y.

That assumption is visible in the data format itself. Every point in the example is [x, y], a two-element array, and the library works out axis scaling from those. A gantt bar has two x values, so the format has to accommodate that, and the fact that a gantt type exists at all suggests the axis machinery handles ranges as well as points.

The core modules that make this work are in js/. Flotr.js is the main namespace and handles plugin and type registration. Graph.js is the primary graph constructor and rendering orchestrator. Series.js does data series processing and normalisation, which is where the axis-range and data-type decisions get made. Axis.js handles axis calculations and rendering. And Color.js, Date.js, DOM.js and Text.js are the utility modules, with Date.js and Text.js being the two that any charting library needs and that every charting library gets subtly wrong.

## The build concatenates files, and the outputs are not interchangeable

The build system is smoosh, from the same author as bean, and the Makefile is where the shape of the distribution becomes clear.

Four build outputs are documented. flotr2.js is the full library with dependencies. flotr2.min.js is the minified version. flotr2.nolibs.js is the library without dependencies, for when you supply the two microlibs yourself. And flotr2.ie.min.js is the IE-specific build. The Makefile also produces flotr2-basic, a smaller build, and flotr2.amd.js, an AMD module, which the package.json names as the main entry point.

The concatenation is done with cat. The flotr2 target builds the libraries and the IE build, then concatenates build/lib.js and build/flotr2.js into flotr2.js, concatenates the minified variants into flotr2.min.js, copies the IE minified build to flotr2.ie.min.js, and writes the non-minified library to flotr2.nolibs.js.

The build configurations are JSON files in make/ that define the file concatenation order, which is how the smoosh build is parameterised. Different configurations exist for the full library, the IE build, the basic build and the examples.

This is an old-style build and it has an old-style consequence: there is no bundler, no module resolution and no tree shaking. The artefact is a fixed concatenation in a fixed order, and a consumer gets the whole thing. The pragmatic implication for an adopter is that you ship a file, you pick the variant you want, and you accept whatever the library includes.

## Tests are Playwright visual regression, and that changes what the project can promise

The test setup is the most interesting recent change in the repository, and it is worth reading as a statement about what the maintainers consider important.

The project uses smoosh to build and Playwright for testing. The commands are make or make all to run tests and build the complete library, make flotr2 to build the main library files, make test to run the Playwright tests, and npm install to install build and test dependencies. The npm scripts mirror this: test runs npm run build followed by playwright test, and there are test:headed, test:debug and test:update-snapshots variants.

The test suite includes unit tests for core functionality covering Color and Graph options, visual regression tests using example charts, and chart type rendering tests. All tests run in headless Chrome for consistent, pixel-perfect rendering.

Pixel-perfect visual regression is a demanding standard, and it is the right one for a charting library whose entire output is pixels. A colour that shifts by one value, an axis label that moves by a pixel, a gridline that changes width, all of those are visible changes in a chart, and a numeric assertion on a colour value would miss the case where the layout is correct but the text is one pixel off.

The cost of that standard is that it is brittle against browser version changes and font rendering differences across platforms, which is why the tests are pinned to headless Chrome rather than run across browsers. The examples directory holds the example charts used as the visual fixtures, with dev.html, standalone.html, profile.html and an index.html.

## Where Flotr2 is the wrong tool

The first wrong-tool case is any project that needs SVG output. Flotr2 is a Canvas-based charting library and the README says so explicitly. Canvas is the right choice for a chart with many data points, for animation, and for a chart that is redrawn frequently, because the whole surface is one bitmap. It is the wrong choice when you need vector output for print, when you need to inspect or style individual chart elements from CSS, or when a chart has to be accessible as a DOM tree of SVG nodes.

The second is reactive data binding. Flotr2 has no concept of a data source that changes and redraws. You call draw again with new data, and the library redraws the whole graph. A project using React, Vue or Svelte that expects a chart to re-render from state needs a wrapper, and that wrapper is work you write.

The third is the packaging story. The npm package is marked private in package.json, with a version of 0.1.0 and no keywords, so it is not published to a registry. Consumers are expected to take the built files from the repository or a release. The version field of 0.1.0 also does not correspond to the released 2.0.2, so the manifest is not the source of truth for versioning.

The fourth is that this is a mature library with a small community around it. The shoutouts section credits Bas Wenneker, Fabien Ménager and others for the original Flotr, and Jochen Berger and Jordan Santell for their contributions to Flotr2. The project has been in the ecosystem for a long time, which cuts both ways: there is a large body of existing knowledge, and there is a small number of people who will answer a question.

The bug reporting route tells you what the project wants from you. The README asks you to fork a jsfiddle with your question or bug reproduction case, which is a reasonable ask, and there is a Google Group for discussion.

## Conclusion

Flotr2 fits a JavaScript project that wants a single charting file with no framework dependency and a plugin system for custom visualisations, and it does not fit a team that needs SVG output for print, reactive binding to a UI framework, or a library with a current type definition. Before adopting it, run npm install and make to build the artefacts and the Playwright suite, and check the build outputs you intend to ship, since the library is published as concatenated files and the AMD entry point is a separate artefact from flotr2.js.

## FAQ

### What is Flotr2 and how do I draw a chart with it?

Flotr2 is a Canvas-based JavaScript charting library. You call Flotr.draw with a container element, an array of data series where each series is an array of x and y pairs, and a configuration object, and it returns the graph object. The example in the README uses Flotr.draw(container, [d1, d2], options).

### How do I add a custom chart type or plugin to Flotr2?

Graph types and plugins are registered rather than subclassed. You call Flotr.addType(name, implementation) for a new chart type and Flotr.addPlugin(name, implementation) for a plugin, and plugins use lifecycle hooks such as beforedraw and afterdraw. Existing types live in js/types/ and plugins in js/plugins/.

### How do I build and test Flotr2?

Run npm install to install the build and test dependencies, then make or make all to run the tests and build the library, or make flotr2 to build the main files. The Playwright suite is run with make test or npm test, and all tests run in headless Chrome for pixel-perfect rendering.

### Which chart types does Flotr2 provide?

The types directory holds lines, bars, pie and points as basic charts, bubbles, candles and radar as advanced ones, and gantt and timeline for timeline visualisations. The canvas and plugin architecture also allows new types to be registered with Flotr.addType.

## Sources

- [HumbleSoftware/Flotr2 on GitHub](https://github.com/HumbleSoftware/Flotr2)
- [License: MIT](https://github.com/HumbleSoftware/Flotr2/blob/main/LICENSE)
- [Project website](http://www.humblesoftware.com/flotr2/)
- [README](https://github.com/HumbleSoftware/Flotr2/blob/main/README.md)
- [Releases](https://github.com/HumbleSoftware/Flotr2/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/humblesoftware-flotr2
