Line Chart showing tidal prediction for San Francisco near Crissy Field.
Data from NOAA CO-OPS API
Built with blockbuilder.org
license: mit |
Line Chart showing tidal prediction for San Francisco near Crissy Field.
Data from NOAA CO-OPS API
Built with blockbuilder.org
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { | |
margin: 20px; | |
font-family: sans-serif; | |
} | |
text { | |
font-size: 11px; | |
} | |
</style> | |
</head> | |
<body> | |
<h3></h3> | |
<script> | |
var margin = { top: 20, right: 20, bottom: 50, left: 50 }; | |
var width = 600 - margin.left - margin.right; | |
var height = 310 - 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 + ')'); | |
var xScale = d3.scaleTime().range([0, width]); | |
var yScale = d3.scaleLinear().range([height, 0]); | |
var valueLine = d3.line() | |
.curve(d3.curveBasis) | |
.x(function(d) { return xScale(d.t); }) | |
.y(function(d) { return yScale(d.v); }); | |
var baseURL = 'https://tidesandcurrents.noaa.gov/api/datagetter'; | |
var params = { | |
begin_date: '20170703', | |
end_date: '20170704', | |
interval: 'h', | |
station: 9414290, | |
product: 'predictions', | |
datum: 'MSL', | |
units: 'english', | |
time_zone: 'lst', | |
application:'d3-tidal-chart', | |
format: 'json' | |
}; | |
var queryString = Object.keys(params) | |
.reduce(function (str, key, idx, array) { | |
str += key + '=' + params[key]; | |
if (idx !== array.length - 1) { | |
str += '&' | |
} | |
return str; | |
},''); | |
var queryURL = baseURL + '?' + queryString; | |
var parseTime = d3.timeParse('%Y-%m-%d %H:%M'); | |
var formatTime = d3.timeFormat('%B %d, %Y'); | |
d3.json(queryURL, function(error, data) { | |
if (error) throw error; | |
var parsedData = data.predictions.map(function(d) { | |
return { | |
t: parseTime(d.t), | |
v: +d.v, | |
}; | |
}); | |
xScale.domain(d3.extent(parsedData, function(d) { return d.t; })); | |
yScale.domain(d3.extent(parsedData, function(d) { return d.v; })); | |
var title = d3.select('h3') | |
.attr('class', 'tide-chart-title') | |
.text('NOAA Tidal Predictions for ' + formatTime(parsedData[0].t) + | |
' - ' + formatTime(parsedData[parsedData.length - 1].t)); | |
svg.append('path') | |
.datum(parsedData) | |
.attr('class', 'line') | |
.attr("fill", "none") | |
.attr("stroke", "steelblue") | |
.attr("stroke-linejoin", "round") | |
.attr("stroke-linecap", "round") | |
.attr("stroke-width", 1.5) | |
.attr('d', valueLine); | |
svg.append('g') | |
.attr('transform', 'translate(0,' + height + ')') | |
.call(d3.axisBottom(xScale)); | |
svg.append('g') | |
.call(d3.axisLeft(yScale)); | |
svg.append('text') | |
.attr('text-anchor', 'middle') | |
.attr('transform', 'translate(' + (-margin.left + 12) + ',' + (height / 2) + ') rotate(-90)') | |
.text('Difference in feet from MSL'); | |
svg.append('text') | |
.attr('text-anchor', 'middle') | |
.attr('transform', 'translate(' + (width / 2) + ',' + (height + (margin.bottom - 10)) + ')') | |
.text('Time of Day'); | |
}); | |
</script> | |
</body> |