Skip to content

Instantly share code, notes, and snippets.

@gcch
Last active February 9, 2018 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcch/46c99cacc5f161a72acdd0d322583635 to your computer and use it in GitHub Desktop.
Save gcch/46c99cacc5f161a72acdd0d322583635 to your computer and use it in GitHub Desktop.
/**
*
* monitor.js --- Show the graph about room status (temp. / hum. / pres.) acquired from json data
*
* Copyright (c) 2018 tag.
*
*/
var express = require('express');
var router = express.Router();
/**************************************************/
var jsdom = require('jsdom');
var d3 = require('d3');
function generateSvg() {
const { JSDOM } = jsdom;
const { document } = (new JSDOM(``)).window;
global.document = document;
const datafile = '/home/pi/bme280.json'
// Load data
var fs = require('fs');
var file = fs.readFileSync(datafile, {encoding:'utf8'}, function(err, data){
if (err) {
throw err;
}
});
var dataset = JSON.parse(file);
//console.log(dataset);
var parseDate = d3.timeParse('%Y-%m-%dT%H:%M:%S');
// Generate SVG area
var margin = {
top: 64,
right: 128,
bottom: 64,
left: 128
};
var size = {
width: 1200,
height: 800
}
var datetimeOldest = dataset[0]['datetime'];
var datetimeLatest = dataset[dataset.length - 1]['datetime'];
var svg = d3.select('body')
.append('svg')
.attr('width', margin.left + size.width + margin.right)
.attr('height', margin.top + size.height + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
// Scale
var xScale = d3.scaleTime()
.domain( [new Date(datetimeOldest), new Date(datetimeLatest)] )
.range([0, size.width]);
var yScale1 = d3.scaleLinear()
.domain([45, -5])
.range([0, size.height]);
var yScale2 = d3.scaleLinear()
.domain([100, 0])
.range([0, size.height]);
var yScale3 = d3.scaleLinear()
.domain([1100, 900])
.range([0, size.height]);
// Title
var title = svg.append('text')
.text('Temp. / Hum. / Pres. (Last Update: ' + datetimeLatest + ')')
.attr('transform', 'translate(0, ' + -margin.top / 4 + ')');
// X axis
var xAxis = svg.append('g')
.attr('class', 'axis x')
.attr('transform', 'translate(0, ' + size.height + ')')
.call(
d3.axisBottom(xScale)
.tickFormat( d3.timeFormat('%Y-%m-%d %H:%M:%S') )
.tickSize(-size.height)
)
.append('text')
.text('datetime')
.attr('stroke', '#000')
.attr('x', size.width / 2)
.attr('y', margin.bottom * 7 / 8);
svg.select('.x')
.selectAll('.tick')
.selectAll('text')
.style('text-anchor', 'end')
.attr('transform', 'rotate(-15)');
// Y axis
var yAxis1 = svg.append('g')
.attr('class', 'axis y1')
.call(
d3.axisLeft(yScale1)
.ticks(50)
.tickSize(-size.width)
)
.append('text')
.text('temperature [℃]')
.attr('text-anchor', 'start')
.attr('stroke', '#F00')
.attr('transform', 'translate(' + -margin.left / 4 + ', ' + size.height / 2 + ')rotate(90)');
var yAxis2 = svg.append('g')
.attr('class', 'axis y2')
.attr('transform', 'translate(' + size.width + ', 0)')
.call(
d3.axisRight(yScale2)
.ticks(10)
.tickSize(-size.width)
)
.append('text')
.text('humidity [%]')
.attr('stroke', '#0F0')
.attr('transform', 'translate(' + margin.right / 4 + ', ' + size.height / 2 + ')rotate(90)');
var yAxis3 = svg.append('g')
.attr('class', 'axis y3')
.attr('transform', 'translate(' + size.width + ', 0)')
.call(
d3.axisRight(yScale3)
.ticks(10)
.tickSize(-size.width)
)
.append('text')
.text('pressure [hPa]')
.attr('stroke', '#00F')
.attr('transform', 'translate(' + margin.right * 7 / 8 + ', ' + size.height / 2 + ')rotate(90)');
svg.select('.y3')
.selectAll('.tick')
.selectAll('text')
.attr('transform', 'translate(' + margin.right / 2 + ', 0)');
// Grid
svg.selectAll('line')
.attr('stroke', '#ddd');
// Graph
var line1 = d3.line()
.x(function(d, i) { return xScale( new Date(d.datetime) ); })
.y(function(d, i) { return yScale1( d.temperature ); });
var line2 = d3.line()
.x(function(d, i) { return xScale( new Date(d.datetime) ); })
.y(function(d, i) { return yScale2( d.humidity ); });
var line3 = d3.line()
.x(function(d, i) { return xScale( new Date(d.datetime) ); })
.y(function(d, i) { return yScale3( d.pressure ); });
svg.append('path')
.datum(dataset)
.attr('d', line1)
.attr('fill', 'none')
.attr('stroke', '#F00')
.attr('stroke-width', 2);
svg.append('path')
.datum(dataset)
.attr('d', line2)
.attr('fill', 'none')
.attr('stroke', '#0F0')
.attr('stroke-width', 2);
svg.append('path')
.datum(dataset)
.attr('d', line3)
.attr('fill', 'none')
.attr('stroke', '#00F')
.attr('stroke-width', 2);
}
/**************************************************/
router.get('/', function(req, res, next) {
generateSvg();
res.send(d3.select('body').node().innerHTML);
});
module.exports = router;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment