|
<!DOCTYPE html> |
|
<head> |
|
<meta charset='utf-8'> |
|
<script src='w.js'></script> |
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js'></script> |
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.10.3/babel.min.js'></script> |
|
</head> |
|
<body> |
|
<script lang='babel' type='text/babel'> |
|
const maxWidth = 5120; |
|
const maxHeight = 2880; |
|
const margin = { |
|
top: 10, |
|
right: 10, |
|
bottom: 25, |
|
left: 35 |
|
}; |
|
|
|
const xVariable = 'letter'; |
|
const yVariable = 'frequency'; |
|
|
|
const faintGray = '#ededed'; |
|
|
|
let xScale; |
|
let yScale; |
|
let xAxis; |
|
let yAxis; |
|
|
|
d3.select('body') |
|
.style({ |
|
margin: 0, |
|
position: 'fixed', |
|
top: 0, |
|
right: 0, |
|
bottom: 0, |
|
left: 0 |
|
}) |
|
|
|
const svg = d3.select('body').append('svg') |
|
.attr('width', '100%') |
|
.attr('height', '100%'); |
|
|
|
const chartArea = svg.append('g') |
|
.classed('chartArea', true) |
|
.attr('transform', `translate(${margin.left}, ${margin.top})`) |
|
|
|
const barGroup = chartArea.append('g') |
|
.classed('bars', true); |
|
|
|
const xAxisG = chartArea.append('g') |
|
.classed('axis', true) |
|
.classed('x', true); |
|
|
|
const yAxisG = chartArea.append('g') |
|
.classed('axis', true) |
|
.classed('y', true); |
|
|
|
function type(d) { |
|
// coerce to a Number from a String (or anything) |
|
d[yVariable] = Number(d[yVariable]); |
|
return d; |
|
} |
|
|
|
d3.csv('data.csv', type, (error, data) => { |
|
console.log('data', data); |
|
|
|
function initChart() { |
|
const width = 100; |
|
const height = 50; |
|
|
|
// Initialise scales |
|
xScale = d3.scale.ordinal() |
|
.domain(data.map(d => d[xVariable])); |
|
|
|
yScale = d3.scale.linear() |
|
.domain([0, d3.max(data.map(d => d[yVariable]))]); |
|
|
|
// Build the x-axis |
|
xAxis = d3.svg.axis() |
|
.scale(xScale) |
|
.orient('bottom'); |
|
|
|
// Build the y-axis |
|
yAxis = d3.svg.axis() |
|
.scale(yScale) |
|
.orient('left'); |
|
} |
|
|
|
function updateScales() { |
|
const detectedWidth = window.innerWidth |
|
|| document.documentElement.clientWidth |
|
|| document.body.clientWidth; |
|
|
|
const detectedHeight = window.innerHeight |
|
|| document.documentElement.clientHeight |
|
|| document.body.clientHeight; |
|
|
|
const newWidth = d3.min([detectedWidth, maxWidth]) - margin.left - margin.right; |
|
const newHeight = d3.min([detectedHeight, maxHeight]) - margin.top - margin.bottom; |
|
|
|
xScale.rangeRoundBands([0, newWidth], 0.1); |
|
yScale.range([newHeight, 0]); |
|
} |
|
|
|
function updateAxes(firstCall) { |
|
const detectedHeight = window.innerHeight |
|
|| document.documentElement.clientHeight |
|
|| document.body.clientHeight; |
|
|
|
const newHeight = d3.min([detectedHeight, maxHeight]); |
|
|
|
// position the xAxisG before the transition the first time |
|
if (typeof firstCall !== 'undefined') { |
|
xAxisG |
|
.attr('transform', `translate(0, ${newHeight - margin.top - margin.bottom})`); |
|
} |
|
|
|
xAxisG |
|
.transition() |
|
.duration(0) |
|
.attr('transform', `translate(0, ${newHeight - margin.top - margin.bottom})`) |
|
.call(xAxis); |
|
|
|
yAxisG |
|
.transition() |
|
.duration(0) |
|
.call(yAxis); |
|
|
|
// style the axes |
|
d3.selectAll('.axis text') |
|
.style({ |
|
'font-family': 'sans-serif', |
|
'font-size': '10px' |
|
}) |
|
|
|
d3.selectAll('.axis path') |
|
.style({ |
|
fill: 'none', |
|
stroke: '#161616' |
|
}) |
|
|
|
d3.selectAll('.axis line') |
|
.style('stroke', 'black'); |
|
} |
|
|
|
function updateBars() { |
|
const updateSelection = barGroup.selectAll('rect') |
|
.data(data); |
|
|
|
updateSelection.enter() |
|
.append('rect') |
|
.classed('rect', true) |
|
.style('fill', faintGray); |
|
|
|
updateSelection.exit() |
|
.remove(); |
|
|
|
updateSelection |
|
.transition() |
|
.duration(0) |
|
.attr('x', function(d) {return xScale(d[xVariable]);}) |
|
.attr('width', xScale.rangeBand) |
|
.attr('y', d => yScale(d[yVariable])) |
|
.attr('height', d => yScale(0) - yScale(d[yVariable])); |
|
|
|
updateSelection |
|
.on('mouseover', function () { |
|
d3.select(this) |
|
.style({ |
|
'fill': 'steelblue', |
|
'fill-opacity': 0.6 |
|
}); |
|
}) |
|
.on('mouseout', function () { |
|
d3.select(this) |
|
.style({ |
|
'fill': faintGray, |
|
'fill-opacity': 1 |
|
}); |
|
}); |
|
} |
|
|
|
function update(firstCall) { |
|
updateScales(); |
|
updateAxes(firstCall); |
|
updateBars(); |
|
} |
|
|
|
function initEvents() { |
|
// Set up event handler for resizes |
|
W.addListener(update); |
|
} |
|
|
|
initChart(); |
|
update(true); // set parameter `firstCall` to true this once |
|
initEvents(); |
|
}); |
|
</script> |
|
</body> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|