Skip to content

Instantly share code, notes, and snippets.

@angelialau
Created June 8, 2020 00:40
Show Gist options
  • Save angelialau/4820a9b52ad92dfe1fc20dd112e1b0dd to your computer and use it in GitHub Desktop.
Save angelialau/4820a9b52ad92dfe1fc20dd112e1b0dd to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>HW1</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<style id="jsbin-css">
.bar {
fill: LightGray;
stroke: Black;
}
#ylabel {
font-family: Helvetica;
font-size: 14px;
fill: Black;
text-anchor:middle;
}
</style>
</head>
<body>
<div id="chart"></div>
<script id="jsbin-javascript">
d3.json('https://raw.githubusercontent.com/hvo/datasets/master/us-refugees.json')
.then(refugees => {
var data = refugees.map(x => ([x.Year,
Object.entries(x)
.filter(item=>(item[0]!='Year'))
.reduce((total, item)=>(total+item[1]), 0)
]));
createPlot(data);
});
function createPlot(data) {
const canvasSize = [300, 1000];
const barStart = 60;
const chartLeft = 20; //left alignment for both chart title and year labels
const rowHeight = 20;
const transitionDur = 1000;
var chart = d3.select("#chart");
var canvas = chart.append("svg")
.attr('width', canvasSize[0])
.attr('height', canvasSize[1]);
// y axis labels
var y = d3.scaleLinear()
.domain([d3.min(data.map(x=>x[0])),
d3.max(data.map(x=>x[0]))])
.range([0, (data.length-1)*rowHeight]);
canvas.append('g')
.attr('transform', 'translate(55, 60)')
.call(d3.axisLeft(y).ticks(data.length, 'I'))
.call(g => g.select(".domain").remove())
// y axis title
const yTitlePos = [chartLeft-10, canvasSize[1]*2/5]
canvas.append('text')
.attr('class', '#ylabel')
.attr('x', yTitlePos[0])
.attr('y', yTitlePos[1])
.attr('transform', `rotate(-90, ${yTitlePos[0]}, ${yTitlePos[1]})`)
.text('Year');
// the actual bars
const barMaxWidth = canvasSize[0]-100
var maxVal = d3.max(data.map(x=>x[1]));
var widthScale = d3.scaleLinear()
.domain([0, maxVal])
.range([0, barMaxWidth]);
canvas.selectAll('.legendGroup')
.data(data).enter()
.append('g').append('rect')
.attr('class', 'bar')
.attr('x', barStart)
.attr('y', (d, i)=>(50 + i*rowHeight))
.attr('width', d=>widthScale(d[1]))
.attr('height', rowHeight-2)
.on('mouseover', (d, i) => {
d3.select(event.currentTarget)
.transition().duration(transitionDur)
.style('fill', 'SteelBlue')
.attr('x', chartLeft)
.attr('width', 60+widthScale(maxVal))
})
.on('mouseout', d => {
d3.select(event.currentTarget)
.transition().duration(transitionDur)
.style('fill', 'LightGrey')
.attr('x', barStart)
.attr('width', widthScale(d[1]))
});
// title
canvas.append('text')
.attr('x', chartLeft)
.attr('y', rowHeight)
.text('Refugees');
}
</script>
</body>
</html>
.bar {
fill: LightGray;
stroke: Black;
}
#ylabel {
font-family: Helvetica;
font-size: 14px;
fill: Black;
text-anchor:middle;
}
d3.json('https://raw.githubusercontent.com/hvo/datasets/master/us-refugees.json')
.then(refugees => {
var data = refugees.map(x => ([x.Year,
Object.entries(x)
.filter(item=>(item[0]!='Year'))
.reduce((total, item)=>(total+item[1]), 0)
]));
createPlot(data);
});
function createPlot(data) {
const canvasSize = [300, 1000];
const barStart = 60;
const chartLeft = 20; //left alignment for both chart title and year labels
const rowHeight = 20;
const transitionDur = 1000;
var chart = d3.select("#chart");
var canvas = chart.append("svg")
.attr('width', canvasSize[0])
.attr('height', canvasSize[1]);
// y axis labels
var y = d3.scaleLinear()
.domain([d3.min(data.map(x=>x[0])),
d3.max(data.map(x=>x[0]))])
.range([0, (data.length-1)*rowHeight]);
canvas.append('g')
.attr('transform', 'translate(55, 60)')
.call(d3.axisLeft(y).ticks(data.length, 'I'))
.call(g => g.select(".domain").remove())
// y axis title
const yTitlePos = [chartLeft-10, canvasSize[1]*2/5]
canvas.append('text')
.attr('class', '#ylabel')
.attr('x', yTitlePos[0])
.attr('y', yTitlePos[1])
.attr('transform', `rotate(-90, ${yTitlePos[0]}, ${yTitlePos[1]})`)
.text('Year');
// the actual bars
const barMaxWidth = canvasSize[0]-100
var maxVal = d3.max(data.map(x=>x[1]));
var widthScale = d3.scaleLinear()
.domain([0, maxVal])
.range([0, barMaxWidth]);
canvas.selectAll('.legendGroup')
.data(data).enter()
.append('g').append('rect')
.attr('class', 'bar')
.attr('x', barStart)
.attr('y', (d, i)=>(50 + i*rowHeight))
.attr('width', d=>widthScale(d[1]))
.attr('height', rowHeight-2)
.on('mouseover', (d, i) => {
d3.select(event.currentTarget)
.transition().duration(transitionDur)
.style('fill', 'SteelBlue')
.attr('x', chartLeft)
.attr('width', 60+widthScale(maxVal))
})
.on('mouseout', d => {
d3.select(event.currentTarget)
.transition().duration(transitionDur)
.style('fill', 'LightGrey')
.attr('x', barStart)
.attr('width', widthScale(d[1]))
});
// title
canvas.append('text')
.attr('x', chartLeft)
.attr('y', rowHeight)
.text('Refugees');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment