Built with blockbuilder.org
forked from molliemarie's block: FirstScatterComplete
| license: mit |
Built with blockbuilder.org
forked from molliemarie's block: FirstScatterComplete
| <!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; | |
| } | |
| </style> | |
| <body> | |
| <div id='titleDiv'> | |
| <text>UFO Sightings in 2018</text> | |
| </div> | |
| <div id = 'buttonsDiv'> | |
| </div> | |
| </body> | |
| <script> | |
| //***** defining variables ***** | |
| 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; | |
| //***** setting up svgs ***** | |
| 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 + ")"); | |
| //***** setting up scales and axes ***** | |
| 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); | |
| //***** reading in data ***** | |
| d3.csv("https://raw.githubusercontent.com/molliemarie/MSIA-D3Course-2019/master/Projects%26Exercises/FirstCompleteScatter/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); | |
| //***** once data is ready, pass into ready function ***** | |
| function ready(fullData) { | |
| window.fullData = fullData; | |
| const yearList = d3.set(fullData.map(function(d) { return d.year })).values(); | |
| function dataSwap(datasetGroup) { | |
| //filters data using new input year | |
| const thisDataGroup = fullData.filter(function(d) { return d.year == datasetGroup}) | |
| xScale | |
| .domain(d3.extent(thisDataGroup, function(d) { return d.parsedDate; })) | |
| yScale | |
| .domain([0, d3.max(thisDataGroup, function(d) { return d.count; })]); | |
| // attaches new scales to the axes | |
| xAxis.scale(xScale); | |
| yAxis.scale(yScale); | |
| // Updates the axis groups, and therefore the labels | |
| 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) + ')'}) | |
| d3.select('#titleDiv') | |
| .text('UFO Sightings in ' + datasetGroup); | |
| } | |
| d3.select('#buttonsDiv') //select div with id buttonsDiv | |
| .selectAll('button') //look for existing buttons | |
| .data(yearList) //bind data (year list) | |
| .enter().append('button') //append buttons for each data point | |
| .text(function(d) { return d; }) | |
| .on('click', function(d) { | |
| dataSwap(d)}); | |
| //***** filtering to get startData ***** | |
| const startData = fullData.filter(function(d) { return d.year == 2018; }) | |
| console.log(startData) | |
| //***** updating scales with data ***** | |
| xScale.domain(d3.extent(startData, function(d) { return d.parsedDate; })) | |
| yScale.domain([0, d3.max(startData, function(d) { return d.count})]) | |
| //***** Create axis groups ***** | |
| 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); | |
| //***** defining ufoGroup ***** | |
| 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) { | |
| d3.select(this) | |
| .select('text') | |
| .transition() | |
| .duration(transitionTime) | |
| .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) { | |
| d3.select(this) | |
| .select('text') | |
| .transition() | |
| .duration(transitionTime) | |
| .style('opacity', 0) | |
| d3.select(this) | |
| .select('circle') | |
| .transition() | |
| .ease(d3.easeElastic) | |
| .duration(transitionTime) | |
| .attr('r', radius) | |
| d3.selectAll('circle') | |
| .style('opacity', 1) | |
| }); | |
| //***** appending circles ***** | |
| ufoGroup.append('circle') | |
| .attr('class', 'ufoCircle') | |
| .attr('r', radius) | |
| //***** appending text ***** | |
| ufoGroup.append('text') | |
| .attr('class', 'ufoText') | |
| .attr('dx', 10) | |
| .attr('dy', -10) | |
| .text(function(d) { return d.count}) | |
| .attr('opacity', 0); | |
| } | |
| </script> |