Streamchart with React (2023)

Streamchart with React (1)

A streamgraph is a variation of the more common stacked area chart. It rounds edges and displays areas around the central axis which gives a nice impression of flow.

This section explains how to stack and smooth the data with d3.js, and render the shapes with react. It starts from the basic and goes until necessary customization like tooltips, hover effect, legend and annotation. Examples always come with editable sandboxes.

Useful links

The Data

Most of the time the input dataset is an array where each item is an object.

Each object provides information for a step on the X axis. It has a value like x or date that provides the exact position on the X axis. Then it has several numeric values, one for each group of the dataset.

Here is a minimal example:

const data = [ { x: 1, groupA: 38, groupB: 19, }, { x: 2, groupA: 16, groupB: 14, }, ...];

→ Wide and Long formats

The format described above is often called the wide format. Another common format is the long format, where each object in the array provides information for 1 group only. (The array becomes way longer 🙃)

If your dataset is formatted using the long format, you can transform it using the pivotWider function below:

Pivot function
type LongDataItem = { date: string; group: string; value: number;};type WideDataItem = { date: string;} & { [key: string]: number }const pivotWider = (data: LongDataItem[]) => { const result: WideDataItem[] = []; data.forEach((item) => { const existingEntry = result.find((entry) => entry.date === item.date); if (existingEntry) { existingEntry[item.group] = item.value; } else { const newEntry = { date: item.date }; newEntry[item.group] = item.value; result.push(newEntry); } }); return result;}

.csv data

If your data is in .csv format, you can translate it thanks to the csvParse() function of d3. I'll write a blogpost soon on how to deal with the csv format. Subscribe to the project to know when it is ready!

ToDoAdd some more hints on how to type those data objects

Component skeleton

The goal here is to create a StreamGraph component that will be stored in a StreamGraph.tsx file. This component requires 3 props to render: a width, a height, and some data.

The shape of the data is described above. The width and height will be used to render an svg element in the DOM, in which we will insert the graph.

To put it in a nutshell, that's the skeleton of our StreamGraph component:

import * as d3 from "d3"; // we will need d3.jstype WideDataItem = { date: string;} & { [key: string]: number }type StreamGraphProps = { width: number; height: number; data: WideDataItem[];};export const StreamGraph = ({ width, height, data }: StreamGraphProps) => { // read the data // find the list of groups to display // stack the data // build the shapes return ( <div> <svg width={width} height={height}> // render all the shapes </svg> </div> );};

It's fundamental to understand that with this code organization, d3.js will be used to prepare the SVG circle, but it's React that will render them in the return() statement. We won't use d3 methods like append that you can find in usual d3.js examples.

Stacking series

Building a stream chart requires to stack the data. Series are displayed one on top of each other and you have to compute their positions on the Y axis.

Fortunately, D3.js has a handy stack() function that does exactly that. The process is deeply explained in the stacked area chart section of the gallery.

Stacking explanation

The only variation required here is to use the d3.stackOffsetSilhouette offset option. Instead of stacking everything above the 0 baseline, it will put groups on both parts of it.

Computing the position of the chart series should look something like:

const stackSeries = d3 .stack() .keys(groups) .order(d3.stackOrderNone) .offset(d3.stackOffsetSilhouette);const series = stackSeries(data);

Basic streamgraph example

Once more, the process to render the shape is very close to the stacked area chart. A few variations are required though.

→ Smoothing

We need to smooth the area shape to get the good-looking organic flow. Once more d3 is here to the rescue with a curve function that does all the work for us.

This is how to call the curve function and the end of the area function call:

const areaBuilder = d3 .area() .x(d => xScale(x)) .y1(d => yScale(d[1])) .y0(d => yScale(d[0])) .curve(curveCatmullRom);

→ Axis

Usual axes do not work for streamgraphs. The Y axis would make no sense since shapes are on both side of the 0 baseline. It is commonly removed. The X axis would feel lost alone at the very bottom of the chart.

Here I suggest to replace the X axis with vertical ablines and remove the Y axis completely.

Most basic streamgraph with react and d3.js

Responsive Streamgraph with react

The component above is not responsive. It expects 2 props called width and height and will render a Streamgraph of those dimensions.

Making the Streamgraph responsive requires adding a wrapper component that gets the dimension of the parent div, and listening to a potential dimension change. This is possible thanks to a hook called useDimensions that will do the job for us.

useDimensions: a hook to make your viz responsive
export const useDimensions = (targetRef: React.RefObject<HTMLDivElement>) => { const getDimensions = () => { return { width: targetRef.current ? targetRef.current.offsetWidth : 0, height: targetRef.current ? targetRef.current.offsetHeight : 0 }; }; const [dimensions, setDimensions] = useState(getDimensions); const handleResize = () => { setDimensions(getDimensions()); }; useEffect(() => { window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); useLayoutEffect(() => { handleResize(); }, []); return dimensions;}

I'm in the process of writing a complete blog post on the topic. Subscribe to the project to know when it's ready.

Hover effect

It is pretty hard to follow the evolution of a specific group on a streamgraph.

It is common to add an hover effect to the figure: hovering over a group will highlight it, making it easier to follow its evolution. Try it on the graph below:

StreamGraph with hover effect that highlights a specific series

There are various strategies to implement such an hover effect.

Here, I suggest to do everything in css using pseudo classes, and targetting svg elements only. Basically, everything in the svg container will be dimmed (lower opacity and saturation) when the mouse goes over the chart. But the specific shape that is hovered over will keep its full opacity thanks to a more specific css selector.

Hover effect is a big topic and I will post more about it soon!

Know when

Streamgraph inspiration

If you're looking for inspiration to create your next Streamgraph, note that dataviz-inspiration.com showcases many examples. Definitely the best place to get ... inspiration!

dataviz-inspiration.com showcases hundreds of stunning dataviz projects. Have a look to get some ideas on how to make your Streamgraph looks good!

visit

Streamgraph algorithm with transition

Our streamgraph is renderer using a set of path. The d attribute of those paths provides the boundary coordinates of those paths.

When a prop of the StreamGraph component updates, we might want to update the paths to represent the latest state of our application. It can be an update of the dataset, or an update of the function used to stack the data or smooth the area as below.

It is possible to smoothly animate this transition thanks to react-spring.

Offset typeCurve type

Try d3.js various options to offset the data and smooth shapes. See a smooth transition between options.

The animation suggested above is a bit tricky to implement. Indeed, we need to transition from paths that do not have the same number of edges. It is possible thanks to a library called flubber but definitely deserves its own blogpost.

I'll publish a full blogpost on the topic soon!

Get notified

ToDofind why flubber does some weird interpolation in some cases

Application

The following chart is a real-life application of a streamgraph. It shows the evolution if the number of page-views for 5 tech websites in the last 7 years. My goal was to assess if the rise of chat-GPT had an impact on it.

This interactive chart has several interesting features:

  • slider: you can control the displayed time-frame thanks to a slider.
  • inline legend: label of each series are written inline. A background proportional to their value provides additional insight.
  • hover effect: legend will be updated with precise values at the hovered timestamp.

A customized streamgraph built with React and D3.js. It has inline legends, slider to control timeframe, hover effect and more.

Evolution

+Line chart
+Area chart
+Stacked Area
+Streamgraph
+Timeseries

Copyright © the React Graph Gallery 2023

About | License

FAQs

Can you use chartjs with react? ›

Chart.js comes with built-in TypeScript typings and is compatible with all popular JavaScript frameworks including React , Vue , Svelte , and Angular .

How do you display data as a graph in react? ›

Explanation
  1. The state variable contains all the data and styling properties of the bar graph. The labels keyword assigns names to each bar, and the dataset sub-set contains information such as bar color, border width, ​and height of the bar.
  2. The Bar component is rendered using <Bar /> inside the React App component.

How to use react-chartjs-2 in react? ›

Creating a Charts in React Component

We need to develop a new component that will act as the container for our chart in order to render a chart using react-chartjs-2. This component will produce the chart using the Chart. js library. And incorporate it into our React application using the react-chartjs-2 module.

Is React good for data visualization? ›

React Chart Libraries are a useful resource for web developers who want to add insightful data visualizations to their websites. These apps are mostly used to aid web developers in demonstrating the current or future state of a specific application or feature.

How do I create a bar chart in react JS? ›

Creating a bar chart

To get started, we will run this command on the terminal, 'npm create vite@latest'. This will unfold the latest features of Vite while bringing a few prompts that needs to be answered. Next, we will be installing react-chartjs with npm with the following command, “npm install - save chart.

What graph is best for displaying data? ›

A line chart, area chart, and column chart are the most common chart types used to visualize change over time. In most cases, they can be used interchangeably, but there are subtle differences between them. Line charts and area charts are the best tools to visualize data that goes up and down from day to day.

What are the different types of React charts? ›

React Chart and Graph Types

You can create React charts like Pie, Bar, Area, Line, Point, Stacked, Donut, Scatter, Gauge, Polar, Treemap, Stock, Financial, Geospatial Maps and more for your mobile or web apps.

How to display a graph in js? ›

That's all!
  1. Typical Scatter Chart Syntax: const myChart = new Chart("myChart", { type: "scatter", data: {}, options: {} ...
  2. Typical Line Chart Syntax: const myChart = new Chart("myChart", { type: "line", data: {}, options: {} ...
  3. Typical Bar Chart Syntax: const myChart = new Chart("myChart", { type: "bar", data: {}, options: {}

How do you map data in react JS? ›

Example
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. function ListItem(props) {
  4. return <li>{props.value}</li>;
  5. }
  6. function NumberList(props) {
  7. const numbers = props.numbers;
  8. const listItems = numbers.map((number) =>

How do you map values in Reactjs? ›

Syntax: var array = [1,2,3,4,5] var PlusOne= array. map((e)=>{ return (e+1); }); // All array element value will increase by one. list.

Can you use React navigation in React? ›

React Navigation's web support currently requires using React Native for Web. This approach lets us reuse the same code on both React Native and Web.

Can I use Exceljs in React? ›

I have used a couple of libraries for generating reports in React. The easiest by a mile was react-csv which, with little to no configuration, can give you a CSV. But the library that I rely on these days is exceljs.

Does Threejs work with React? ›

react-three-fiber is an open-source react-renderer for three. js. It makes it easier to use three. js in React by exposing reusable and self-contained components from three.

Is it a good idea to use RxJS with React? ›

Yes, RxJS can be used with many JavaScript frameworks, including React. RxJS is often used for managing side effects, but is also suited to managing state.

Can we use Highcharts with react JS? ›

On a client side React application Highcharts can be loaded as the following example: // Load Highcharts var Highcharts = require('highcharts'); // Load a module require('highcharts/modules/funnel')(Highcharts); However with an isomorphic application the code will also be run on a server.

References

Top Articles
Latest Posts
Article information

Author: Prof. An Powlowski

Last Updated: 10/05/2023

Views: 6065

Rating: 4.3 / 5 (44 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Prof. An Powlowski

Birthday: 1992-09-29

Address: Apt. 994 8891 Orval Hill, Brittnyburgh, AZ 41023-0398

Phone: +26417467956738

Job: District Marketing Strategist

Hobby: Embroidery, Bodybuilding, Motor sports, Amateur radio, Wood carving, Whittling, Air sports

Introduction: My name is Prof. An Powlowski, I am a charming, helpful, attractive, good, graceful, thoughtful, vast person who loves writing and wants to share my knowledge and understanding with you.