Build Charts with NextJS and D3.js
Introduction
D3.js (Data-Driven Documents) is a powerful JavaScript library for producing dynamic, interactive data visualizations from numerical data. Instead of providing pre-built charts, D3 offers low-level tools that allow you to manipulate DOM elements directly (typically SVGs, Canvas, or HTML).
The advantages:
- Infinite Customization: You can create any type of chart you can imagine.
- High Performance: Smoothly handles large data sets and animated transitions.
- Strong Mathematical Ecosystem: Fully supports scale calculation functions, coordinate axis formatting, and complex geometric algorithms.
Detail
First, let's start with a simple example of drawing a line chart that describes monthly revenue during the year.
Please create the file app/api/revenue/route.ts to simulate a 12-month revenue api with a random amount from 1000-6000
Create file app/d3/LineChart.tsx
This component performs fetching revenue data from the API, then uses D3.js to calculate the coordinates (scales) and draw a line chart. It includes drawing coordinate axes, the lines connecting the data points, and circles at each data marker. Additionally, it uses ResizeObserver to ensure the chart is always co-dãn (responsive) according to the size of the parent container.
See the results as follows
You can see that when using D3, you actually create HTML DOM elements
Next, let's look at an example of a Candle tick chart that receives real-time data using the Server-Sent Events (SSE) protocol
Unlike Websocket, SSE only transmits 1-way data and data is text, applying in this case, the client only needs to receive data transmitted from the server.
Please create the file app/api/sse/route.ts to simulate SSE
- This code snippet sets up a Route Handler in NextJS to create a continuous stream of real-time data via Server-Sent Events (SSE). Every 100ms, it generates 10 simulated nến data (candlestick data) records with OHLC parameters (open, high, low, close) and sends them to the client via a continuous stream.
- When you use force-dynamic, you are ordering NextJS to:
- Not Cache: Must process this logic every time a new request arrives.
- Bypass Static Build Mode: Force this Route to run entirely in a real Server environment (Dynamic Rendering).
- Why does SSE need this? SSE is a long-running data stream. If you do not set force-dynamic, NextJS may misinterpret this as a static API and close the connection immediately after returning the first data, or worse, cache old data, preventing your chart from updating live.
Please create file app/d3/D3CandlestickChart.tsx
This component is a real-time candlestick chart. It uses EventSource to listen for data from the SSE API and updates state continuously (limited to the last 100 candles). D3.js is used to draw rectangles (candle body) and lines (candle wick) based on OHLC values. The chart is also integrated with the ability to automatically adjust size and change candle color (green/red) depending on whether the price fluctuations are increasing or decreasing.
The result will be as follows, you can run in real life to see the chart transform according to the changes in data
Happy coding!
Comments
Post a Comment