Built with blockbuilder.org
forked from molliemarie's block: FirstScatterComplete
forked from molliemarie's block: FirstScatterPlusInteractionsComplete
forked from molliemarie's block: FirstScatterPlusInteractionsPlusLineComplete
license: mit |
Built with blockbuilder.org
forked from molliemarie's block: FirstScatterComplete
forked from molliemarie's block: FirstScatterPlusInteractionsComplete
forked from molliemarie's block: FirstScatterPlusInteractionsPlusLineComplete
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<style type="text/css"> | |
svg { | |
border:1px solid #f0f; | |
} | |
.axis line { | |
stroke-width:1px; | |
stroke: #ccc; | |
stroke-dasharray: 2px 2px; | |
} | |
.axis text { | |
font-size: 12px; | |
fill: #777; | |
} | |
.axis path { | |
display: none; | |
} | |
.ufoGroup text { | |
fill: #aaa; /*grey out text*/ | |
font-size: 11px; | |
} | |
.ufoCircle { | |
fill: limegreen; | |
} | |
.ufoLine { | |
fill: none; | |
} | |
.ufoLine { | |
/*removes black fill*/ | |
fill: none; | |
/*styles line */ | |
stroke: darkgray; | |
stroke-width: 3 ; | |
} | |
</style> | |
<body> | |
<div id='titleDiv'> | |
<text>UFO Sightings in 2018</text> | |
<div id="buttonsDiv"></div> | |
</div> | |
</body> | |
<script> | |
//The data | |
function dataSwap(datasetGroup, fullData) { | |
const thisDataGroup = fullData.filter(function(d) { return d.year == datasetGroup}); | |
console.log(thisDataGroup); | |
xScale | |
.domain(d3.extent(thisDataGroup, function(d) { return d.parsedDate; })); | |
yScale | |
.domain([0, d3.max(thisDataGroup, function(d) { return d.count; })]); | |
xAxis.scale(xScale); | |
yAxis.scale(yScale); | |
xAxisGroup | |
.call(xAxis); | |
yAxisGroup | |
.transition() | |
.duration(transitionTime) | |
.call(yAxis); | |
svg.selectAll('.ufoGroup') | |
.data(thisDataGroup) | |
.transition() | |
.ease(d3.easeElastic) | |
.duration(transitionTime) | |
.attr('transform', function(d) { return 'translate(' + xScale(d.parsedDate) + ',' + yScale(d.count) + ')'}) | |
svg.selectAll('.ufoLine') | |
.transition() | |
.ease(d3.easeElastic) //if you use the same ease here as you do with the circles, the line and circles will move together. | |
.duration(transitionTime) | |
.attr('d', lineGenerator(thisDataGroup)); | |
d3.select('#titleText') | |
.text('UFO Sightings in ' + datasetGroup); | |
}; | |
const parseTime = d3.timeParse("%m/%Y"); | |
const margin = {top: 20, right: 30, bottom: 20, left: 30}; | |
const outerWidth = 700; | |
const outerHeight = 300; | |
const innerWidth = outerWidth - margin.left - margin.right; | |
const innerHeight = outerHeight - margin.top - margin.bottom; | |
const transitionTime = 1000; | |
const radius = 10; | |
const SVG = d3.select("body").append("svg") | |
.attr("width", outerWidth) | |
.attr("height", outerHeight); | |
const svg = SVG.append('g') | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
const xScale = d3.scaleTime() | |
.range([0, innerWidth]); | |
const xAxis = d3.axisBottom(xScale) | |
.tickSize(-innerHeight); | |
const yScale = d3.scaleLinear() | |
.range([innerHeight, 0]) | |
const yAxis = d3.axisLeft(yScale) | |
.tickSize(-innerWidth); | |
const lineGenerator = d3.line() | |
.curve(d3.curveCardinal); | |
const xAxisGroup = svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + innerHeight + ")") | |
.call(xAxis); | |
const yAxisGroup = svg.append("g") | |
.attr("class", "y axis") //gives group the classes 'y' and 'axis' | |
.call(yAxis); | |
d3.csv("https://raw.githubusercontent.com/molliemarie/MSIA-D3Course-2019/master/Projects%26Exercises/generalUpdatePattern/data/ufo.csv", function(d) { | |
return { | |
date: d.date, | |
count: +d.count, | |
month: +d.date.split('/')[0], | |
parsedDate: parseTime(d.date), | |
year: parseTime(d.date).getYear() + 1900 | |
}; | |
}).then(ready); | |
function ready(fullData) { | |
const yearList = d3.set(fullData.map(function(d) { return d.year })).values(); | |
const startData = fullData.filter(function(d) { return d.year == 2018; }); | |
console.log(startData); | |
d3.select('#buttonsDiv') | |
.selectAll('button') | |
.data(yearList) | |
.enter().append('button') | |
.text(function(d) { return d; }) | |
.on('click', function(d) { | |
dataSwap(d, fullData) | |
}); | |
xScale.domain(d3.extent(startData, function(d) { return d.parsedDate; })); | |
yScale.domain([0, d3.max(startData, function(d) { return d.count})]); | |
xAxisGroup.call(xAxis); | |
yAxisGroup.call(yAxis); | |
lineGenerator | |
.x(function(d) { return xScale(d.parsedDate)}) | |
.y(function(d) { return yScale(d.count)}) | |
svg.append('path') | |
.attr('class', 'ufoLine') | |
.attr('d', lineGenerator(startData)); | |
const ufoGroup = svg.selectAll('.ufoGroup') | |
.data(startData).enter().append('g') | |
.attr('class', 'ufoGroup') | |
.attr('transform', function(d) { return 'translate(' + xScale(d.parsedDate) + ',' + yScale(d.count) + ')'}) | |
.on('mouseenter', function(d) { | |
// define hover events | |
d3.select(this) | |
.select('text') | |
.transition() | |
.duration(0) | |
.style('opacity', 1) | |
d3.selectAll('circle') | |
.style('opacity', 0.5) | |
d3.select(this) | |
.select('circle') | |
.transition() | |
.ease(d3.easeElastic) | |
.duration(transitionTime) | |
.attr('r', radius*2) | |
.style('opacity', 1) | |
}) | |
.on('mouseleave', function(d) { | |
// define mouseleave events | |
d3.select(this) | |
.select('text') | |
.transition() | |
.style('opacity', 0) | |
d3.select(this) | |
.select('circle') | |
.transition() | |
.ease(d3.easeElastic) | |
.duration(transitionTime) | |
.attr('r', radius) | |
d3.selectAll('circle') | |
.style('opacity', 1) | |
}) | |
ufoGroup.append('circle') | |
.attr('class', 'ufoCircle') | |
.attr('r', 10) | |
ufoGroup.append('text') | |
.attr('class', 'ufoText') | |
.attr('dx', 10) | |
.attr('dy', -10) | |
.text(function(d) { return d.count}) | |
.attr('opacity', 0) | |
} | |
</script> |