Skip to content

Instantly share code, notes, and snippets.

@jwilber
Last active December 25, 2019 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jwilber/72702cfaea1dca33380fa40157f0c42c to your computer and use it in GitHub Desktop.
Save jwilber/72702cfaea1dca33380fa40157f0c42c to your computer and use it in GitHub Desktop.
interpolated line-chart with legend
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
g.tick line {
opacity: .1;
}
path.domain {
opacity:0;
}
</style>
</head>
<body>
<script src="linechart.js"></script>
</body>
'use strict'
d3.csv('tweetdata.csv', linechart);
function linechart(data) {
console.log(data);
const colDict = {retweets: 'skyblue', favorites: 'coral' , tweets: 'olive'}
const margin = {top: 50, right: 25, bottom: 25, left: 25};
const width = 700 - margin.right - margin.left;
const height = 500 - margin.top - margin.bottom;
const svg = d3.select('body').append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// define scales
const xScale = d3.scaleLinear().domain([1, 10]).range([20, width]);
const yScale = d3.scaleLinear().domain([0, 35]).range([height, 20]);
// define axes
const xAxis = d3.axisBottom()
.scale(xScale)
.tickSize(height + 5)
.tickValues([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const yAxis = d3.axisRight()
.scale(yScale)
.tickSize(width + 10)
.ticks(10);
// draw axies
svg.append('g').attr('id', 'xAxisG').call(xAxis);
svg.append('g').attr('id', 'yAxisG').call(yAxis);
// Add circles
svg.selectAll('circle.tweets')
.data(data)
.enter()
.append('circle')
.attr('class', 'tweets')
.attr('r', 5)
.attr('cx', d => xScale(d.day))
.attr('cy', d => yScale(d.tweets))
.style('fill', 'olive');
svg.selectAll('circle.favorites')
.data(data)
.enter()
.append('circle')
.attr('class', 'favorites')
.attr('r', 5)
.attr('cx', d => xScale(d.day))
.attr('cy', d => yScale(d.favorites))
.style('fill', 'coral');
svg.selectAll('circle.retweets')
.data(data)
.enter()
.append('circle')
.attr('class', 'retweets')
.attr('r', 5)
.attr('cx', d => xScale(d.day))
.attr('cy', d => yScale(d.retweets))
.style('fill', 'skyblue');
// add lines
const tweetLine = d3.line()
.x(d => xScale(d.day))
.y(d => yScale(d.tweets))
.curve(d3.curveBasis);
svg.append('path')
.attr('class', 'tweets')
.attr('d', tweetLine(data))
.attr('fill', 'none')
.attr('stroke', 'olive')
.attr('stroke-width', 5)
const favoriteLine = d3.line()
.x(d => xScale(d.day))
.y(d => yScale(d.favorites))
.curve(d3.curveCardinal);
svg.append('path')
.attr('class', 'favorites')
.attr('d', favoriteLine(data))
.attr('fill', 'none')
.attr('stroke', 'coral')
.attr('stroke-width', 5)
const retweetLine = d3.line()
.x(d => xScale(d.day))
.y(d => yScale(d.retweets))
.curve(d3.curveStep);
svg.select('path')
.attr('class', 'retweets')
.attr('d', retweetLine(data))
.attr('fill', 'none')
.attr('stroke', 'skyblue')
.attr('stroke-width', 5)
// interactivity
d3.selectAll('path')
.on('mouseover', highlightLine);
d3.selectAll('path')
.on('mouseout', deHighlightLine);
function highlightLine(d) {
let col = d3.select(this).attr('stroke');
let sw = d3.select(this).attr('stroke-width');
d3.select(this).attr('stroke', d3.rgb(col).brighter(.2));
d3.select(this).attr('stroke-width', 10);
};
function deHighlightLine(d) {
let col = d3.select(this).attr('class');
let sw = d3.select(this).attr('stroke-width');
d3.select(this).attr('stroke', colDict[col]);
d3.select(this).attr('stroke-width', 5);
};
// legend
var legend_keys = ["retweets", "favorites", "tweets"]
var lineLegend = svg.selectAll(".lineLegend").data(legend_keys)
.enter().append("g")
.attr("class","lineLegend")
.attr("transform", function (d,i) {
return "translate(" + (margin.left) + "," + (i*20)+")";
});
lineLegend.append("text").text(function (d) {return d;})
.attr("transform", "translate(15, 6)"); //align texts with boxes
lineLegend.append("rect")
.attr("fill", d => colDict[d])
.attr("width", 12).attr('height', 5);
// title
d3.select('svg')
.append('text')
.html('Tweets Line-Chart')
.attr('x', width / 2 - margin.right)
.attr('y', margin.top / 2)
.attr('font', 'Georgia')
.style('font-size', 20);
};
day tweets retweets favorites
1992 9.0 29.0 5.0
1994 9.0 22.0 0.0
1993 8.0 50.0 0.0
2012 33.0 33.0 0.0
1995 0.0 42.0 0.0
1996 3.0 33.0 22.0
1999 9.0 45.0 18.0
2007 28.0 19.0 17.0
2015 0.0 18.0 8.0
2003 9.0 20.0 33.0
2000 5.0 35.0 37.0
2002 4.0 36.0 7.0
day tweets retweets favorites
1 1 2 5
2 6 11 3
3 3 8 1
4 5 14 6
5 10 29 16
6 4 22 10
7 3 14 1
8 5 18 7
9 1 30 22
10 4 16 15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment