Plotteus logoPlotteus

Examples

Introduction


What is Plotteus?

What isPlotteus logoPlotteus?

Plotteus is an open-source JavaScript data visualization library designed for better storytelling. It's a powerful tool that allows you to create interactive visualizations for your story from scratch, starting with defining a chart type, through seamless transitions between states, to giving you full control over them.

It's quite simple to start creating charts with Plotteus. A minimal example is shown below.

const div = document.querySelector("#story");
const steps = [
  {
    key: "intro",
    chartType: "bar",
    title: "Hello, Plotteus! 🎉",
    groups: [
      {
        key: "Alice",
        data: [
          { key: "A", value: 1 },
          { key: "B", value: 1.2 },
          { key: "C", value: 1.4 },
        ],
      },
      {
        key: "Bob",
        data: [
          { key: "A", value: 1.6 },
          { key: "B", value: 1.8 },
          { key: "C", value: 1.6 },
        ],
      },
      {
        key: "Cecile",
        data: [
          { key: "A", value: 1.4 },
          { key: "B", value: 1.2 },
          { key: "C", value: 1 },
        ],
      },
    ],
  },
];
const story = makeStory(div, steps);
story.render("intro", 1);

While you can use Plotteus to create a single chart, it's main purpose is to create stories – sequences of charts that tell a story.


Fine-grained control

One of the strengths of Plotteus is that it gives you complete control over how to present your data stories. Popular approaches to data storytelling focus on using a bunch of charts that remain blended in the text or a sticky chart connected to a set of triggers that start an animation when activated, usually by scrolling.

Plotteus gives you more freedom – it creates a set of interpolators that can be used to render a given part of a story at any progress. This means that you can render your story incrementally as the user scrolls through the page, use a slider to control the progress or replicate the trigger approach to completely render a step over a given duration.

You have the power to choose.

Story progress

const div = document.querySelector("#story");
const groups = [
  {
    key: "Alice",
    data: [
      { key: "A", value: 1 },
      { key: "B", value: 1.2 },
      { key: "C", value: 1.4 },
    ],
  },
  {
    key: "Bob",
    data: [
      { key: "A", value: 1.6 },
      { key: "B", value: 1.8 },
      { key: "C", value: 1.6 },
    ],
  },
  {
    key: "Cecile",
    data: [
      { key: "A", value: 1.4 },
      { key: "B", value: 1.2 },
      { key: "C", value: 1 },
    ],
  },
];
const steps = [
  {
    key: "zero",
    chartType: "bar",
    groups,
  },
  {
    key: "one",
    chartType: "bar",
    groups: [
      ...groups,
      {
        key: "Dave",
        data: [
          { key: "A", value: 0.8 },
          { key: "B", value: 0.6 },
          { key: "C", value: 0.4 },
        ],
      },
    ],
  },
];
const story = makeStory(div, steps);
const onChange = (value) => {
  if (value < 0.5) {
    story.render("zero", value * 2);
  } else {
    story.render("one", (value - 0.5) * 2);
  }
}

Keeping the data in context

Another behavior that is usually hard to achieve is the smoothness of a story. Since some chart types may be better suited for a specific slice of the data better than others, it would be nice to be able to make a transition between them while keeping the data in context.

For example, you might want to highlight several parts of a treemap and compare them using a bar chart. Normally, you would have to exit the entire treemap and enter a new bar chart with only the data you need (which could make it difficult to keep the track of the parts being compared and their position in the previous treemap). With Plotteus, you can seamlessly animate any chart type into any other chart type.

Plotteus also makes it easy to do other basic things that are also essential for data storytelling, such as highlighting, sorting, or adding new data, all nicely animated.

Story progress

const div = document.querySelector("#story");
const steps = [
  {
    key: "zero",
    chartType: "bubble",
    groups: [
      {
        key: "Alice",
        data: [
          { key: "A", value: 1 },
          { key: "B", value: 1.2 },
          { key: "C", value: 1.4 },
        ],
      },
      {
        key: "Bob",
        data: [
          { key: "A", value: 1.6 },
          { key: "B", value: 1.8 },
          { key: "C", value: 1.6 },
        ],
      },
      {
        key: "Cecile",
        data: [
          { key: "A", value: 1.4 },
          { key: "B", value: 1.2 },
          { key: "C", value: 1 },
        ],
      },
    ],
  },
  {
    key: "one",
    chartType: "scatter",
    groups: [
      {
        key: "Alice",
        data: [
          { key: "A", x: 0.4, y: 0.1 },
          { key: "B", x: 0.7, y: 0.5 },
          { key: "C", x: 1, y: 0.9 },
        ],
      },
      {
        key: "Bob",
        data: [
          { key: "A", x: 1.2, y: 1.1 },
          { key: "B", x: 1.3, y: 0.4 },
          { key: "C", x: 0.6, y: 1.3 },
        ],
      },
      {
        key: "Cecile",
        data: [
          { key: "A", x: 1.4, y: 0.6 },
          { key: "B", x: 1.2, y: 1 },
          { key: "C", x: 1.6, y: 0.2 },
        ],
      },
    ],
  },
];
const story = makeStory(div, steps);
const onChange = (value) => {
  if (value < 0.5) {
    story.render("zero", value * 2);
  } else {
    story.render("one", (value - 0.5) * 2);
  }
}

Limitless animations and a powerful mechanism to control them combined with a config-based approach, customizability, and responsiveness, make for a powerful combination that results in more enjoyable and memorable ways to tell your stories.

Ready to take them to the next level?