Added UI wrapper. Bar chart color avg. Finishing touches.

master
Ben Burlingham 10 years ago
parent f1a8e3c1ce
commit 20ec04240e
  1. 6
      css/index.css
  2. 44
      index.html
  3. 13
      js/behaviors.js
  4. 87
      js/chart.js
  5. 2
      js/chart3.js
  6. 15
      js/data.js
  7. 1
      js/init.js
  8. 2
      sass/chart.scss
  9. 4
      sass/index.scss

@ -7,8 +7,8 @@
.main { .main {
height: 920px; height: 920px;
margin: 10px auto; margin: 10px auto 100px auto;
padding: 20px; padding: 50px 20px;
position: relative; position: relative;
width: 800px; } width: 800px; }
@ -18,7 +18,7 @@
left: 540px; left: 540px;
position: absolute; position: absolute;
top: 20px; top: 20px;
width: 240px; } width: 220px; }
#chart svg { #chart svg {
margin-left: 30px; margin-left: 30px;
height: 100%; height: 100%;

@ -4,9 +4,35 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title></title> <title></title>
<link href='css/index.css' rel='stylesheet' type='text/css'> <link href='css/index.css' rel='stylesheet' type='text/css'>
<script src='/bb-2016/js/ui.js'></script>
</head> </head>
<body> <body>
<h1>Buoy Analysis</h1>
<h2>NOAA data for stations off the California coast from 1982 to 2015</h2>
<hr>
<h3>Project Goal</h3>
<blockquote>
Create visualization of California coastal ocean temperature data to find monthly and yearly trends.
<br><br>
Visualization should invite interaction to create and answer questions such as:
<ul>
<li>Are ocean temperatures increasing?</li>
<li>What are the visible effects of El Nino?</li>
<li>What is the temperature of the ocean near San Francisco?</li>
</ul>
</blockquote>
<p>
Data source: <a href="http://www.ndbc.noaa.gov/">National Data Buoy Center</a>. Historical data, such as <a href="http://www.ndbc.noaa.gov/station_history.php?station=46213">46213 Cape Mendocino</a>, is mostly available since 1982. Extract, transform, and reduce scripts run on Node, publically available in <a href="http://gogs.benburlingham.com/ben.burlingham/buoy-analysis">source code</a>.
</p>
<p>
This visualization is created using D3 and Three.js libraries.
</p>
<div class="main"> <div class="main">
<div id='map'><svg></svg></div> <div id='map'><svg></svg></div>
@ -32,9 +58,6 @@
<div id="chart3"></div> <div id="chart3"></div>
</div> </div>
- MAP harbors
<!-- <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> --> <!-- <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> -->
<!-- <script src="//d3js.org/topojson.v1.min.js"></script> --> <!-- <script src="//d3js.org/topojson.v1.min.js"></script> -->
<!-- https://cdnjs.cloudflare.com/ajax/libs/three.js/r74/three.min.js --> <!-- https://cdnjs.cloudflare.com/ajax/libs/three.js/r74/three.min.js -->
@ -53,20 +76,9 @@
<script src="js/chart3.js"></script> <script src="js/chart3.js"></script>
<script src="js/init.js"></script> <script src="js/init.js"></script>
<!-- <script src="gradients-v1.js"></script> -->
<!-- <script src="gradients-v2.js"></script> -->
<!-- <script src="gradients-v3.js"></script> -->
<!-- <script src="gradients-v4.js"></script> -->
<!-- <!--
Deploy!
var camX = -20; Pong!
var camY = -300;
var camZ = 150;
var tgtX = 425;
var tgtY = 300;
var tgtZ = -20;
https://css-tricks.com/svg-line-animation-works/ https://css-tricks.com/svg-line-animation-works/

@ -13,6 +13,7 @@ var BuoyAnalysisBehaviors = {
}); });
BuoyAnalysisMap.findStationsUnderReticle(); BuoyAnalysisMap.findStationsUnderReticle();
BuoyAnalysisChart.updateColor();
BuoyAnalysisChart.draw(); BuoyAnalysisChart.draw();
BuoyAnalysisChart3.draw(); BuoyAnalysisChart3.draw();
}, },
@ -33,6 +34,7 @@ var BuoyAnalysisBehaviors = {
.attr('transform', 'translate(' + [ d.x, d.y ] + ')') .attr('transform', 'translate(' + [ d.x, d.y ] + ')')
BuoyAnalysisMap.findStationsUnderReticle(); BuoyAnalysisMap.findStationsUnderReticle();
BuoyAnalysisChart.updateColor();
BuoyAnalysisChart.draw(); BuoyAnalysisChart.draw();
BuoyAnalysisChart3.draw(); BuoyAnalysisChart3.draw();
}, },
@ -86,23 +88,24 @@ var BuoyAnalysisBehaviors = {
e.classed('selected', true); e.classed('selected', true);
if (e.classed('toggle1')) { if (e.classed('toggle1')) {
BuoyAnalysisChart.bars.property = 'at'; BuoyAnalysisData.property = 'at';
} }
else if (e.classed('toggle2')) { else if (e.classed('toggle2')) {
BuoyAnalysisChart.bars.property = 'wt'; BuoyAnalysisData.property = 'wt';
} }
else if (e.classed('toggle3')) { else if (e.classed('toggle3')) {
BuoyAnalysisChart.bars.property = 'wh'; BuoyAnalysisData.property = 'wh';
} }
else if (e.classed('toggle4')) { else if (e.classed('toggle4')) {
BuoyAnalysisChart.bars.property = 'wp'; BuoyAnalysisData.property = 'wp';
} }
else if (e.classed('toggle5')) { else if (e.classed('toggle5')) {
BuoyAnalysisChart.bars.property = 'ws'; BuoyAnalysisData.property = 'ws';
} }
BuoyAnalysisChart.updateAxes(); BuoyAnalysisChart.updateAxes();
BuoyAnalysisChart.draw(); BuoyAnalysisChart.draw();
BuoyAnalysisChart3.draw();
}, },
/** /**

@ -8,19 +8,16 @@ var BuoyAnalysisChart = {
padding: 15, padding: 15,
spacing: 2, spacing: 2,
height: 23, height: 23,
width: 210, width: 190,
color: '#f00',
showMonths: true, showMonths: true,
showYears: true, showYears: true,
property: 'wt',
tickValues: null, tickValues: null,
imperialLabel: null, imperialLabel: null,
metricLabel: null, metricLabel: null,
leftHexValue: null,
rightHexValue: null
}, },
axis: { axis: {
@ -45,33 +42,8 @@ var BuoyAnalysisChart = {
return year * BuoyAnalysisChart.bars.height + BuoyAnalysisChart.bars.padding + year * BuoyAnalysisChart.bars.spacing + (i % 12) * 2; return year * BuoyAnalysisChart.bars.height + BuoyAnalysisChart.bars.padding + year * BuoyAnalysisChart.bars.spacing + (i % 12) * 2;
}, },
/** /**
* * DOM init.
*/
// appendGradient: function() {
// var chart = d3.select('#chart svg');
// var id = 'gradient-year';
// chart.selectAll('#' + id).remove();
// var gradient = chart.append("svg:defs")
// .append("svg:linearGradient")
// .attr("id", id)
// gradient.append("svg:stop")
// .attr("offset", "0%")
// .attr("stop-color", BuoyAnalysisChart.bars.leftHexValue)
// .attr("stop-opacity", 1);
// gradient.append("svg:stop")
// .attr("offset", "100%")
// .attr("stop-color", BuoyAnalysisChart.bars.rightHexValue)
// .attr("stop-opacity", 1);
// },
/**
*
*/ */
appendYearLabels: function() { appendYearLabels: function() {
var years = BuoyAnalysisData.calculateYearlyAverages(BuoyAnalysisMap.reticle.stations); var years = BuoyAnalysisData.calculateYearlyAverages(BuoyAnalysisMap.reticle.stations);
@ -89,7 +61,7 @@ var BuoyAnalysisChart = {
}, },
/** /**
* * DOM init.
*/ */
appendAxes: function() { appendAxes: function() {
var chart = d3.select('#chart svg'); var chart = d3.select('#chart svg');
@ -114,22 +86,44 @@ var BuoyAnalysisChart = {
.classed('label-axis-x', true) .classed('label-axis-x', true)
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.text(BuoyAnalysisChart.bars.imperialLabel) .text(BuoyAnalysisChart.bars.imperialLabel)
.attr('x', 200) .attr('x', 180)
.attr('y', 10) .attr('y', 10)
chart.append('text') chart.append('text')
.classed('label-axis-x', true) .classed('label-axis-x', true)
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.text(BuoyAnalysisChart.bars.metricLabel) .text(BuoyAnalysisChart.bars.metricLabel)
.attr('x', 200) .attr('x', 180)
.attr('y', 876) .attr('y', 876)
}, },
/** /**
* * Updates the color of the bars to an average of current station colors.
*/
updateColor: function() {
var r, g, b, station, tmp;
r = g = b = 0;
function avg(val) {
return Math.round(val / BuoyAnalysisMap.reticle.stations.length);
}
BuoyAnalysisMap.reticle.stations.forEach(function(s) {
station = BuoyAnalysisData.stationJson[s];
tmp = BuoyAnalysisMap.stationColorScale(station.lat).substr(1).match(/.{1,2}/g);
r += parseInt(tmp[0], 16);
g += parseInt(tmp[1], 16);
b += parseInt(tmp[2], 16);
});
BuoyAnalysisChart.bars.color = 'rgba(' + avg(r) + ',' + avg(g) + ',' + avg(b) + ', 0.1)';
},
/**
* Handles unit and scale changes.
*/ */
updateAxes: function() { updateAxes: function() {
switch(BuoyAnalysisChart.bars.property) { switch(BuoyAnalysisData.property) {
case 'at': case 'at':
BuoyAnalysisChart.bars.tickValues = [8, 12, 16, 20]; BuoyAnalysisChart.bars.tickValues = [8, 12, 16, 20];
@ -194,11 +188,9 @@ var BuoyAnalysisChart = {
var len = BuoyAnalysisData.years.end - BuoyAnalysisData.years.start + 1; var len = BuoyAnalysisData.years.end - BuoyAnalysisData.years.start + 1;
var h = (BuoyAnalysisChart.bars.height + BuoyAnalysisChart.bars.spacing) * len + BuoyAnalysisChart.bars.padding; var h = (BuoyAnalysisChart.bars.height + BuoyAnalysisChart.bars.spacing) * len + BuoyAnalysisChart.bars.padding;
// alert(BuoyAnalysisData.bars.height + ' ' + BuoyAnalysisChart.bars.spacing)
BuoyAnalysisData.setAxisProperties(); BuoyAnalysisData.setAxisProperties();
BuoyAnalysisChart.appendAxes(); BuoyAnalysisChart.appendAxes();
// BuoyAnalysisChart.appendGradient();
BuoyAnalysisChart.appendYearLabels(); BuoyAnalysisChart.appendYearLabels();
chart.selectAll('.bar-year').remove(); chart.selectAll('.bar-year').remove();
@ -231,30 +223,13 @@ var BuoyAnalysisChart = {
chart.selectAll('.bar-year').data(years).enter() chart.selectAll('.bar-year').data(years).enter()
.append('rect') .append('rect')
.classed('bar-year', true) .classed('bar-year', true)
// .attr('fill', 'url("#gradient-year")') .attr('fill', BuoyAnalysisChart.bars.color)
.attr('fill', '#f0f0ff')
.attr('height', 23) .attr('height', 23)
// .attr('width', BuoyAnalysisChart.bars.width)
.attr('width', function(d) { .attr('width', function(d) {
return BuoyAnalysisChart.axis.scale(d.average); return BuoyAnalysisChart.axis.scale(d.average);
}) })
.attr('x', 0) .attr('x', 0)
.attr('y', BuoyAnalysisChart.barYearY) .attr('y', BuoyAnalysisChart.barYearY)
// chart.selectAll('.mask-year').data(years).enter()
// .append('rect')
// .classed('.mask-year', true)
// .attr('fill', '#fff')
// .attr('height', 23)
// .attr('width', function(d) {
// return Math.max(0, BuoyAnalysisChart.bars.width - BuoyAnalysisChart.axis.scale(d.average));
// })
// .attr('x', function(d) {
// return BuoyAnalysisChart.axis.scale(d.average);
// })
// .attr('y', function(d, i) {
// return BuoyAnalysisChart.barYearY(d, i);
// })
} }
if (BuoyAnalysisChart.bars.showMonths === true) { if (BuoyAnalysisChart.bars.showMonths === true) {

@ -131,7 +131,7 @@ var BuoyAnalysisChart3 = {
var geo = new THREE.PlaneGeometry(40, 300, 1, BuoyAnalysisData.years.end - BuoyAnalysisData.years.start); var geo = new THREE.PlaneGeometry(40, 300, 1, BuoyAnalysisData.years.end - BuoyAnalysisData.years.start);
for (var year = BuoyAnalysisData.years.start, i = 0; year <= BuoyAnalysisData.years.end; year++, i++) { for (var year = BuoyAnalysisData.years.start, i = 0; year <= BuoyAnalysisData.years.end; year++, i++) {
h = BuoyAnalysisData.stationJson[station]['a' + year]['wt']['y'] * 10 || h; h = BuoyAnalysisData.stationJson[station]['a' + year][BuoyAnalysisData.property]['y'] * 10 || h;
geo.vertices[2 * i].z = h; geo.vertices[2 * i].z = h;
geo.vertices[2 * i + 1].z = h; geo.vertices[2 * i + 1].z = h;

@ -7,6 +7,8 @@ var BuoyAnalysisData = {
stationJson: {}, stationJson: {},
property: 'wt',
years: { years: {
start: 1982, start: 1982,
end: 2015 end: 2015
@ -39,9 +41,9 @@ var BuoyAnalysisData = {
/** /**
* *
*/ */
setAxisProperties: function(property, tickValues) { setAxisProperties: function() {
var json = BuoyAnalysisData.stationJson; var json = BuoyAnalysisData.stationJson;
var property = BuoyAnalysisChart.bars.property; var property = BuoyAnalysisData.property;
var tickValues = BuoyAnalysisChart.bars.tickValues; var tickValues = BuoyAnalysisChart.bars.tickValues;
BuoyAnalysisChart.axis.min = 100; BuoyAnalysisChart.axis.min = 100;
@ -68,16 +70,13 @@ var BuoyAnalysisData = {
BuoyAnalysisChart.axis.scale = d3.scale.linear().domain([0, BuoyAnalysisChart.axis.max]) BuoyAnalysisChart.axis.scale = d3.scale.linear().domain([0, BuoyAnalysisChart.axis.max])
.range([0, BuoyAnalysisChart.bars.width]); .range([0, BuoyAnalysisChart.bars.width]);
// BuoyAnalysisChart.axis.scaleInverted = d3.scale.linear().domain([0, BuoyAnalysisChart.axis.max])
// .range([BuoyAnalysisChart.bars.width, 0]);
BuoyAnalysisChart.axis.imperial = d3.svg.axis() BuoyAnalysisChart.axis.imperial = d3.svg.axis()
.scale(BuoyAnalysisChart.axis.scale) .scale(BuoyAnalysisChart.axis.scale)
.orient("top") .orient("top")
.tickFormat(function(d) { .tickFormat(function(d) {
var val; var val;
switch(BuoyAnalysisChart.bars.property) { switch(BuoyAnalysisData.property) {
case 'at': case 'at':
case 'wt': case 'wt':
val = Math.round(d * 9 / 5 + 32); val = Math.round(d * 9 / 5 + 32);
@ -115,7 +114,7 @@ var BuoyAnalysisData = {
count = 0; count = 0;
stations.forEach(function(id) { stations.forEach(function(id) {
data = BuoyAnalysisData.stationJson[id]['a' + year][BuoyAnalysisChart.bars.property]; data = BuoyAnalysisData.stationJson[id]['a' + year][BuoyAnalysisData.property];
if (data === undefined || data.y === 0) { if (data === undefined || data.y === 0) {
return; return;
@ -144,7 +143,7 @@ var BuoyAnalysisData = {
count = 0; count = 0;
stations.forEach(function(id) { stations.forEach(function(id) {
data = BuoyAnalysisData.stationJson[id]['a' + year][BuoyAnalysisChart.bars.property]; data = BuoyAnalysisData.stationJson[id]['a' + year][BuoyAnalysisData.property];
if (data === undefined || data.m[month] === 0) { if (data === undefined || data.m[month] === 0) {
return; return;

@ -16,6 +16,7 @@
.then(BuoyAnalysisBehaviors.attachBehaviors) .then(BuoyAnalysisBehaviors.attachBehaviors)
.then(BuoyAnalysisChart.updateAxes) .then(BuoyAnalysisChart.updateAxes)
.then(BuoyAnalysisChart.updateColor)
.then(BuoyAnalysisChart.draw) .then(BuoyAnalysisChart.draw)
.then(BuoyAnalysisChart3.init) .then(BuoyAnalysisChart3.init)

@ -7,7 +7,7 @@
left:540px; left:540px;
position:absolute; position:absolute;
top:20px; top:20px;
width:240px; width:220px;
svg { svg {
margin-left:$axisW; margin-left:$axisW;

@ -13,8 +13,8 @@ $mainW: 800px;
.main { .main {
height:$mainH; height:$mainH;
margin:10px auto; margin:10px auto 100px auto;
padding:20px; padding:50px 20px;
position:relative; position:relative;
width:$mainW; width:$mainW;
} }

Loading…
Cancel
Save