Column selector. NPM-based build environment.

master
ben-burlingham 10 years ago
parent df595d6c5e
commit 9db3080d34
  1. BIN
      .sass-cache/5c9c699b536baf3fb8147b977bb72448ea259feb/index.scssc
  2. BIN
      bar-display.png
  3. 2
      client/_stations.json
  4. 83
      client/behaviors.js
  5. 227
      client/chart.js
  6. 89
      client/data.js
  7. 2
      client/init.js
  8. 159
      css/index.css
  9. 158
      index.html
  10. 24
      package.json
  11. BIN
      raw/bar-display.psd
  12. 3
      readme.md
  13. 52
      sass/chart.scss
  14. 22
      sass/index.scss
  15. 18
      sass/map.scss
  16. 116
      sass/options.scss
  17. 184
      server/assemble.js
  18. 5
      server/meteo.js
  19. 21
      tasks/sass.js
  20. 11
      tasks/watch.js

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

@ -1,18 +1,17 @@
'use strict';
var BuoyAnalysisBehaviors = {
stationClick: function() {
},
stationMouseover: function() {
},
/**
*
*/
reticleDrag: function(d) {
},
/**
*
*/
reticleDragEnd: function() {
var x = d3.mouse(this)[0];
var y = d3.mouse(this)[1];
@ -39,10 +38,72 @@ var BuoyAnalysisBehaviors = {
BuoyAnalysisChart.draw();
},
/**
*
*/
reticleResize: function() {
},
/**
*
*/
barDisplayClick: function(d) {
var e = d3.select(this);
d3.selectAll('.bar-display .toggle').classed('selected', false);
e.classed('selected', true);
if (e.classed('toggle1')) {
BuoyAnalysisChart.bars.showYears = true;
BuoyAnalysisChart.bars.showMonths = true;
}
else if (e.classed('toggle2')) {
BuoyAnalysisChart.bars.showYears = false;
BuoyAnalysisChart.bars.showMonths = true;
}
else if (e.classed('toggle3')) {
BuoyAnalysisChart.bars.showYears = true;
BuoyAnalysisChart.bars.showMonths = false;
}
BuoyAnalysisChart.draw();
},
/**
*
*/
columnDisplayClick: function(d) {
var e = d3.select(this);
d3.selectAll('.column-display .toggle').classed('selected', false);
e.classed('selected', true);
if (e.classed('toggle1')) {
BuoyAnalysisChart.bars.property = 'ATMP';
}
else if (e.classed('toggle2')) {
BuoyAnalysisChart.bars.property = 'WTMP';
}
else if (e.classed('toggle3')) {
BuoyAnalysisChart.bars.property = 'WVHT';
}
else if (e.classed('toggle4')) {
BuoyAnalysisChart.bars.property = 'WPER';
}
else if (e.classed('toggle5')) {
BuoyAnalysisChart.bars.property = 'WSPD';
}
BuoyAnalysisChart.updateAxes();
BuoyAnalysisChart.draw();
},
/**
*
*/
attachBehaviors: function() {
d3.select('#map')
.on('click', BuoyAnalysisBehaviors.reticleDragEnd)
@ -50,7 +111,13 @@ var BuoyAnalysisBehaviors = {
// .on('drag', BuoyAnalysisBehaviors.reticleDrag)
// .on('dragend', BuoyAnalysisBehaviors.reticleDragEnd)
// );
},
d3.selectAll('.bar-display .toggle')
.on('click', BuoyAnalysisBehaviors.barDisplayClick);
d3.selectAll('.column-display .toggle')
.on('click', BuoyAnalysisBehaviors.columnDisplayClick);
}
};
// d3.selectAll('.detail')

@ -5,9 +5,31 @@ var BuoyAnalysisChart = {
*
*/
bars: {
padding: 24,
padding: 26,
spacing: 2,
width: 23,
showMonths: true,
showYears: true,
property: 'WTMP',
tickValues: null,
imperialLabel: null,
metricLabel: null,
smallHexValue: null,
largeHexValue: null
},
axis: {
h: 200,
min: 100,
max: 0,
scale: null,
scaleInverted: null,
imperial: null,
metric: null
},
/**
@ -22,107 +44,202 @@ var BuoyAnalysisChart = {
*/
barMonthX: function(d, i) {
var year = Math.floor(i / 12);
return year * BuoyAnalysisChart.bars.width + BuoyAnalysisChart.bars.padding + year * BuoyAnalysisChart.bars.spacing + (i % 12) * 2;
},
/**
*
*/
draw: function() {
var years = BuoyAnalysisData.calculateYearlyAverages(BuoyAnalysisMap.reticle.stations);
var months = BuoyAnalysisData.calculateMonthlyAverages(BuoyAnalysisMap.reticle.stations);
appendGradient: function() {
var chart = d3.select('#chart');
var id = 'gradient-year';
var toggles = d3.select('#year-toggles')
chart.selectAll('*').remove();
chart.selectAll('#' + id).remove();
var gradient = chart.append("svg:defs")
.append("svg:linearGradient")
.attr("id", "Gradient1")
.attr("id", id)
.attr('gradientTransform', 'rotate(90)')
gradient.append("svg:stop")
.attr("offset", "0%")
.attr("stop-color", "#6cf7ce")
.attr("stop-color", BuoyAnalysisChart.bars.largeHexValue)
.attr("stop-opacity", 1);
gradient.append("svg:stop")
.attr("offset", "100%")
.attr("stop-color", "#40596F")
.attr("stop-color", BuoyAnalysisChart.bars.smallHexValue)
.attr("stop-opacity", 1);
},
chart.selectAll('.bar-year').data(years).enter()
.append('rect')
.classed('bar-year', true)
.attr('fill', 'url("#Gradient1")')
.attr('width', 23)
.attr('height', BuoyAnalysisData.axis.h)
.attr('x', BuoyAnalysisChart.barYearX)
.attr('y', 0)
chart.selectAll('.mask-year').data(years).enter()
.append('rect')
.classed('.mask-year', true)
.attr('fill', '#fff')
.attr('width', 25)
.attr('height', function(d) {
return BuoyAnalysisData.axis.scale(d.average);
})
.attr('x', function(d, i) {
return BuoyAnalysisChart.barYearX(d, i) - 1;
})
.attr('y', 0)
/**
*
*/
appendYearLabels: function() {
var years = BuoyAnalysisData.calculateYearlyAverages(BuoyAnalysisMap.reticle.stations);
toggles.selectAll('div').data(years).enter()
d3.select('#year-labels').selectAll('div').data(years).enter()
.append('div')
.classed('year-toggle', true)
.classed('label', true)
.text(function(d) {
return d.year.toString().slice(-2);
})
.attr('x', BuoyAnalysisChart.barYearX)
.attr('y', 180)
},
/**
*
*/
appendAxes: function() {
var chart = d3.select('#chart');
chart.selectAll('.axis').remove();
chart.selectAll('.label-axis-y').remove();
chart.append("g")
.classed('axis', true)
.classed('axis-fahrenheit', true)
.attr('transform', 'translate(24, 0)')
.classed('axis-imperial', true)
.attr('transform', 'translate(30, 0)')
.attr('fill', '#000')
.call(BuoyAnalysisData.axis.fahrenheit);
.call(BuoyAnalysisChart.axis.imperial);
chart.append("g")
.classed('axis', true)
.classed('axis-celsius', true)
.classed('axis-metric', true)
.attr('transform', 'translate(871, 0)')
.call(BuoyAnalysisData.axis.celsius);
.call(BuoyAnalysisChart.axis.metric);
chart.append('text')
.classed('label-axis-y', true)
.attr('text-anchor', 'middle')
.text('F')
.attr('x', 10)
.text(BuoyAnalysisChart.bars.imperialLabel)
.attr('x', 12)
.attr('y', 15)
chart.append('text')
.classed('label-axis-y', true)
.attr('text-anchor', 'middle')
.text('C')
.text(BuoyAnalysisChart.bars.metricLabel)
.attr('x', 885)
.attr('y', 15)
},
/**
*
*/
updateAxes: function() {
switch(BuoyAnalysisChart.bars.property) {
case 'ATMP':
BuoyAnalysisChart.bars.tickValues = [8, 12, 16, 20, 24];
BuoyAnalysisChart.bars.imperialLabel = 'F';
BuoyAnalysisChart.bars.metricLabel = 'C';
BuoyAnalysisChart.bars.smallHexValue = '#40596F';
BuoyAnalysisChart.bars.largeHexValue = '#6cf7ce';
break;
case 'WTMP':
BuoyAnalysisChart.bars.tickValues = [10, 13, 15.5, 18.5, 21];
BuoyAnalysisChart.bars.imperialLabel = 'F';
BuoyAnalysisChart.bars.metricLabel = 'C';
BuoyAnalysisChart.bars.smallHexValue = '#40596F';
BuoyAnalysisChart.bars.largeHexValue = '#6cf7ce';
break;
case 'WVHT':
BuoyAnalysisChart.bars.tickValues = [0, 1, 2, 3, 4];
BuoyAnalysisChart.bars.imperialLabel = 'FT';
BuoyAnalysisChart.bars.metricLabel = 'M';
BuoyAnalysisChart.bars.smallHexValue = '#f00';
BuoyAnalysisChart.bars.largeHexValue = '#C8EBF4';
// BuoyAnalysisChart.bars.largeHexValue = '#ff0';
break;
case 'WPER':
BuoyAnalysisChart.bars.tickValues = [5, 7, 9, 11, 13, 15];
BuoyAnalysisChart.bars.imperialLabel = 'SEC';
BuoyAnalysisChart.bars.metricLabel = 'SEC';
BuoyAnalysisChart.bars.smallHexValue = '#20a';
BuoyAnalysisChart.bars.largeHexValue = '#a02';
break;
case 'WSPD':
BuoyAnalysisChart.bars.tickValues = [3, 6, 9, 12];
BuoyAnalysisChart.bars.imperialLabel = 'FT/S';
BuoyAnalysisChart.bars.metricLabel = 'M/S';
BuoyAnalysisChart.bars.smallHexValue = '#f00';
BuoyAnalysisChart.bars.largeHexValue = '#0f0';
break;
};
},
/**
*
*/
draw: function() {
var years = BuoyAnalysisData.calculateYearlyAverages(BuoyAnalysisMap.reticle.stations);
var months = BuoyAnalysisData.calculateMonthlyAverages(BuoyAnalysisMap.reticle.stations);
var chart = d3.select('#chart');
chart.selectAll('.bar-month').data(months).enter()
.append('rect')
.attr('fill', 'rgba(0, 0, 0, 0.2)')
.attr('width', 1)
.attr('height', function(d) {
return BuoyAnalysisData.axis.scaleInverted(d.average)
})
.attr('x', BuoyAnalysisChart.barMonthX)
.attr('y', function(d) {
return BuoyAnalysisData.axis.h - BuoyAnalysisData.axis.scaleInverted(d.average);
})
BuoyAnalysisData.setAxisProperties();
BuoyAnalysisChart.appendAxes();
BuoyAnalysisChart.appendGradient();
BuoyAnalysisChart.appendYearLabels();
chart.selectAll('.bar-year').remove();
chart.selectAll('.mask-year').remove();
chart.selectAll('.bar-month').remove();
if (BuoyAnalysisChart.bars.showYears === true) {
chart.selectAll('.bar-year').data(years).enter()
.append('rect')
.classed('bar-year', true)
.attr('fill', 'url("#gradient-year")')
.attr('width', 23)
.attr('height', BuoyAnalysisChart.axis.h)
.attr('x', BuoyAnalysisChart.barYearX)
.attr('y', 0)
chart.selectAll('.mask-year').data(years).enter()
.append('rect')
.classed('.mask-year', true)
.attr('fill', '#fff')
.attr('width', 25)
.attr('height', function(d) {
return Math.max(0, BuoyAnalysisChart.axis.scale(d.average));
})
.attr('x', function(d, i) {
return BuoyAnalysisChart.barYearX(d, i) - 1;
})
.attr('y', 0)
}
if (BuoyAnalysisChart.bars.showMonths === true) {
chart.selectAll('.bar-month').data(months).enter()
.append('rect')
.classed('bar-month', true)
.attr('fill', 'rgba(0, 0, 0, 0.2)')
.attr('width', 1)
.attr('height', function(d) {
return Math.max(0, BuoyAnalysisChart.axis.scaleInverted(d.average));
})
.attr('x', BuoyAnalysisChart.barMonthX)
.attr('y', function(d) {
return BuoyAnalysisChart.axis.h - BuoyAnalysisChart.axis.scaleInverted(d.average);
})
}
}
};

@ -12,16 +12,6 @@ var BuoyAnalysisData = {
end: 2015
},
axis: {
h: 200,
min: 100,
max: 0,
scale: null,
scaleInverted: null,
fahrenheit: null,
celsius: null
},
/**
*
*/
@ -49,51 +39,74 @@ var BuoyAnalysisData = {
/**
*
*/
setAxisProperties: function() {
setAxisProperties: function(property, tickValues) {
var json = BuoyAnalysisData.stationJson;
var property = BuoyAnalysisChart.bars.property;
var tickValues = BuoyAnalysisChart.bars.tickValues;
for (var id in json) {
for (var prop in json[id]) {
if (prop === 'id' || prop === 'lat' || prop === 'lon' || prop === 'name') {
continue;
}
BuoyAnalysisChart.axis.min = 100;
BuoyAnalysisChart.axis.max = 0;
for (var id in json) {
for (var year = BuoyAnalysisData.years.start; year <= BuoyAnalysisData.years.end; year++) {
for (var i = 0; i < 12; i++) {
if (json[id][prop]['m'][i] <= 0) {
if (json[id][property + year]['m'][i] <= 0) {
continue;
}
if (json[id][prop]['m'][i] < BuoyAnalysisData.axis.min) {
BuoyAnalysisData.axis.min = json[id][prop]['m'][i];
if (json[id][property + year]['m'][i] < BuoyAnalysisChart.axis.min) {
BuoyAnalysisChart.axis.min = json[id][property + year]['m'][i];
}
if (json[id][prop]['m'][i] > BuoyAnalysisData.axis.max) {
BuoyAnalysisData.axis.max = json[id][prop]['m'][i];
if (json[id][property + year]['m'][i] > BuoyAnalysisChart.axis.max) {
BuoyAnalysisChart.axis.max = json[id][property + year]['m'][i];
}
}
}
}
// console.warn("MIN: " + BuoyAnalysisData.axis.min + ', MAX: ' + BuoyAnalysisData.axis.max)
// console.log(BuoyAnalysisChart.bars.property)
// console.log(BuoyAnalysisChart.axis.min)
// console.warn(BuoyAnalysisChart.axis.max)
BuoyAnalysisData.axis.scale = d3.scale.linear()
.domain([BuoyAnalysisData.axis.min, BuoyAnalysisData.axis.max])
.range([BuoyAnalysisData.axis.h, 0]);
BuoyAnalysisChart.axis.scale = d3.scale.linear()
.domain([BuoyAnalysisChart.axis.min, BuoyAnalysisChart.axis.max])
.range([BuoyAnalysisChart.axis.h, 0]);
BuoyAnalysisData.axis.scaleInverted = d3.scale.linear()
.domain([BuoyAnalysisData.axis.min, BuoyAnalysisData.axis.max])
.range([0, BuoyAnalysisData.axis.h]);
BuoyAnalysisChart.axis.scaleInverted = d3.scale.linear()
.domain([BuoyAnalysisChart.axis.min, BuoyAnalysisChart.axis.max])
.range([0, BuoyAnalysisChart.axis.h]);
BuoyAnalysisData.axis.fahrenheit = d3.svg.axis()
.scale(BuoyAnalysisData.axis.scale)
BuoyAnalysisChart.axis.imperial = d3.svg.axis()
.scale(BuoyAnalysisChart.axis.scale)
.orient("left")
.tickFormat(function(d) { return Math.round(d * 9 / 5 + 32); })
.tickValues([10, 13, 15.5, 18.5, 21]);
BuoyAnalysisData.axis.celsius = d3.svg.axis()
.scale(BuoyAnalysisData.axis.scale)
.tickFormat(function(d) {
var val;
switch(BuoyAnalysisChart.bars.property) {
case 'ATMP':
case 'WTMP':
val = Math.round(d * 9 / 5 + 32);
break;
case 'WVHT':
case 'WSPD':
val = Math.round(d * 3.28 * 10) / 10;
break;
case 'WPER':
val = d;
break;
};
return val;
})
.tickValues(tickValues);
BuoyAnalysisChart.axis.metric = d3.svg.axis()
.scale(BuoyAnalysisChart.axis.scale)
.orient("right")
.tickValues([10, 13, 15.5, 18.5, 21]);
.tickValues(tickValues);
},
/**
@ -108,7 +121,7 @@ var BuoyAnalysisData = {
count = 0;
stations.forEach(function(id) {
data = BuoyAnalysisData.stationJson[id]['avgs' + year];
data = BuoyAnalysisData.stationJson[id][BuoyAnalysisChart.bars.property + year];
if (data === undefined || data.y === 0) {
return;
@ -137,7 +150,7 @@ var BuoyAnalysisData = {
count = 0;
stations.forEach(function(id) {
data = BuoyAnalysisData.stationJson[id]['avgs' + year];
data = BuoyAnalysisData.stationJson[id][BuoyAnalysisChart.bars.property + year];
if (data === undefined || data.m[month] === 0) {
return;

@ -7,7 +7,6 @@
Promise.resolve()
.then(BuoyAnalysisData.populateMapData)
.then(BuoyAnalysisData.populateSrcFile)
.then(BuoyAnalysisData.setAxisProperties)
.then(BuoyAnalysisMap.drawMap)
.then(BuoyAnalysisMap.drawStations)
@ -16,5 +15,6 @@
.then(BuoyAnalysisBehaviors.attachBehaviors)
.then(BuoyAnalysisChart.updateAxes)
.then(BuoyAnalysisChart.draw)
})();

@ -0,0 +1,159 @@
* {
box-sizing: border-box;
cursor: default;
font-family: 'open sans';
letter-spacing: 0.7px;
margin: 0;
padding: 0; }
.main {
height: 900px;
margin: 50px auto;
position: relative;
width: 900px; }
#chart {
border: solid #e8e8e8;
border-width: 0 1px;
cursor: pointer;
height: 200px;
left: 0;
position: absolute;
top: 600px;
width: 100%; }
#year-labels {
border: solid #e8e8e8;
border-width: 0 1px 1px 1px;
font-size: 0;
height: 30px;
padding-left: 24px;
position: absolute;
top: 800px;
width: 100%; }
#year-labels .label {
color: #bbb;
cursor: pointer;
display: inline-block;
line-height: 20px;
font-size: 9px;
margin-right: 2px;
text-align: center;
width: 23px; }
.year-toggle:hover {
background: #eee; }
.axis .domain {
fill: none;
stroke: none; }
.axis .tick {
fill: #888;
font-size: 8px; }
.label-axis-y {
fill: #333;
font-size: 10px;
letter-spacing: normal; }
#map {
background: #e8fbfe;
border: 1px solid #e8e8e8;
height: 600px;
position: relative;
width: 100%;
z-index: 0; }
.feature {
fill: #dffbb8;
stroke: #bde484; }
.reticle {
fill: rgba(153, 173, 40, 0.2);
stroke: #5D5336; }
.column-display {
cursor: pointer;
height: 210px;
left: 20px;
overflow: hidden;
position: absolute;
top: 270px;
width: 180px; }
.column-display select {
background: 0;
border: 0;
outline: 0;
width: 200px; }
.column-display .toggle {
background: 0;
color: #ccc;
cursor: pointer;
font-size: 10px;
height: 30px;
letter-spacing: 1.5px;
line-height: 30px;
text-transform: uppercase;
transition: color 0.3s ease; }
.column-display .toggle:hover {
color: #777; }
.column-display .toggle.selected {
color: #444;
cursor: default;
font-weight: bold; }
.reticle-sizer {
left: 20px;
position: absolute;
top: 520px;
z-index: 1; }
.bar-display {
left: 25px;
position: absolute;
top: 560px; }
.bar-display .toggle {
background-image: url("../bar-display.png");
background-repeat: no-repeat;
cursor: pointer;
display: inline-block;
font-size: 0;
height: 40px;
margin-right: 15px;
opacity: 0.15;
transition: opacity 0.3s ease;
width: 30px; }
.bar-display .toggle:hover {
opacity: 1; }
.bar-display .toggle.selected {
cursor: default;
opacity: 1; }
.bar-display .toggle1 {
background-position: -60px 10px; }
.bar-display .toggle2 {
background-position: -30px 10px; }
.bar-display .toggle3 {
background-position: 0 10px; }
input[type=range] {
-webkit-appearance: none; }
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 2px;
background: #ddd;
border: none;
border-radius: 3px; }
input[type=range]::-webkit-slider-thumb {
background: #d8ebd3;
border: 2px solid #5D5336;
border-radius: 50%;
height: 16px;
margin-top: -7px;
width: 16px;
-webkit-appearance: none; }
input[type=range]:focus {
outline: none; }

@ -3,128 +3,7 @@
<head>
<meta charset="UTF-8">
<title></title>
<link href='https://fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'>
<style>
* {
box-sizing:border-box;
font-family:'open sans';
letter-spacing:0.7px;
margin: 0;
padding: 0;
}
.main {
height:900px;
margin:50px auto;
position:relative;
width:900px;
}
#map {
background:#e8fbfe;
border:1px solid #e8e8e8;
height:600px;
position:relative;
width:100%;
z-index:0;
}
#chart {
border:solid #e8e8e8;
border-width:0 1px;
cursor:pointer;
height:200px;
left:0;
position:absolute;
top:600px;
width:100%;
}
#year-toggles {
border:solid #e8e8e8;
border-width:0 1px 1px 1px;
font-size:0;
height:30px;
padding-left:24px;
position:absolute;
top:800px;
width:100%;
}
.year-toggle {
border:1px solid #e8e8e8;
color:#bbb;
cursor:pointer;
display:inline-block;
line-height:20px;
font-size:9px;
margin-right:2px;
text-align:center;
width:23px;
}
.year-toggle:hover {
background:#eee;
}
.feature {
fill:#dffbb8;
stroke:#bde484;
}
.reticle {
fill: rgba(153, 173, 40, 0.2);
stroke: #5D5336;
}
.reticle-sizer {
left:10px;
position:absolute;
top:10px;
z-index:1;
}
.axis .domain {
fill: none;
stroke: none;
}
.axis .tick {
fill:#888;
font-size:8px;
}
.label-axis-y {
font-size:10px;
}
input[type=range]{
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 2px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
background: #d8ebd3;
border: 2px solid #5D5336;
border-radius: 50%;
height: 16px;
margin-top: -7px;
width: 16px;
-webkit-appearance: none;
}
input[type=range]:focus {
outline: none;
}
</style>
<link href='css/index.css' rel='stylesheet' type='text/css'>
</head>
<body>
@ -133,25 +12,32 @@
<input type="range" title='Reticle Size' class='reticle-sizer'>
<!-- <div class="container-center">
<span class="label left">o</span>
<div class="bar-display">
<div class="toggle toggle1 selected"></div>
<div class="toggle toggle2"></div>
<div class="toggle toggle3"></div>
</div>
<span class="label right">O</span>
<div class="column-display">
<div class="toggle toggle1">Air Temperature</div>
<div class="toggle toggle2 selected">Water Temperature</div>
<div class="toggle toggle3">Wave Height</div>
<div class="toggle toggle4">Wave Period</div>
<div class="toggle toggle5">Wind Speed</div>
</div>
<span class="label left">Slow</span>
<input type="range" title='Animation Speed'>
<span class="label fast">Fast</span>
<hr>
<svg id="chart"></svg>
<div id="year-labels"></div>
</div>
<div class="title">Station Data</div>
- MAP ocean bottom
- MAP land topography
- MAP mexico and surrounding states
- MAP major major cities
<div class="station-info"></div>
</div> -->
- UI reticle sizing
- UI reticle drag
<svg id="chart"></svg>
<div id="year-toggles"></div>
</div>
<!-- <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> -->
<script src="d3.min.js"></script>

@ -0,0 +1,24 @@
{
"name": "buoy-analysis",
"version": "1.0.0",
"description": "",
"main": "server.js",
"dependencies": {
"chalk": "^1.1.1",
"dateformat": "^1.0.12",
"es6-promise": "^3.0.2",
"node-sass": "^3.4.2",
"watch": "^0.17.1",
"xml2js": "^0.4.15"
},
"devDependencies": {},
"scripts": {
"watch": "node tasks/watch"
},
"repository": {
"type": "git",
"url": "http://gogs.benburlingham.com/ben.burlingham/buoy-analysis"
},
"author": "",
"license": "ISC"
}

Binary file not shown.

@ -0,0 +1,3 @@
NPM scripts task runner:
`npm run watch`

@ -0,0 +1,52 @@
#chart {
border:solid #e8e8e8;
border-width:0 1px;
cursor:pointer;
height:200px;
left:0;
position:absolute;
top:600px;
width:100%;
}
#year-labels {
border:solid #e8e8e8;
border-width:0 1px 1px 1px;
font-size:0;
height:30px;
padding-left:24px;
position:absolute;
top:800px;
width:100%;
.label {
color:#bbb;
cursor:pointer;
display:inline-block;
line-height:20px;
font-size:9px;
margin-right:2px;
text-align:center;
width:23px;
}
}
.year-toggle:hover {
background:#eee;
}
.axis .domain {
fill: none;
stroke: none;
}
.axis .tick {
fill:#888;
font-size:8px;
}
.label-axis-y {
fill: #333;
font-size:10px;
letter-spacing:normal;
}

@ -0,0 +1,22 @@
$mainH: 900px;
$mainW: 900px;
* {
box-sizing:border-box;
cursor:default;
font-family:'open sans';
letter-spacing:0.7px;
margin: 0;
padding: 0;
}
.main {
height:$mainH;
margin:50px auto;
position:relative;
width:$mainW;
}
@import 'chart';
@import 'map';
@import 'options';

@ -0,0 +1,18 @@
#map {
background:#e8fbfe;
border:1px solid #e8e8e8;
height:600px;
position:relative;
width:100%;
z-index:0;
}
.feature {
fill:#dffbb8;
stroke:#bde484;
}
.reticle {
fill: rgba(153, 173, 40, 0.2);
stroke: #5D5336;
}

@ -0,0 +1,116 @@
.column-display {
cursor:pointer;
height:210px;
left:20px;
overflow:hidden;
position:absolute;
top:270px;
width:180px;
select {
background:0;
border:0;
outline:0;
width:200px;
}
.toggle {
background:0;
color:#ccc;
cursor:pointer;
font-size:10px;
height:30px;
letter-spacing:1.5px;
line-height:30px;
text-transform:uppercase;
transition:color 0.3s ease;
&:hover {
color:#777;
}
&.selected {
color:#444;
cursor:default;
font-weight:bold;
}
}
}
.reticle-sizer {
left:20px;
position:absolute;
top:520px;
z-index:1;
}
.bar-display {
$toggleW: 30px;
$toggleH: 40px;
$toggleSpacing: 15px;
left:25px;
position:absolute;
top:560px;
.toggle {
background-image:url('../bar-display.png');
background-repeat:no-repeat;
cursor:pointer;
display:inline-block;
font-size:0;
height:$toggleH;
margin-right:$toggleSpacing;
opacity:0.15;
transition:opacity 0.3s ease;
width:$toggleW;
&:hover {
opacity:1;
}
&.selected {
cursor:default;
opacity:1;
}
}
.toggle1 {
background-position:-60px 10px;
}
.toggle2 {
background-position:-30px 10px;
}
.toggle3 {
background-position:0 10px;
}
}
input[type=range]{
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 2px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
background: #d8ebd3;
border: 2px solid #5D5336;
border-radius: 50%;
height: 16px;
margin-top: -7px;
width: 16px;
-webkit-appearance: none;
}
input[type=range]:focus {
outline: none;
}

@ -29,11 +29,6 @@ var chalk = require('chalk');
module.exports = {
// Zero indexed column.
// #YY MM DD hh mm WDIR WSPD GST WVHT DPD APD MWD PRES ATMP WTMP DEWP VIS TIDE
// 14 - WTMP (C)
columnToAverage: 14,
/**
*
*/
@ -66,7 +61,7 @@ module.exports = {
arr.forEach(function(row) {
val = parseFloat(row[col]);
if (val === 999 || val === 0) {
if (val === 999 || val === 0 || val === 99) {
return;
}
@ -108,7 +103,7 @@ module.exports = {
count = 0;
values.map(function(value) {
if (value === 999 || value === 0) {
if (value === 999 || value === 0 || value === 99) {
return;
}
@ -125,84 +120,15 @@ module.exports = {
/**
*
*/
getDailyAverages: function(arr, col) {
console.log('Daily averages for column ' + col + '.');
if (arr.length === undefined) {
return [];
}
var sum, count, a, b, doy;
var days = [];
var averages = [];
var dayms = 1000 * 60 * 60 * 24;
for (var i = 0; i <= 365; i++) {
days[i] = [];
}
// Assemble all the values for each day of the year.
arr.forEach(function(row) {
a = new Date(row[0], row[1] - 1, row[2]);
b = new Date(row[0], 0, 1);
doy = Math.ceil((a - b) / dayms);
// if (days[doy] === undefined) {
// // problem here - there are still YYMMDD rows in data
// console.log(row);
// }
days[doy].push(row[col]);
});
// Get the average for each collection of values in each day of the year.
days.forEach(function(values, index) {
sum = 0;
count = 0;
values.map(function(val) {
sum += parseInt(val);
count++;
});
averages[index] = Math.round((sum / count) * 10) / 10 || 0;
});
return averages;
},
/**
*
*/
getAllDailyAverages: function(station, startYear, endYear) {
var result = [];
for (var year = startYear; year <= endYear; year++) {
result.push(
IO.read(meteo.dirs.json + station + '-' + year + '.json')
.then(module.exports.parse)
.then(function(arr) {
return module.exports.getDailyAverages(arr, module.exports.columnToAverage);
})
);
}
return Promise.all(result);
},
/**
*
*/
getAllMonthlyAverages: function(station, startYear, endYear) {
getAllMonthlyAverages: function(station, col) {
var result = [];
for (var year = startYear; year <= endYear; year++) {
for (var year = meteo.years.start; year <= meteo.years.end; year++) {
result.push(
IO.read(meteo.dirs.json + station + '-' + year + '.json')
.then(module.exports.parse)
.then(function(arr) {
return module.exports.getMonthlyAverages(arr, module.exports.columnToAverage);
return module.exports.getMonthlyAverages(arr, col);
})
);
}
@ -213,15 +139,15 @@ module.exports = {
/**
*
*/
getAllYearlyAverages: function(station, startYear, endYear) {
getAllYearlyAverages: function(station, col) {
var result = [];
for (var year = startYear; year <= endYear; year++) {
for (var year = meteo.years.start; year <= meteo.years.end; year++) {
result.push(
IO.read(meteo.dirs.json + station + '-' + year + '.json')
.then(module.exports.parse)
.then(function(arr) {
return module.exports.getYearlyAverages(arr, module.exports.columnToAverage, station === '46232');
return module.exports.getYearlyAverages(arr, col);
})
);
}
@ -243,14 +169,11 @@ module.exports = {
*/
buildFinalJson: function() {
var finalResult = {};
var startYear = 1982;
var endYear = 2015;
function next(index) {
if (index === stations.ids.length) {
// if (index === 1) {
// IO.write('final-output.json', JSON.stringify(finalResult, null, 4));
// IO.write('_stations.json', JSON.stringify(finalResult, null, 4));
IO.write('_stations.json', JSON.stringify(finalResult));
return;
}
@ -259,8 +182,12 @@ module.exports = {
// Init objects.
finalResult['s' + station] = {};
for (var year = startYear; year <= endYear; year++) {
finalResult['s' + station]['avgs' + year] = {};
for (var year = meteo.years.start; year <= meteo.years.end; year++) {
finalResult['s' + station]['WSPD' + year] = {}; // 6
finalResult['s' + station]['WVHT' + year] = {}; // 8
finalResult['s' + station]['WPER' + year] = {}; // 9
finalResult['s' + station]['ATMP' + year] = {}; // 13
finalResult['s' + station]['WTMP' + year] = {}; // 14
}
Promise.resolve()
@ -274,28 +201,83 @@ module.exports = {
finalResult['s' + station].lon = json.lon;
})
// Daily
// .then(module.exports.getAllDailyAverages.bind(null, station, startYear, endYear))
// .then(function(arr) {
// arr.forEach(function(averages, index) {
// finalResult['s' + station]['avgs' + (startYear + index)].d = averages;
// });
// })
// Monthly wind speed
.then(module.exports.getAllMonthlyAverages.bind(null, station, 6))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['WSPD' + (meteo.years.start + index)].m = averages;
});
})
// Yearly wind speed
.then(module.exports.getAllYearlyAverages.bind(null, station, 6))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['WSPD' + (meteo.years.start + index)].y = averages;
});
})
// Monthly wave height
.then(module.exports.getAllMonthlyAverages.bind(null, station, 8))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['WVHT' + (meteo.years.start + index)].m = averages;
});
})
// Yearly wave height
.then(module.exports.getAllYearlyAverages.bind(null, station, 8))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['WVHT' + (meteo.years.start + index)].y = averages;
});
})
// Monthly wave period
.then(module.exports.getAllMonthlyAverages.bind(null, station, 9))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['WPER' + (meteo.years.start + index)].m = averages;
});
})
// Yearly wave period
.then(module.exports.getAllYearlyAverages.bind(null, station, 9))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['WPER' + (meteo.years.start + index)].y = averages;
});
})
// Monthly air temp
.then(module.exports.getAllMonthlyAverages.bind(null, station, 13))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['ATMP' + (meteo.years.start + index)].m = averages;
});
})
// Yearly air temp
.then(module.exports.getAllYearlyAverages.bind(null, station, 13))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['ATMP' + (meteo.years.start + index)].y = averages;
});
})
// Monthly
.then(module.exports.getAllMonthlyAverages.bind(null, station, startYear, endYear))
// Monthly water temp
.then(module.exports.getAllMonthlyAverages.bind(null, station, 14))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['avgs' + (startYear + index)].m = averages;
finalResult['s' + station]['WTMP' + (meteo.years.start + index)].m = averages;
});
})
// Yearly
.then(module.exports.getAllYearlyAverages.bind(null, station, startYear, endYear))
// Yearly water temp
.then(module.exports.getAllYearlyAverages.bind(null, station, 14))
.then(function(arr) {
arr.forEach(function(averages, index) {
finalResult['s' + station]['avgs' + (startYear + index)].y = averages;
finalResult['s' + station]['WTMP' + (meteo.years.start + index)].y = averages;
});
})

@ -15,6 +15,11 @@ module.exports = {
months: [null, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
years: {
start: 1982,
end: 2015
},
//==========================
// Downloads
//==========================

@ -0,0 +1,21 @@
var sass = require('node-sass');
var fs = require('fs');
var chalk = require('chalk');
var dateFormat = require('dateformat');
function thenWrite(err, result) {
if (err) {
console.log(err);
return;
}
var d = new Date();
fs.writeFile('css/index.css', result.css, 'utf8');
console.log(dateFormat(new Date(), "dddd mmm d H:MM:ss") + ' ' + chalk.green('Rendered css/index.css'))
}
module.exports = {
render: function() {
sass.render({ file: 'sass/index.scss' }, thenWrite);
}
}

@ -0,0 +1,11 @@
var watch = require('watch');
var sass = require('./sass');
watch.watchTree('sass', function (f, curr, prev) {
if (typeof f == "object" && prev === null && curr === null) {
// Finished walking the tree
return;
}
sass.render();
});
Loading…
Cancel
Save