Skip to content

Instantly share code, notes, and snippets.

@molliemarie
Last active February 3, 2020 01:56
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 molliemarie/593bc86dfed1569fa1437e0a3077b3ce to your computer and use it in GitHub Desktop.
Save molliemarie/593bc86dfed1569fa1437e0a3077b3ce to your computer and use it in GitHub Desktop.
FirstScatterPlusInteractionsPlusLinePlusGeneralUpdatePattern
license: mit
<!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);
setScales(thisDataGroup);
setAxes();
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));
drawCircles(thisDataGroup)
d3.select('#titleText')
.text('UFO Sightings in ' + datasetGroup);
};
function drawCircles(thisData) {
const groups = svg.selectAll('.ufoGroup')
.data(thisData, function(d) { return d.month })
// groups
// .enter().append('g')
const enterGroups = groups
.enter().append('g')
// will need to assign class and location to incoming data groups
.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)
})
// add new circles
enterGroups.append('circle')
.attr('class', 'ufoCircle')
.style('fill', 'limegreen')
.attr('r', radius)
// add new text
enterGroups.append('text')
.attr('class', 'ufoText')
.attr('dx', radius)
.attr('dy', -radius)
.text(function(d) { return d.count})
.style('opacity', 0)
groups
.merge(groups)
.transition()
.ease(d3.easeElastic)
.duration(transitionTime)
.attr('transform', function(d) { return 'translate(' + xScale(d.parsedDate) + ',' + yScale(d.count) + ')'})
groups.exit().remove()
}
function setScales(thisData) {
xScale
.domain(d3.extent(thisData, function(d) { return d.parsedDate; }));
yScale
.domain([0, d3.max(thisData, function(d) { return d.count; })]);
};
function setAxes() {
xAxis.scale(xScale);
yAxis.scale(yScale);
xAxisGroup
.call(xAxis);
yAxisGroup
.transition()
.duration(transitionTime)
.call(yAxis);
}
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)
});
setScales(startData);
setAxes();
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));
drawCircles(startData)
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment