Skip to content

Instantly share code, notes, and snippets.

Created July 24, 2017 23:11
Show Gist options
  • Save mglukhovsky/d6664666953c884c024a7665ac5c251b to your computer and use it in GitHub Desktop.
Save mglukhovsky/d6664666953c884c024a7665ac5c251b to your computer and use it in GitHub Desktop.
Realtime graph with D3
<title>Stripe Charts</title>
body {
font: 10px sans-serif;
.layer path, .layer line {
fill: none;
stroke: red;
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
<svg width="960" height="500"></svg>
<!-- D3 -->
<script src=""></script>
<script src=""></script>
<script src="/realtime-graph-d3.js"></script>
'use strict'
// Generate random values
let month = new Date(2014, 0, 1)
function randomData() {
let newData = {
apples: Math.random()*3000,
bananas: Math.random()*2000,
cherries: Math.random()*1000,
dates: Math.random()*400
month = moment(month).add(30, 'days').toDate()
return newData
const data = []
for (let i=0; i < 12; i++) {
data[i] = randomData()
const keys = ['apples', 'bananas', 'cherries', 'dates']
// Get the maximum of the total number of event types
let maxEventCount = d3.max(data, (d) => {
// Sum the values for each event type
return d3.sum(keys, (key) => d[key])*1.5
const xDomain = () => {
return [data[0].month, data[data.length-2].month]
// Build the SVG plot
const margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 1000 - margin.left - margin.right,
height = 500 - - margin.bottom
const x = d3.scaleTime()
// Find the largest and smallest dates for the domain
.range([0, width]),
y = d3.scaleLinear()
// Set the domain to the highest event count
.range([height, 0]),
color = d3.scaleOrdinal(d3.schemeCategory10)
const svg ='svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + + margin.bottom)
.attr('transform', `translate(${margin.left},${})`)
.attr('id', 'clip')
.attr('width', width)
.attr('height', height)
// Use a stack layout to create our stacked area graph
const stack = d3.stack()
const stackedData = stack(data)
// Build our area graph (using cardinal smoothing to create curves)
const area = d3.area()
// The x axis is based on time
.x((d,i) => x(
// y0 and y1 represent the bottom and top values for each section of the area graph
.y0((d) => y(d[0]))
.y1((d) => y(d[1]))
const xAxis = d3.axisBottom()
const yAxis = d3.axisLeft()
// Create a group layer for each event type
const layer = svg.selectAll('.layer')
.attr('class', 'layer')
.attr('clip-path', 'url(#clip)')
// Add the actual area paths for each event type
const path = layer.append('path')
.attr('class', 'areas')
.attr('d', area)
.style('fill', (d, i) => color(i))
// Add our axes to the plot
const xAxisGroup = svg.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0, ${height})`)
.attr('clip-path', 'url(#clip)')
.attr('class', 'y axis')
function tick() {
.attr('d', area)
.attr('transform', null)
const prevDate = moment(data[0].month).subtract(30, 'days').toDate()
console.log(d3.extent(data, d => d.month))
let transitionCount = 0
.attr('transform', `translate(${x(prevDate)})`)
.on('end', () => {
transitionCount += 1
if (transitionCount === keys.length) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment