Skip to content

Instantly share code, notes, and snippets.

@molliemarie
Last active February 7, 2019 22:15
Show Gist options
  • Save molliemarie/f2bbb2ec0b339d5e60a30a69b3a02f7d to your computer and use it in GitHub Desktop.
Save molliemarie/f2bbb2ec0b339d5e60a30a69b3a02f7d to your computer and use it in GitHub Desktop.
UFO sightings plot
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style type="text/css">
.axis line {
stroke-width:1px;
stroke: #ccc;
stroke-dasharray: 2px 2px;
}
.axis text {
font-size: 12px;
fill: #777;
}
.axis path {
display: none;
}
.circle-group text {
fill: #aaa; /*grey out text*/
font-size: 11px;
}
/* *2* style line */
.ufoLine {
/*removes black fill*/
fill: none;
/*styles line */
stroke-width: 1.5;
stroke: darkgray;
stroke-width: 3 ;
}
/*NEW CSS GOES HERE*/
</style>
<body>
<div id='titleDiv'></div>
<div id="buttonsDiv"></div>
</body>
<script>
//NOW LET'S ADD A LINE
// *1* create line for original data
// *2* style line to remove all that black
// *3* update line in dataSwap function
// define dataSwap function
function dataSwap(datasetGroup) {
// filter data to get new data subset based on year
var thisDataGroup = data.filter(function(d) { return d.year == datasetGroup});
// define scale domains using new data, pass newly defined scales into axes, call axes for each axis group
xScale
.domain(d3.extent(thisDataGroup, function(d) { return d.date; }));
yScale
.domain(d3.extent(thisDataGroup, function(d) { return d.count; }));
xAxis.scale(xScale);
yAxis.scale(yScale);
xAxisGroup
.call(xAxis);
yAxisGroup
.transition()
.duration(transitionTime)
.call(yAxis);
// *3* update line in dataSwap function
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));
// move locations of each ufo group (each of which contain a circle and text)
svg.selectAll('.ufoGroup')
.data(thisDataGroup)
.transition()
.ease(d3.easeElastic)
.duration(transitionTime)
.attr('transform', function(d) { return 'translate(' + xScale(d.date) + ',' + yScale(d.count) + ')'})
// update title
d3.select('#titleText')
.text('UFO Sightings in ' + datasetGroup);
}
// define variables, including svg, margins, etc.
var radius = 10;
var parseTime = d3.timeParse("%m/%Y");
var transitionTime = 1000
var margin = {top: 50, right: 10, bottom: 20, left: 40};
var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Add a title. This could alternatively be done above in the html section
d3.select('#titleDiv')
.append('h1')
.attr('id', 'titleText')
.text('UFO Sightings in 2018')
// define xScale and yScale; will define domain later within ready function
var xScale = d3.scaleTime()
.range([0, width]);
var yScale = d3.scaleLinear()
.range([height, 0])
// Define xAxis and yAxis, will define associated scales inside ready function
var xAxis = d3.axisBottom()
.tickSize(-height);
var yAxis = d3.axisLeft()
.tickSize(-width);
// Define xAxisGroup and yAxisGroup. Will call the appropriate axis within ready function
var xAxisGroup = svg.append("g")
.attr("class", "x axis") //gives group the classes `x` and `axis`
.attr("transform", "translate(0," + height + ")");
var yAxisGroup = svg.append("g")
.attr("class", "y axis"); //gives group the classes `y` and `axis`
// *1* create line for original data
var lineGenerator = d3.line()
.curve(d3.curveCardinal); //makes line 'curvy'
// transforming data into json
d3.csv("ufo.csv", ready)
function ready(error, data) {
if (error) return console.warn(error);
window.data = data;
// format data
data.forEach(function(d) {
d.count = +d.count;
d.month = d.date.split('/')[0];
d.date = parseTime(d.date);
d.year = d.date.getYear() + 1900
});
// filter to define startData
var startData = data.filter(function(d) { return d.year == 2018; })
// define domain of scales, pass newly defined scales into axes, call axes for each axis group
xScale.domain(d3.extent(startData, function(d) { return d.date; }));
yScale.domain(d3.extent(startData, function(d) { return d.count; }));
xAxis.scale(xScale)
yAxis.scale(yScale)
xAxisGroup.call(xAxis);
yAxisGroup.call(yAxis);
// create buttons
var yearList = d3.set(data.map(function(d) { return d.year })).values();
d3.select('#buttonsDiv')
.selectAll('button')
.data(yearList)
.enter().append('button')
.text(function(d) { return d; })
.on('click', function(d) {
dataSwap(d)
})
// *1* Create line
lineGenerator
.x(function(d) { return xScale(d.date)})
.y(function(d) { return yScale(d.count)})
svg.append('path')
.attr('class', 'ufoLine')
.attr('d', lineGenerator(startData));
// create ufo Groups
var ufoGroup = svg.selectAll('.ufoGroup')
.data(startData).enter().append('g')
.attr('class', 'ufoGroup')
.attr('transform', function(d) { return 'translate(' + xScale(d.date) + ',' + 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)
})
// append circles to ufo groups
ufoGroup.append('circle')
.attr('class', 'ufoCircle')
.style('fill', 'limegreen')
.attr('r', radius)
// append text to ufo groups
ufoGroup.append('text')
.attr('class', 'ufoText')
.attr('dx', radius)
.attr('dy', -radius)
.text(function(d) { return d.count})
.style('opacity', 0)
};
</script>
date count
12/2018 233
11/2018 228
10/2018 262
09/2018 293
08/2018 350
07/2018 400
06/2018 225
05/2018 243
04/2018 221
03/2018 235
02/2018 235
01/2018 311
12/2017 500
11/2017 351
10/2017 482
09/2017 58
08/2017 374
07/2017 485
06/2017 392
05/2017 356
04/2017 401
03/2017 337
02/2017 415
01/2017 324
12/2016 347
11/2016 489
10/2016 481
09/2016 591
08/2016 550
07/2016 681
06/2016 427
05/2016 380
04/2016 384
03/2016 411
02/2016 433
01/2016 419
12/2015 436
11/2015 902
10/2015 653
09/2015 730
08/2015 627
07/2015 736
06/2015 488
05/2015 466
04/2015 454
03/2015 480
02/2015 344
01/2015 540
12/2014 526
11/2014 549
10/2014 795
09/2014 835
08/2014 928
07/2014 1103
06/2014 784
05/2014 656
04/2014 670
03/2014 519
02/2014 555
01/2014 718
12/2013 769
11/2013 809
10/2013 798
09/2013 796
08/2013 923
07/2013 986
06/2013 647
05/2013 537
04/2013 430
03/2013 400
02/2013 284
01/2013 401
12/2012 675
11/2012 782
10/2012 678
09/2012 778
08/2012 907
07/2012 944
06/2012 768
05/2012 522
04/2012 504
03/2012 538
02/2012 398
01/2012 588
12/2011 538
11/2011 450
10/2011 644
09/2011 561
08/2011 646
07/2011 771
06/2011 409
05/2011 321
04/2011 318
03/2011 336
02/2011 276
01/2011 330
12/2010 307
11/2010 366
10/2010 479
09/2010 453
08/2010 533
07/2010 852
06/2010 390
05/2010 333
04/2010 296
03/2010 262
02/2010 191
01/2010 294
12/2009 294
11/2009 324
10/2009 324
09/2009 601
08/2009 504
07/2009 617
06/2009 392
05/2009 360
04/2009 319
03/2009 341
02/2009 397
01/2009 499
12/2008 350
11/2008 459
10/2008 536
09/2008 386
08/2008 506
07/2008 577
06/2008 485
05/2008 347
04/2008 444
03/2008 341
02/2008 372
01/2008 476
12/2007 362
11/2007 375
10/2007 449
09/2007 451
08/2007 474
07/2007 467
06/2007 431
05/2007 319
04/2007 323
03/2007 364
02/2007 268
01/2007 441
12/2006 387
11/2006 413
10/2006 401
09/2006 330
08/2006 430
07/2006 431
06/2006 344
05/2006 302
04/2006 323
03/2006 307
02/2006 234
01/2006 254
12/2005 279
11/2005 467
10/2005 488
09/2005 532
08/2005 355
07/2005 459
06/2005 412
05/2005 303
04/2005 317
03/2005 359
02/2005 278
01/2005 261
12/2004 306
11/2004 331
10/2004 453
09/2004 413
08/2004 552
07/2004 439
06/2004 432
05/2004 391
04/2004 393
03/2004 416
02/2004 301
01/2004 305
12/2003 383
11/2003 472
10/2003 475
09/2003 510
08/2003 545
07/2003 453
06/2003 309
05/2003 252
04/2003 226
03/2003 192
02/2003 267
01/2003 328
12/2002 251
11/2002 295
10/2002 340
09/2002 378
08/2002 489
07/2002 434
06/2002 352
05/2002 251
04/2002 194
03/2002 197
02/2002 260
01/2002 239
12/2001 214
11/2001 280
10/2001 257
09/2001 351
08/2001 397
07/2001 410
06/2001 315
05/2001 255
04/2001 236
03/2001 291
02/2001 235
01/2001 284
12/2000 233
11/2000 232
10/2000 330
09/2000 299
08/2000 298
07/2000 366
06/2000 278
05/2000 189
04/2000 200
03/2000 225
02/2000 204
01/2000 231
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment