From 0ddae601bd08ce0ceaa0743a098ee6b4be8d27b8 Mon Sep 17 00:00:00 2001 From: Eric Hulburd Date: Mon, 22 Feb 2016 14:31:59 -0600 Subject: [PATCH] remove cached files --- .babelrc | 3 - .gitignore | 4 - client/api/energy_data.js | 19 - client/api/houses.js | 19 - client/api/power_data.js | 20 - client/app.js | 11 - client/config/api.js | 1 - client/config/db.js | 9 - client/config/store.js | 1 - client/d3/bar/base.js | 48 --- client/d3/bar/composite.js | 135 ------- client/d3/bar/horizontal.js | 76 ---- client/d3/bar/vertical.js | 76 ---- client/d3/base.js | 75 ---- client/d3/chart.scss | 5 - client/d3/grid/calendar_grid.js | 153 -------- client/d3/line/line.js | 122 ------ client/d3/line/spline.js | 13 - client/d3/line/spline_stack.js | 108 ------ client/d3/sliders/date_range.js | 133 ------- client/dashboard/energy/energy.js | 134 ------- client/dashboard/energy/energy.rt | 39 -- client/dashboard/energy/energy.rt.js | 25 -- client/dashboard/energy/energy.scss | 0 client/dashboard/layout/layout.js | 88 ----- client/dashboard/layout/layout.rt | 60 --- client/dashboard/layout/layout.rt.js | 69 ---- client/dashboard/layout/layout.scss | 9 - client/dashboard/power/power.js | 199 ---------- client/dashboard/power/power.rt | 35 -- client/dashboard/power/power.rt.js | 24 -- client/lib/databasable.js | 70 ---- client/lib/model.js | 9 - client/models/energy_datum.js | 47 --- client/models/house.js | 261 ------------- client/models/power_datum.js | 46 --- client/style.js | 9 - client/style.scss | 16 - gulpfile.babel.js | 68 ---- package.json | 58 --- readme.md | 1 - server/app.express.js | 127 ------ server/config/controllers.js | 17 - server/config/database.js | 37 -- server/config/react_templates.js | 7 - server/config/webpack/design.js | 1 - server/config/webpack/development.js | 48 --- server/config/webpack/production.js | 58 --- server/controllers/energy_controller.js | 16 - server/controllers/houses_controller.js | 18 - server/controllers/power_controller.js | 16 - server/helpers/api_helper.js | 29 -- server/lib/tasks/react_template_compile.js | 57 --- server/lib/tasks/seed_data.js | 103 ----- server/models/energy_datum.js | 52 --- server/models/house.js | 93 ----- server/models/power_datum.js | 59 --- server/public/favicon.ico | Bin 1150 -> 0 bytes server/public/index2.html | 41 -- server/routes.js | 11 - server/views/error.jade | 6 - server/views/index.jade | 3 - server/views/layout.jade | 34 -- shared/models/house.js | 10 - shared/utils/array.js | 28 -- shared/utils/date_range.js | 68 ---- shared/utils/math.js | 38 -- spec/shared/utils/date_range.test.js | 424 --------------------- spec/support/jasmine.json | 12 - 69 files changed, 3711 deletions(-) delete mode 100644 .babelrc delete mode 100644 .gitignore delete mode 100644 client/api/energy_data.js delete mode 100644 client/api/houses.js delete mode 100644 client/api/power_data.js delete mode 100644 client/app.js delete mode 100644 client/config/api.js delete mode 100644 client/config/db.js delete mode 100644 client/config/store.js delete mode 100644 client/d3/bar/base.js delete mode 100644 client/d3/bar/composite.js delete mode 100644 client/d3/bar/horizontal.js delete mode 100644 client/d3/bar/vertical.js delete mode 100644 client/d3/base.js delete mode 100644 client/d3/chart.scss delete mode 100644 client/d3/grid/calendar_grid.js delete mode 100644 client/d3/line/line.js delete mode 100644 client/d3/line/spline.js delete mode 100644 client/d3/line/spline_stack.js delete mode 100644 client/d3/sliders/date_range.js delete mode 100644 client/dashboard/energy/energy.js delete mode 100644 client/dashboard/energy/energy.rt delete mode 100644 client/dashboard/energy/energy.rt.js delete mode 100644 client/dashboard/energy/energy.scss delete mode 100644 client/dashboard/layout/layout.js delete mode 100644 client/dashboard/layout/layout.rt delete mode 100644 client/dashboard/layout/layout.rt.js delete mode 100644 client/dashboard/layout/layout.scss delete mode 100644 client/dashboard/power/power.js delete mode 100644 client/dashboard/power/power.rt delete mode 100644 client/dashboard/power/power.rt.js delete mode 100644 client/lib/databasable.js delete mode 100644 client/lib/model.js delete mode 100644 client/models/energy_datum.js delete mode 100644 client/models/house.js delete mode 100644 client/models/power_datum.js delete mode 100644 client/style.js delete mode 100644 client/style.scss delete mode 100644 gulpfile.babel.js delete mode 100644 package.json delete mode 100644 readme.md delete mode 100644 server/app.express.js delete mode 100644 server/config/controllers.js delete mode 100644 server/config/database.js delete mode 100644 server/config/react_templates.js delete mode 100644 server/config/webpack/design.js delete mode 100644 server/config/webpack/development.js delete mode 100644 server/config/webpack/production.js delete mode 100644 server/controllers/energy_controller.js delete mode 100644 server/controllers/houses_controller.js delete mode 100644 server/controllers/power_controller.js delete mode 100644 server/helpers/api_helper.js delete mode 100644 server/lib/tasks/react_template_compile.js delete mode 100644 server/lib/tasks/seed_data.js delete mode 100644 server/models/energy_datum.js delete mode 100644 server/models/house.js delete mode 100644 server/models/power_datum.js delete mode 100644 server/public/favicon.ico delete mode 100644 server/public/index2.html delete mode 100644 server/routes.js delete mode 100644 server/views/error.jade delete mode 100644 server/views/index.jade delete mode 100644 server/views/layout.jade delete mode 100644 shared/models/house.js delete mode 100644 shared/utils/array.js delete mode 100644 shared/utils/date_range.js delete mode 100644 shared/utils/math.js delete mode 100644 spec/shared/utils/date_range.test.js delete mode 100644 spec/support/jasmine.json diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 9b7d435..0000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["es2015", "stage-0", "react"] -} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 1a1f39d..0000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules/ -server/bin/ -client/build/ -shared/data/ diff --git a/client/api/energy_data.js b/client/api/energy_data.js deleted file mode 100644 index 2c0706c..0000000 --- a/client/api/energy_data.js +++ /dev/null @@ -1,19 +0,0 @@ -import extend from 'extend'; - -const ENDPOINT = '/data/v1/energy'; - -class EnergyDataApi { - - static index(params){ - return jQuery.ajax({ - url: ENDPOINT + '?' + jQuery.param(params), - type: 'GET', - dataType: 'json' - }).then((res)=>{ - return res.data; - }); - } - -} - -export default EnergyDataApi; diff --git a/client/api/houses.js b/client/api/houses.js deleted file mode 100644 index eb165af..0000000 --- a/client/api/houses.js +++ /dev/null @@ -1,19 +0,0 @@ -import extend from 'extend'; - -const ENDPOINT = '/data/v1/houses'; - -class HousesApi { - - static index(params){ - return jQuery.ajax({ - url: ENDPOINT + '?' + jQuery.param(params), - type: 'GET', - dataType: 'json' - }).then((res)=>{ - return res.data; - }); - } - -} - -export default HousesApi; diff --git a/client/api/power_data.js b/client/api/power_data.js deleted file mode 100644 index d8df20e..0000000 --- a/client/api/power_data.js +++ /dev/null @@ -1,20 +0,0 @@ -const ENDPOINT = '/data/v1/power'; -import extend from 'extend'; - -// send all date parameters as unix timestamps; -class PowerDataApi { - - static index(params){ - return jQuery.ajax({ - url: ENDPOINT + '?' + jQuery.param(params), - type: 'GET', - dataType: 'json' - }).then((res)=>{ - return res.data; - }); - } - -} - -export default PowerDataApi; - diff --git a/client/app.js b/client/app.js deleted file mode 100644 index c938854..0000000 --- a/client/app.js +++ /dev/null @@ -1,11 +0,0 @@ -import 'babel-polyfill'; -import 'bootstrap/dist/js/bootstrap.min'; - -import React from 'react'; -import ReactDOM from 'react-dom'; -import Layout from './dashboard/layout/layout'; - -ReactDOM.render( - React.createElement(Layout), - document.getElementById('root') -); diff --git a/client/config/api.js b/client/config/api.js deleted file mode 100644 index cc0bafa..0000000 --- a/client/config/api.js +++ /dev/null @@ -1 +0,0 @@ -api.js diff --git a/client/config/db.js b/client/config/db.js deleted file mode 100644 index c974c4b..0000000 --- a/client/config/db.js +++ /dev/null @@ -1,9 +0,0 @@ -import Loki from 'lokijs'; - -var db = new Loki('spike'); - -db.addCollection('PowerData'); -db.addCollection('EnergyData'); -db.addCollection('Houses'); - -export default diff --git a/client/config/store.js b/client/config/store.js deleted file mode 100644 index b1c4591..0000000 --- a/client/config/store.js +++ /dev/null @@ -1 +0,0 @@ -store.js diff --git a/client/d3/bar/base.js b/client/d3/bar/base.js deleted file mode 100644 index 1374492..0000000 --- a/client/d3/bar/base.js +++ /dev/null @@ -1,48 +0,0 @@ -import extend from 'extend'; - -// This class is inspired by // http://bl.ocks.org/mbostock/3885304. -class BarChart { - - get chart_options(){ - return { - series_opacity_gradient: true, - margin: {top: 0, left: 70, bottom: 50, right: 20} - }; - } - - serializeData(data){ - var bar_chart = this, - serialized_data = { - max: undefined, - series: [] - }; - - data.forEach(function(data_set){ - var series = extend({ - css_class: bar_chart.toClass ? bar_chart.toClass(data_set) : "", - title: bar_chart.titleize ? bar_chart.titleize(data_set) : "" - }, data_set); - series.total = 0; - series.values = []; - data_set.values.forEach(function(datum, j){ - var series_datum = extend({ - name: datum.name, - value: datum.value, - cummulative: series.total, - css_class: bar_chart.toClass ? bar_chart.toClass(data_set, datum) : "", - title: bar_chart.titleize ? bar_chart.titleize(data_set, datum) : "", - opacity: 1.0 - 0.5 * (j / data_set.values.length) - }, datum); - series_datum.series = series; - series.total += datum.value; - series.values.push(series_datum); - }); - serialized_data.series.push(series); - serialized_data.max = serialized_data.max === undefined ? - series.total : - Math.max(serialized_data.max, Math.abs(series.total)); - }); - return serialized_data; - }; - -} diff --git a/client/d3/bar/composite.js b/client/d3/bar/composite.js deleted file mode 100644 index 3b41cb9..0000000 --- a/client/d3/bar/composite.js +++ /dev/null @@ -1,135 +0,0 @@ -import Chart from './../base'; - -class BarLineChart extends Chart { - - get chart_options(){ - return Object.assign(Chart.DEFAULTS, { - }); - } - - afterAxes(){ - var chart = this; - line_chart.fnLine = d3.svg.line() - .interpolate(line_chart.chart_options.interpolation) - .x(function(d){ return line_chart.x_scale(d[line_chart.domain_attr]); }) - .y(function(d){ return line_chart.y_scale_right(d[line_chart.line_attr]); }); - } - - defineAxes(){ - var chart = this; - - // Axes Left - chart.y_scale_left = d3.scale.linear() - .range([chart.height, 0]); - chart.y_axis_left = d3.svg.axis() - .scale(chart.y_scale_left) - .orient("left") - .outerTickSize(0); - - // Axes Right - chart.y_scale_right = d3.scale.linear() - .range([chart.height, 0]); - chart.y_axis_left = d3.svg.axis() - .scale(chart.y_scale_right) - .orient("right") - .outerTickSize(0); - - chart.x_scale = d3.scale.ordinal() - .rangeRoundBands([chart.height, 0], 0.1); - - chart.x_axis = d3.svg.axis() - .scale(chart.x_scale) - .orient("bottom") - .outerTickSize(0) - //chart.x_axis.tickFormat(d3.time.format('%b %d at %H')) - //chart.x_axis.ticks(d3.time.hour, 12); - - // append axis groups. - chart.svg.append("g") - .attr("class", "d3-chart-range d3-chart-range-left d3-chart-axis"); - chart.svg.append("g") - .attr("class", "d3-chart-range d3-chart-range-right d3-chart-axis"); - chart.svg.append("g") - .attr("class", "d3-chart-domain d3-chart-axis") - .attr("transform", "translate(0, " + (chart.height) + ")"); - } - - defineDomain(domain){ - var chart = this; - - chart.domain = domain; - chart.x_scale.domain(domain); - chart.svg.select(".d3-chart-domain") - .call(chart.x_axis); - .selectAll("text") - .attr("transform", function(){ - var elem = this, - bbox = elem.getBBox(), - middleX = bbox.x + (bbox.width / 2), - middleY = bbox.y + (bbox.height / 2); - return "rotate(-30," + middleX + "," + middleY + ")"; - }); - } - - drawBarData(data){ - var chart = this; - data = chart.serializeBarData(data); - - chart.y_scale_left.domain(data.range_extent); - chart.svg.select(".d3-chart-range").call(chart.y_axis_left); - - data.series.forEach(function(series){ - var filtered_values = series.values.filter((value){ return chart.domain.indexOf(value[chart.domain_attr]) < 0; }) - bars = chart.svg.selectAll(".d3-chart-bar") - .data(series.values); - chart.applyData(series, bars.enter().append("rect")); - chart.applyData(series, bars.transition()); - bars.exit().remove(); - }); - } - - // helper method for drawData - applyBarData(series, elements){ - var chart = this, - series_class = "d3-chart-bar " + series.css_class; - elements - .attr("class", function(d){ return series_class + " " + d.css_class; }) - .attr("title", function(d){ return d.title; }) - .attr("width", chart.x_scale.rangeBand()) - .attr("x", chart.x_scale(series.title)) - .attr("height", return chart.y_scale(d[chart.bar_attr])) - .attr("y", function(d) { return chart.y_scale(d.cummulative); }) - .attr('fill', function(d){ return chart.fnColor(d.title); }); - } - - drawLineData(data){ - var chart = this, - nested_extent = chart.nestedExtent(data.series, 'values', chart.domain_attr, chart.line_attr); - - // calibrate axes - bar_chart.y_scale_right.domain([Math.min(0, nested_extent.range_min), nested_extent.range_max]); - bar_chart.svg.select(".d3-chart-range-right") - .call(bar_chart.y_axis_right); - - // draw lines - var line = g.selectAll(".d3-chart-line") - .data(data.series); - - [line.enter().append('g'), line.transition()].forEach((groups)=>{ - line_chart.applyLineData(groups, data.series); - }); - line.exit().remove(); - } - - applyLineData(groups){ - var chart = this; - groups - .attr('class', function(series){ return "d3-chart-line " + chart.cssClass(series); }) - .attr("title", function(series){ return series.title; }) - .append("path") - .attr("d", function(series){ return chart.fnLine(series.values.filter((value)=>{ return chart.domain.indexOf(value[chart.domain_attr]) < 0; })); }) - .style("stroke", function(series){ return line_chart.fnColor(series.title); }); - - } - -} diff --git a/client/d3/bar/horizontal.js b/client/d3/bar/horizontal.js deleted file mode 100644 index 4165473..0000000 --- a/client/d3/bar/horizontal.js +++ /dev/null @@ -1,76 +0,0 @@ -import BarChart from './bar.base'; - -class HorizontalBarChart extends BarChart { - - defineAxes(){ - var bar_chart = this; - bar_chart.y_scale = d3.scale.ordinal() - .rangeRoundBands([bar_chart.height, 0], 0.1); - - bar_chart.y_axis = d3.svg.axis() - .scale(bar_chart.y_scale) - .orient("left"); - - bar_chart.x_scale = d3.scale.linear() - .range([0, bar_chart.width]); - - bar_chart.x_axis = d3.svg.axis() - .scale(bar_chart.x_scale) - .orient("bottom") - .ticks(bar_chart.range_ticks) - .outerTickSize(0); - - // append axes - bar_chart.svg.append("g") - .attr("class", "d3-chart-domain d3-chart-axis"); - bar_chart.svg.append("g") - .attr("class", "d3-chart-range d3-chart-axis") - .attr("transform", "translate(0, " + (bar_chart.height - bar_chart.margin.top) + ")"); - } - - drawData(data){ - var bar_chart = this; - data = bar_chart.serializeData(data); - - // calibrate axes - bar_chart.y_scale.domain(data.series.reverse().map(function(d) { return d.name; })); - bar_chart.svg.select(".d3-chart-domain.d3-chart-axis") - .call(bar_chart.y_axis) - .selectAll("text") - .attr("transform", function(){ - var elem = this, - bbox = elem.getBBox(), - middleX = bbox.x + (bbox.width / 2), - middleY = bbox.y + (bbox.height / 2); - return "rotate(-30,"+middleX + "," + middleY+")"; - }); - - bar_chart.x_scale.domain([0, data.max]); - bar_chart.svg.select(".d3-chart-range.d3-chart-axis").call(bar_chart.x_axis); - - data.series.forEach(function(series){ - var bars = bar_chart.svg.selectAll("d3-chart-rect.d3-chart-bar." + series.css_class) - .data(series.values); - bar_chart.applyData(series, bars.enter().append("rect")); - bar_chart.applyData(series, bars.transition()); - bars.exit().remove(); - }); - } - - // helper method for drawData. - applyData(series, elements){ - var bar_chart = this, - series_class = "d3-chart-bar " + series.css_class; - elements - .attr("class", function(d){ return series_class + " " + d.css_class; }) - .attr("title", function(d){ return d.title; }) - .attr("y", function(d) { return bar_chart.y_scale(series.name); }) - .attr("height", bar_chart.y_scale.rangeBand()) - .attr("x", function(d) { return bar_chart.x_scale(d.cummulative); }) - .attr("width", function(d) { return bar_chart.x_scale(d.value); }) - .attr("opacity", function(d) { return d.opacity; }); - } - -} - -export default HorizontalBarChart; diff --git a/client/d3/bar/vertical.js b/client/d3/bar/vertical.js deleted file mode 100644 index 81a2d5f..0000000 --- a/client/d3/bar/vertical.js +++ /dev/null @@ -1,76 +0,0 @@ -import BarChart from './bar.base'; - -class VerticalBarChart extends BarChart { - - defineAxes(){ - var bar_chart = this; - bar_chart.y_scale = d3.scale.ordinal() - .rangeRoundBands([bar_chart.height, 0], 0.1); - - bar_chart.y_axis = d3.svg.axis() - .scale(bar_chart.y_scale) - .ticks(bar_chart.range_ticks) - .orient("left") - .outerTickSize(0); - - bar_chart.x_scale = d3.scale.linear() - .range([0, bar_chart.width]); - - bar_chart.x_axis = d3.svg.axis() - .scale(bar_chart.x_scale) - .orient("bottom"); - - // append axes - bar_chart.svg.append("g") - .attr("class", "d3-chart-range d3-chart-axis"); - bar_chart.svg.append("g") - .attr("class", "d3-chart-domain d3-chart-axis") - .attr("transform", "translate(0, " + (bar_chart.height - bar_chart.margin.top) + ")"); - } - - drawData(data){ - var bar_chart = this; - data = bar_chart.serializeData(data); - - // calibrate axes - bar_chart.x_scale.domain(data.series.reverse().map((d)=>{ return d.name; })); - bar_chart.svg.select(".d3-chart-domain.d3-chart-axis") - .call(bar_chart.x_axis) - .selectAll("text") - .attr("transform", function(){ - var elem = this, - bbox = elem.getBBox(), - middleX = bbox.x + (bbox.width / 2), - middleY = bbox.y + (bbox.height / 2); - return "rotate(-30,"+middleX + "," + middleY+")"; - }); - - bar_chart.y_scale.domain([data.min, data.max]); - bar_chart.svg.select(".d3-chart-range.d3-chart-axis").call(bar_chart.y_axis); - - data.series.forEach(function(series){ - var bars = bar_chart.svg.selectAll(".d3-chart-rect.d3-chart-bar." + series.css_class) - .data(series.values); - bar_chart.applyData(series, bars.enter().append("rect")); - bar_chart.applyData(series, bars.transition()); - bars.exit().remove(); - }); - } - - // helper method for drawData - applyData(series, elements){ - var bar_chart = this, - series_class = "d3-chart-bar " + series.css_class; - elements - .attr("class", function(d){ return series_class + " " + d.css_class; }) - .attr("title", function(d){ return d.title; }) - .attr("width", function(d) { return bar_chart.x_scale.rangeBand(); }) - .attr("x", function(d) { return bar_chart.x_scale(series.name); }) - .attr("height", return bar_chart.y_scale(d.value)) - .attr("y", function(d) { return bar_chart.y_scale(d.cummulative); }) - .attr("opacity", function(d) { return d.opacity; }); - } - -} - -export default VerticalBarChart; diff --git a/client/d3/base.js b/client/d3/base.js deleted file mode 100644 index e071906..0000000 --- a/client/d3/base.js +++ /dev/null @@ -1,75 +0,0 @@ -import extend from 'extend'; - -const DEFAULTS = { - outer_width: 500, - outer_height: 300, - margin: {top: 30, left: 70, bottom: 50, right: 20}, - domain_ticks: 10, - range_ticks: 8, - container: "container", - time_series: false, - range_label: undefined, - domain_attr: undefined, - range_attr: undefined, - toCssClass: function(series){ - return series ? series.title.toLowerCase().replace(/\s+/g, '-') : ""; - } -}; - - -class Chart { - - constructor(options){ - var chart = this; - chart = extend(chart, chart.chart_options, options); - - chart.height = chart.outer_height - chart.margin.top - chart.margin.bottom; - chart.width = chart.outer_width - chart.margin.left - chart.margin.right; - - chart.svg = d3.select(chart.container).append("svg") - .attr("width", chart.outer_width) - .attr("height", chart.outer_height) - .append("g") - .attr("transform", "translate(" + chart.margin.left + "," + chart.margin.top + ")"); - chart.defineAxes(); - if (chart.afterAxes) chart.afterAxes(); - } - - cssClass(series){ - var chart = this; - if (!chart.toCssClass) return ''; - return chart.toCssClass(series); - } - - nestedExtent(a, series_values, domain_attr, range_attr){ - var extent = { - min_domain: Infinity, - max_domain: -Infinity, - min_range: Infinity, - max_range: -Infinity - }; - a.forEach((series)=>{ - series[series_values].forEach((value)=>{ - extent.min_domain = Math.min(min_domain, value[domain_attr]); - extent.max_domain = Math.max(max_domain, value[domain_attr]); - extent.min_range = Math.min(min_range, value[range_attr]); - extent.max_range = Math.max(max_range, value[range_attr]); - }); - }); - return extent; - } - - titleize(s){ - var words = s.split(' '), - array = []; - for (var i=0; i{ return n+1; })) - .rangeRoundBands([0, grid_chart.width], grid_chart.grid_padding, 0); - - grid_chart.x_axis = d3.svg.axis() - .scale(grid_chart.x_scale) - .orient("top") - .outerTickSize(0); - - // append x axis - grid_chart.svg.append("g").attr("class", "d3-chart-domain d3-chart-axis"); - } - - afterAxes(){ - var grid_chart = this; - grid_chart.grid_unit_size = grid_chart.width / 31 - grid_chart.grid_padding * grid_chart.width / 30; - - if (grid_chart.display_date_format) grid_chart.displayDate = d3.time.format(grid_chart.display_date_format); - - if (!grid_chart.toDate && grid_chart.parse_date_format){ - grid_chart.parseDate = d3.time.format(grid_chart.parse_date_format); - grid_chart.toDate = (datum)=>{ - grid_chart.parseDate(datum[grid_chart.date_attr]); - } - } else if (!grid_chart.toDate){ - grid_chart.toDate = (datum)=>{ return datum[grid_chart.date_attr] }; - } - - - grid_chart.monthFormat = d3.time.format('%B %Y'); - grid_chart.toMonthString = (datum)=>{ - return grid_chart.monthFormat(grid_chart.toDate(datum)); - } - } - - serializeData(data){ - var grid_chart = this; - data.css_class = data.css_class || grid_chart.toClass ? grid_chart.toClass(data) : ""; - - grid_chart.rangeValue = grid_chart.range_attr ? function(d){ return d[grid_chart.range_attr]; } : grid_chart.rangeValue; - - data.months = []; - if (data.min_range !== undefined && data.max_range !== undefined){ - data.range = {min: data.min_range, max: data.max_range}; - data.values.forEach((value)=>{ - var date = grid_chart.toDate(value), - date_s = grid_chart.monthFormat(date); - if (data.months.indexOf(date_s) < 0) data.months.push(date_s); - }); - } else { - var min_range = Infinity, - max_range = -Infinity; - data.values.forEach((value)=>{ - var date = grid_chart.toDate(value), - date_s = grid_chart.monthFormat(date), - range_value =grid_chart.rangeValue(value); - min_range = Math.min(min_range, range_value); - max_range = Math.max(max_range, range_value); - if (data.months.indexOf(date_s) < 0) data.months.push(date_s); - }); - if (grid_chart.min_range_zero) min_range = Math.min(min_range, 0); - data.range = { min: min_range, max: max_range }; - } - data.range.diff = data.range.max - data.range.min; - - data.months = data.months.sort((date_s1, date_s2)=>{ - var date1 = grid_chart.monthFormat.parse(date_s1), - date2 = grid_chart.monthFormat.parse(date_s2); - return date1.getTime() - date2.getTime(); - }); - return data; - }; - - drawData(data){ - var grid_chart = this; - grid_chart.i = grid_chart.i || 1; - data = grid_chart.serializeData(data); - - // calibrate axes - var y_axis_height = grid_chart.grid_unit_size * (1 + grid_chart.grid_padding) * data.months.length; - grid_chart.y_scale.rangeRoundBands([0, y_axis_height], grid_chart.grid_padding, 0); - grid_chart.y_scale.domain(data.months); - grid_chart.y_axis.scale(grid_chart.y_scale); - - grid_chart.svg.select(".d3-chart-range") - .call(grid_chart.y_axis); - - grid_chart.svg.select(".d3-chart-domain").call(grid_chart.x_axis); - - var grid_units = grid_chart.svg.selectAll(".d3-chart-grid-unit") - .data(data.values); - grid_units.exit().remove(); - grid_chart.applyData(data, grid_units.enter().append("rect")); - grid_chart.applyData(data, grid_units); - } - - // helper method for drawData. - applyData(data, elements){ - var grid_chart = this, - series_class = "d3-chart-grid-unit " + data.css_class; - elements - .attr("class", series_class) - .attr("y", function(d) { - var bottom = grid_chart.y_scale(grid_chart.toMonthString(d)), - middle = grid_chart.y_scale.rangeBand() / 2 - grid_chart.grid_unit_size / 2; - return bottom + middle; - }) - .attr("height", grid_chart.grid_unit_size) - .attr("x", function(d) { - return grid_chart.x_scale(grid_chart.toDate(d).getDate()); - }) - .attr("width", function(d) { return grid_chart.grid_unit_size; }) - .attr('fill', grid_chart.color) - .attr("opacity", function(d) { return grid_chart.calculateOpacity(75, data.range); }); - } - - calculateOpacity(value, range){ - return Math.max(0, Math.min(1, 1 - (range.max - (value - range.min)) / range.diff)); - }; - -} - -export default CalendarGridChart; diff --git a/client/d3/line/line.js b/client/d3/line/line.js deleted file mode 100644 index 146241b..0000000 --- a/client/d3/line/line.js +++ /dev/null @@ -1,122 +0,0 @@ -import extend from 'extend'; - -import Chart from './../base'; - - -// inspired by https://gist.github.com/mbostock/4b66c0d9be9a0d56484e -class LineChart extends Chart { - - get chart_options(){ - return { - interpolation: 'basis' - }; - } - - defineAxes(){ - var chart = this; - - chart.y_scale = d3.scale.linear() - .range([chart.height, 0]); - chart.y_axis = d3.svg.axis() - .scale(chart.y_scale) - .orient("left") - .outerTickSize(1); - - if (chart.time_series){ - chart.x_scale = d3.time.scale() - .range([0, chart.width]); - } else { - chart.x_scale = d3.scale.linear() - .range([0, chart.width]); - } - - chart.x_axis = d3.svg.axis() - .scale(chart.x_scale) - .orient("bottom") - .outerTickSize(0) - //chart.x_axis.tickFormat(d3.time.format('%b %d at %H')) - //chart.x_axis.ticks(d3.time.hour, 12); - - // append axes - chart.svg.append("g") - .attr("class", "d3-chart-range d3-chart-axis"); - chart.svg.append("g") - .attr("class", "d3-chart-domain d3-chart-axis") - .attr("transform", "translate(0, " + (chart.height) + ")"); - } - - afterAxes(){ - var line_chart = this; - // function that draws the lines. - line_chart.line = d3.svg.line() - .interpolate(line_chart.chart_options.interpolation) - .x(function(d){ return line_chart.x_scale(d[line_chart.domain_attr]); }) - .y(function(d){ return line_chart.y_scale(d[line_chart.range_attr]); }); - - // function that returns unique color based on series_title. - line_chart.color = d3.scale.category20(); - } - - serializeData(data){ - var line_chart = this, - serialized_data = { - series: [], - range_min: Infinity, - range_max: -Infinity, - domain_min: Infinity, - domain_max: -Infinity, - }; - - data.forEach(function(data_set){ - var series = extend({ - css_class: line_chart.toClass ? line_chart.toClass(data_set) : "", - title: line_chart.titleize ? line_chart.titleize(data_set) : "", - color: '' - }, data_set); - - series.values.forEach((value)=>{ - series_data.range_min = Math.min(series_data.range_min, value[line_chart.range_attr]); - series_data.range_max = Math.max(series_data.range_max, value[line_chart.range_attr]); - series_data.domain_min = Math.min(series_data.domain_min, value[line_chart.domain_attr]); - series_data.domain_max = Math.max(series_data.domain_max, value[line_chart.domain_attr]); - }); - serialized_data.series.push(series); - }); - return serialized_data; - }; - - drawData(data){ - var line_chart = this; - data = line_chart.serialize_data; - - // calibrate axes - bar_chart.y_scale.domain([Math.min(0, data.range_min), data.range_max]); - bar_chart.svg.select(".d3-chart-range.d3-chart-axis") - .call(bar_chart.y_axis); - - bar_chart.x_scale.domain([data.domain_max, Math.min(data.domain_min)]); - bar_chart.svg.select(".d3-chart-domain.d3-chart-axis").call(bar_chart.x_axis); - - // draw lines - var line = g.selectAll(".d3-chart-series") - .data(data.series); - - [line.enter().append('g'), line.transition()].forEach((groups)=>{ - line_chart.applyData(groups); - }); - line.exit().remove(); - } - - applyData(groups){ - var line_chart = this; - groups - .attr('class', function(series){ return "d3-chart-line " + series.css_class; }) - .attr("title", function(series){ return series.title; }) - .append("path") - .attr("d", function(series){ return line_chart.line(series.values); }) - .style("stroke", function(series){ return line_chart.color(series.title); }); - } - -} - -export default LineChart; diff --git a/client/d3/line/spline.js b/client/d3/line/spline.js deleted file mode 100644 index e4f6bab..0000000 --- a/client/d3/line/spline.js +++ /dev/null @@ -1,13 +0,0 @@ -import LineChart from './line'; - -const INTEPOLATION = 'cardinal'; - -class SplineChart extends LineChart { - - get chart_options(){ - return { - interpolation: INTEPOLATION - } - } - -} diff --git a/client/d3/line/spline_stack.js b/client/d3/line/spline_stack.js deleted file mode 100644 index 390c7c7..0000000 --- a/client/d3/line/spline_stack.js +++ /dev/null @@ -1,108 +0,0 @@ -import LineChart from './line'; - -const INTERPOLATION = 'cardinal'; - -// inspired by https://bl.ocks.org/mbostock/3885211 -class SplineStackChart extends LineChart { - - get chart_options(){ - return Object.assign(Object.assign({}, LineChart.DEFAULTS), { - interpolation: INTERPOLATION - }); - } - - afterAxes(){ - var spline_stack = this; - spline_stack.fnArea = d3.svg.area() - .x(function(d, i) { return spline_stack.x_scale(d.x); }) - .y0(function(d) { return spline_stack.y_scale(d.y0); }) - .y1(function(d) { return spline_stack.y_scale(d.y0 + d.y); }) - .interpolate(spline_stack.interpolation); - - spline_stack.fnStack = d3.layout.stack() - .values(function(d) { return d.values; }); - - // function that returns unique color based on series_title. - spline_stack.fnColor = d3.scale.category20(); - } - - serializeData(data){ - var spline_stack = this, - serialized_data = { - series: [] }; - data.series.forEach(function(series, i){ - series.css_class = series.css_class || spline_stack.toClass ? spline_stack.toClass(series) : "series-" + i; - if (spline_stack.domain_attr !== 'x' && spline_stack.range_attr !== 'y'){ - series.values = series.values.map((value)=>{ - return {x: value[spline_stack.domain_attr], y: value[spline_stack.range_attr], series: series}; - }); - } - serialized_data.series.push(series); - }); - - serialized_data.series = spline_stack.fnStack(serialized_data.series); - // assume all series have same domain, use first series to establish extent. - serialized_data.domain_extent = d3.extent(serialized_data.series[0].values.map((value)=>{ return value.x; })); - // final series will have the highest y values. - serialized_data.range_max = d3.max(serialized_data.series[serialized_data.series.length - 1].values.map((value)=>{ return value.y0 + value.y; })) - - return serialized_data; - }; - - drawData(data){ - var spline_stack = this; - data = spline_stack.serializeData(data); - - // calibrate axes. - spline_stack.y_scale.domain([0, data.range_max]); - spline_stack.svg.select(".d3-chart-range.d3-chart-axis") - .call(spline_stack.y_axis); - - spline_stack.x_scale.domain(data.domain_extent); - spline_stack.svg.select(".d3-chart-domain.d3-chart-axis").call(spline_stack.x_axis); - - var stack = spline_stack.svg.selectAll(".d3-chart-spline-stack") - .data(data.series); - [stack.enter().append("path"), stack].forEach((paths)=>{ - spline_stack.applyData(paths); - }); - stack.exit().remove(); - - if (spline_stack.include_dots){ - data.series.forEach((series)=>{ - var dots = spline_stack.svg.selectAll(".d3-chart-spline-dot." + series.css_class) - .data(series.values); - [dots.enter().append("circle"), dots].forEach((circles)=>{ - spline_stack.applyDots(series, circles); - }); - dots.exit().remove(); - }); - } - } - - applyData(paths){ - var spline_stack = this; - paths - .attr("class", function(series){ return "d3-chart-spline-stack " + series.css_class;}) - .attr("d", function(series){ return spline_stack.fnArea(series.values); }) - .style("fill", function(series){ return spline_stack.fnColor(series.title); }) - .attr('opacity', 1); - } - - applyDots(series, circles){ - var spline_stack = this; - circles - .attr('class', 'd3-chart-spline-dot ' + series.css_class) - .attr("r", 2) - .attr("cx", function(d, i){ return spline_stack.x_scale(d.x); }) - .attr("cy", function(d, i){ return spline_stack.y_scale(d.y + d.y0); }) - .attr("title", function(d, i){ return spline_stack.titleizeDatum(series, d); }) - .style("fill", spline_stack.fnColor(series.title)) - .attr('opacity', 1) - .attr('stroke-width', 0) - .attr('stroke', '#fff'); - } - -} - -export default SplineStackChart; diff --git a/client/d3/sliders/date_range.js b/client/d3/sliders/date_range.js deleted file mode 100644 index 6e38231..0000000 --- a/client/d3/sliders/date_range.js +++ /dev/null @@ -1,133 +0,0 @@ -import Chart from './../base'; - -class DateRange extends Chart { - - - get chart_options(){ - return Object.assign(Object.assign({}, Chart.DEFAULTS), { - outer_width: 600, - outer_height: 250, - margin: {top: 20, left: 10, bottom: 20, right: 10}, - }); - } - - defineAxes(){ - var date_range = this; - - date_range.x_scale = d3.time.scale() - .range([0, date_range.width]) - .clamp(true); - - date_range.x_axis = d3.svg.axis() - .scale(date_range.x_scale) - .orient("bottom") - .ticks(d3.time.weeks, 1) - //.tickFormat(function(d) { return d + "°"; }) - .tickSize(1) - .outerTickSize(1) - .tickPadding(12) - - date_range.svg.append("g") - .attr("class", "d3-chart-domain") - .attr("transform", "translate(0," + date_range.height / 2 + ")"); - } - - afterAxes(){ - var date_range = this; - - date_range.slider = date_range.svg.append("g") - .attr("class", "d3-chart-slider"); - - date_range.min_handle = date_range.slider.append("circle") - .attr("class", "d3-chart-min-handle") - .attr("transform", "translate(0," + date_range.height / 2 + ")") - .attr("r", 9); - - date_range.max_handle = date_range.slider.append("circle") - .attr("class", "d3-chart-max-handle") - .attr("transform", "translate(0," + date_range.height / 2 + ")") - .attr("r", 9); - - date_range.brush = d3.svg.brush() - .x(date_range.x_scale); - - date_range.slider - .call(date_range.brush) - //.select(".background") - // .attr("height", date_range.height); - - date_range.slider.call(date_range.brush) - .selectAll(".extent,.resize") - .remove(); - } - - drawData(data){ - var date_range = this; - date_range.x_scale.domain([data.abs_min, data.abs_max]); - - date_range.svg.select(".d3-chart-domain") - .call(date_range.x_axis); - - date_range.min_handle.attr('cx', date_range.x_scale(data.current_min)); - date_range.max_handle.attr('cx', date_range.x_scale(data.current_max)); - - date_range.brush.extent([data.current_min, data.current_min]) - .on("brush", ()=>{ - DateRange.handleBrush(date_range, eval('this')); - }); - - date_range.slider - .call(date_range.brush.event) - .transition() // gratuitous intro! - .duration(750) - .call(date_range.brush.extent([data.current_min, data.current_min])) - .call(date_range.brush.event); - - } - - static handleBrush(date_range, elem){ - var date = date_range.brush.extent()[0], - current_min = parseInt(date_range.min_handle.attr('cx')), - current_max = parseInt(date_range.max_handle.attr('cx')); - - if (!current_min && !current_max) return false - if (d3.event.sourceEvent) { // not a programmatic event - date = date_range.x_scale.invert(d3.mouse(elem)[0]); - date_range.brush.extent([date, date]); - } - - var value = date_range.x_scale(date); - - if (value < current_max && value > current_min){ - if (Math.abs(value - current_min) < Math.abs(value - current_max)){ - date_range.min_handle.attr('cx', value); - current_min = value; - } else { - date_range.max_handle.attr('cx', value); - current_max = value; - } - } else if (value >= current_max){ - date_range.max_handle.attr('cx', value); - current_max = value; - if (d3.event.sourceEvent && date_range.maxDelta){ - var new_current_min = date_range.maxDelta(date, date_range.x_scale.invert(current_min)); - if (new_current_min) date_range.min_handle.attr('cx', date_range.x_scale(new_current_min)); - } - } else { - date_range.min_handle.attr('cx', value); - current_min = value; - if (d3.event.sourceEvent && date_range.maxDelta){ - var new_current_max = date_range.maxDelta(date, date_range.x_scale.invert(current_max)); - if (new_current_max) date_range.max_handle.attr('cx', date_range.x_scale(new_current_max)); - } - } - - - if (d3.event.sourceEvent && date_range.onRangeUpdated) { - date_range.onRangeUpdated(date_range.x_scale.invert(current_min), date_range.x_scale.invert(current_max)); - } - } - -} - -export default DateRange; diff --git a/client/dashboard/energy/energy.js b/client/dashboard/energy/energy.js deleted file mode 100644 index 6d9de98..0000000 --- a/client/dashboard/energy/energy.js +++ /dev/null @@ -1,134 +0,0 @@ -import React from 'react'; -import energyRt from './energy.rt.js'; -import House from './../../models/house'; -import CalendarGridChart from './../../d3/grid/calendar_grid'; - -var Energy = React.createClass({ - - getInitialState: function(){ - var energy = this; - return { - graph_attr: 'production', - loading_data: true - }; - }, - - handleResize: function(e) { - this.setState({windowWidth: window.innerWidth}); - }, - - componentDidMount: function() { - // window.addEventListener('resize', this.handleResize); - var energy = this, - house = energy.props.house; - energy.graph_title = 'Daily Consumption'; - house.setEnergyData().then(()=>{ - energy.setState({loading_data: false}); - if (energy.props.view === 'graph') energy.initGraph(); - }); - }, - - componentWillUnmount: function(){ - var energy = this; - energy.destroyGraph(); - }, - - componentWillReceiveProps: function(new_props){ - var energy = this; - if (new_props.house !== energy.props.house){ - energy.setState({loading_data: true}); - new_props.house.setEnergyData().then(()=>{ - energy.setState({loading_data: false}); - if (energy.props.view === 'graph') energy.initGraph(); - }); - } - if (new_props.view !== 'graph' && energy.props.view === 'graph') energy.destroyGraph(); - }, - - componentDidUpdate: function(prev_props, _prev_state){ - var energy = this, - house = energy.props.house; - if (prev_props.view !== 'graph' && energy.props.view === 'graph') energy.initGraph(); - if (prev_props.year !== energy.props.year){ - energy.updateCurrentMonth(); - } - }, - - setGraphAttr: function(event){ - var energy = this, - graph_attr = event.target.dataset.value; - if (graph_attr !== energy.state.graph_attr){ - energy.graph_title = 'Daily ' + event.target.innerText; - energy.setState({ - graph_attr: graph_attr - }, function(){ - if (energy.props.view === 'graph') energy.updateGraph(); - }) - } - }, - - initGraph: function(){ - var energy = this; - if (energy.graph === undefined){ - energy.graph = new CalendarGridChart({ - container: '#energy_graph', - outer_width: 800, - outer_height: 300, - date_attr: 'day', - color: '#0404B4', - toDate: (energy_datum)=>{ return energy_datum.day_to_date; } - }); - jQuery('#energy_graph').tooltip({ - selector: '.d3-chart-grid-unit', - container: 'body', - title: function(){ - var energy_datum = this.__data__, - date_s = d3.time.format('%a %b %d, %Y')(energy_datum.day_to_date), - range_value = `${Math.round(energy_datum.data[energy.state.graph_attr])} kWh`; - return `${date_s}: ${range_value}`; - } - }); - } - energy.updateGraph(); - }, - - updateGraph: function(){ - var energy = this, - house = energy.props.house; - energy.graph.rangeValue = (datum)=>{ return datum.data[energy.state.graph_attr]; } - energy.graph.drawData({ - title: energy.graph_title, - css_class: '', - min_range: 0, - max_range: 150, - values: house.energy_data - }); - }, - - destroyGraph: function(){ - var energy = this; - document.getElementById('energy_graph').innerHTML = ''; - energy.graph = undefined; - }, - - updateCurrentMonth: function(){ - var energy = this, - house = energy.props.house; - house.setEnergyData() - .then(()=>{ - if (energy.props.view === 'graph'){ - // no update necessary since year already updated in layout.rt. - energy.updateGraph(); - } else { - // force update to render correct data in table. - energy.forceUpdate(); - } - }); - }, - - render: function() { - return energyRt.call(this); - } -}); - -export default Energy; diff --git a/client/dashboard/energy/energy.rt b/client/dashboard/energy/energy.rt deleted file mode 100644 index 4c94242..0000000 --- a/client/dashboard/energy/energy.rt +++ /dev/null @@ -1,39 +0,0 @@ -
-
- Retrieving energy data for the {this.props.house.name} household... -
-
-

Select Data

-
- - -
-
- - - - - - - - - - - - - - - - - -
DayConsumption (kWh)Production (kWh)
{energy_datum.day_to_s}{energy_datum.consumption_to_s}{energy_datum.production_to_s}
-
-
diff --git a/client/dashboard/energy/energy.rt.js b/client/dashboard/energy/energy.rt.js deleted file mode 100644 index a17cbd5..0000000 --- a/client/dashboard/energy/energy.rt.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import _ from 'lodash'; -function repeatEnergy_datum1(energy_datum, energy_datumIndex) { - return React.createElement('tr', { 'key': energy_datum.scoped_id }, React.createElement('td', {}), React.createElement('td', {}, energy_datum.day_to_s), React.createElement('td', {}, energy_datum.consumption_to_s), React.createElement('td', {}, energy_datum.production_to_s)); -} -export default function () { - return React.createElement('div', { 'id': 'energy_view' }, this.state.loading_data ? React.createElement('div', { 'className': 'alert alert-warning' }, '\n Retrieving energy data for the ', this.props.house.name, ' household...\n ') : null, this.props.view === 'graph' ? React.createElement('div', {}, React.createElement('h4', {}, 'Select Data'), React.createElement('div', { - 'className': 'btn-group', - 'role': 'group' - }, React.createElement('button', { - 'data-value': 'consumption', - 'className': _.keys(_.pick({ active: this.state.graph_attr === 'consumption' }, _.identity)).join(' ') + ' ' + 'btn btn-primary', - 'onClick': this.setGraphAttr, - 'type': 'button' - }, 'Consumption'), React.createElement('button', { - 'data-value': 'production', - 'className': _.keys(_.pick({ active: this.state.graph_attr === 'production' }, _.identity)).join(' ') + ' ' + 'btn btn-primary', - 'onClick': this.setGraphAttr, - 'type': 'button' - }, 'Production'))) : null, this.props.view === 'table' ? React.createElement('table', { 'className': 'table' }, React.createElement('thead', {}, React.createElement('tr', {}, React.createElement('th', {}), React.createElement('th', {}, 'Day'), React.createElement('th', {}, 'Consumption (kWh)'), React.createElement('th', {}, 'Production (kWh)'))), React.createElement.apply(this, [ - 'tbody', - {}, - _.map(this.props.house.energy_data, repeatEnergy_datum1.bind(this)) - ])) : null, this.props.view === 'graph' ? React.createElement('div', { 'id': 'energy_graph' }) : null); -}; \ No newline at end of file diff --git a/client/dashboard/energy/energy.scss b/client/dashboard/energy/energy.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/dashboard/layout/layout.js b/client/dashboard/layout/layout.js deleted file mode 100644 index 24c3de9..0000000 --- a/client/dashboard/layout/layout.js +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; -import layoutRt from './layout.rt.js'; -import House from './../../models/house'; -import PowerDatum from './../../models/power_datum'; - -var Layout = React.createClass({ - - getInitialState: function(){ - var layout = this; - return { - houses: null, - house: null, - view: 'graph', - dataset: 'power', - requesting_data: true - }; - }, - - handleResize: function(e) { - this.setState({windowWidth: window.innerWidth}); - }, - - componentDidMount: function() { - var layout = this; - // window.addEventListener('resize', this.handleResize); - House.ensureHouses().then((houses)=>{ - layout.setState({ - houses: houses, - house: houses[0], - requesting_data: false, - month: houses[0].current_month, - year: houses[0].current_year - }); - }); - }, - - setHouse: function(event){ - var layout = this, - house_id = event.target.value, - old_house = layout.state.house, - house = layout.state.houses.find((house)=>{ return house.data.id == house_id }); - layout.setState({house: house}, ()=>{ - old_house.closeDb(); - }); - }, - - setView: function(event){ - var layout = this, - view = event.target.dataset.value; - layout.view_name = event.target.innerText; - layout.setState({view: view}); - }, - - setDataset: function(event){ - var layout = this, - dataset = event.target.dataset.value; - layout.setState({dataset: dataset}); - }, - - setYear: function(event){ - var layout = this, - year = event.target.dataset.value, - house = layout.state.house; - if (year != house.current_year){ - house.setYear(year); - layout.setState({year: year}); - } - }, - - refreshData: function(){ - var layout = this, - houses = layout.state.houses, - all = []; - houses.forEach((house)=>{ - all.push(house.clearData()); - }); - Promise.all(all) - .then(()=>{ - window.location.reload(); - }); - }, - - render: function() { - return layoutRt.call(this); - } -}); - -export default Layout; diff --git a/client/dashboard/layout/layout.rt b/client/dashboard/layout/layout.rt deleted file mode 100644 index 94c7255..0000000 --- a/client/dashboard/layout/layout.rt +++ /dev/null @@ -1,60 +0,0 @@ - - -
-
Retrieving houses...
- -

Select household:

- - - -

Select dataset:

-
- - -
- -

View as:

-
- - -
- -

Select dates:

-
- -

- - - -
diff --git a/client/dashboard/layout/layout.rt.js b/client/dashboard/layout/layout.rt.js deleted file mode 100644 index 18ed882..0000000 --- a/client/dashboard/layout/layout.rt.js +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react'; -import _ from 'lodash'; -import Energy from './../energy/energy'; -import Power from './../power/power'; -function repeatHouse1(house, houseIndex) { - return React.createElement('option', { - 'value': house.data.id, - 'key': house.scoped_id - }, house.data.name); -} -function repeatYear2(year, yearIndex) { - return React.createElement('button', { - 'data-value': year, - 'key': 'data-year-' + year, - 'className': 'btn-info btn btn-sm' + ' ' + _.keys(_.pick({ active: year == this.state.house.current_year }, _.identity)).join(' '), - 'onClick': this.setYear - }, year); -} -export default function () { - return React.createElement('div', { 'id': 'layout' }, this.state.requesting_data ? React.createElement('div', { 'className': 'alert alert-warning' }, 'Retrieving houses...') : null, React.createElement('h4', {}, 'Select household:'), this.state.houses ? React.createElement.apply(this, [ - 'select', - { - 'className': 'form-control', - 'onChange': this.setHouse - }, - _.map(this.state.houses, repeatHouse1.bind(this)) - ]) : null, this.state.house ? React.createElement('button', { - 'onClick': this.refreshData, - 'className': 'btn btn-xs btn-default' - }, 'Refresh House Data') : null, React.createElement('h4', {}, 'Select dataset:'), React.createElement('div', { - 'className': 'btn-group', - 'role': 'group' - }, React.createElement('button', { - 'data-value': 'energy', - 'className': _.keys(_.pick({ active: this.state.dataset === 'energy' }, _.identity)).join(' ') + ' ' + 'btn btn-primary', - 'onClick': this.setDataset, - 'type': 'button' - }, 'Daily Energy Statistics'), React.createElement('button', { - 'data-value': 'power', - 'className': _.keys(_.pick({ active: this.state.dataset === 'power' }, _.identity)).join(' ') + ' ' + 'btn btn-primary', - 'onClick': this.setDataset, - 'type': 'button' - }, '15-minute Power Statistics')), React.createElement('h4', {}, 'View as:'), React.createElement('div', { - 'className': 'btn-group', - 'role': 'group' - }, React.createElement('button', { - 'data-value': 'graph', - 'className': _.keys(_.pick({ active: this.state.view === 'graph' }, _.identity)).join(' ') + ' ' + 'btn btn-primary', - 'onClick': this.setView, - 'type': 'button' - }, 'Graph'), React.createElement('button', { - 'data-value': 'table', - 'className': _.keys(_.pick({ active: this.state.view === 'table' }, _.identity)).join(' ') + ' ' + 'btn btn-primary', - 'onClick': this.setView, - 'type': 'button' - }, 'Table')), React.createElement('h4', {}, 'Select dates:'), React.createElement.apply(this, [ - 'div', - { 'className': 'btn-group' }, - this.state.house ? _.map(this.state.house.years, repeatYear2.bind(this)) : null - ]), React.createElement('br', {}), this.state.house && this.state.dataset === 'energy' ? React.createElement(Energy, { - 'house': this.state.house, - 'view': this.state.view, - 'year': this.state.year - }) : null, this.state.house && this.state.dataset === 'power' ? React.createElement(Power, { - 'house': this.state.house, - 'view': this.state.view, - 'year': this.state.year - }) : null); -}; \ No newline at end of file diff --git a/client/dashboard/layout/layout.scss b/client/dashboard/layout/layout.scss deleted file mode 100644 index ec5b920..0000000 --- a/client/dashboard/layout/layout.scss +++ /dev/null @@ -1,9 +0,0 @@ -#layout { - h1 { - color: red; - } -} -// needless comment -#yada { - div { padding: 200px; } -} diff --git a/client/dashboard/power/power.js b/client/dashboard/power/power.js deleted file mode 100644 index 10141a9..0000000 --- a/client/dashboard/power/power.js +++ /dev/null @@ -1,199 +0,0 @@ -import React from 'react'; -import moment from 'moment-timezone'; -import _ from 'lodash'; - -import powerRt from './power.rt.js'; -import House from './../../models/house'; -import SplineStackChart from './../../d3/line/spline_stack'; -import DateRangeSlider from './../../d3/sliders/date_range'; - -var Power = React.createClass({ - - getInitialState: function(){ - var power = this; - return { - loading_data: true - }; - }, - - handleResize: function(e) { - this.setState({windowWidth: window.innerWidth}); - }, - - componentDidMount: function() { - // window.addEventListener('resize', this.handleResize); - var power = this, - house = power.props.house; - power.graph_title = ''; - power.initDateRange(); - house.setPowerData().then(()=>{ - power.setState({loading_data: false}); - if (power.props.view === 'graph'){ - power.initGraph(); - } - }); - }, - - componentWillUnmount: function(){ - var power = this; - power.destroyGraph(); - }, - - componentWillReceiveProps: function(new_props){ - var power = this; - if (new_props.house !== power.props.house){ - // house will change. - power.setState({loading_data: true}); - new_props.house.setPowerData().then(()=>{ - power.setState({loading_data: false}); - if (power.props.view === 'graph'){ - power.initGraph(); - } - }); - } - // view will change from graph to table. - if (new_props.view !== 'graph' && power.props.view === 'graph') power.destroyGraph(); - }, - - componentDidUpdate: function(prev_props, _prev_state){ - var power = this, - house = power.props.house; - // view has changed from graph to table. - if (prev_props.view !== 'graph' && power.props.view === 'graph'){ - power.initGraph(); - } - if (prev_props.house !== house) power.initDateRange(); - var need_update = false; - if (prev_props.year !== power.props.year){ - power.updateCurrentMonth(); - } - }, - - initGraph: function(){ - var power = this, - house = power.props.house; - if (power.graph === undefined){ - power.graph = new SplineStackChart({ - container: '#power_graph', - outer_width: 800, - outer_height: 200, - color: '#0404B4', - time_series: true, - domain_attr: 'x', - range_attr: 'y', - include_dots: true, - titleizeDatum: (series, d)=>{ - return series.title + '
' + Math.round(d.y) + ' W
' + house.formatDate(d.power_datum.data.time, 'MMM D [at] HH:mm'); - } - }); - jQuery('#power_graph').tooltip({ - selector: 'circle', - container: 'body', - html: true, - title: function(){ - return this.__data__.title; - } - }); - } - power.updateGraph(); - }, - - updateGraph: function(){ - var power = this, - house = power.props.house, - net_power = { - title: 'Net Power Consumption', - values: house.power_data.map((power_datum)=>{ - return { - power_datum: power_datum, - x: power_datum.time_to_date, - y: Math.max(0, power_datum.data.consumption - power_datum.data.production) } - }) - }, - savings = { - title: 'Power Production', - values: house.power_data.map((power_datum)=>{ - return { - power_datum: power_datum, - x: power_datum.time_to_date, - y: power_datum.data.production } - }) - }; - power.graph.drawData({ - title: power.graph_title, - css_class: '', - series: [net_power, savings] - }); - }, - - initDateRange: function(){ - var power = this, - house = power.props.house; - if (power.date_range_slider === undefined){ - power.date_range_slider = new DateRangeSlider({ - container: '#power_date_setter', - outer_height: 100, - maxDelta: function(changed_date, other_date){ - if (Math.abs(changed_date.getTime() - other_date.getTime()) > 3600 * 24 * 4 * 1000){ - if (changed_date > other_date){ - return new Date(changed_date.getTime() - 3600 * 24 * 4 * 1000); - } else { - return new Date(changed_date.getTime() + 3600 * 24 * 4 * 1000); - } - } - return false; - } - }); - } - power.date_range_slider.onRangeUpdated = (min, max)=>{ - if (power.date_range_update) clearTimeout(power.date_range_update) - power.date_range_update = setTimeout(()=>{ - house.power_date_range = [Math.round(min.getTime() / 1000), Math.round(max.getTime() / 1000)] - house.setPowerData() - .then(()=>{ - if (power.props.view === 'graph') power.updateGraph(); - else power.forceUpdate(); - }); - }, 500); - }; - power.date_range_slider.drawData({ - abs_min: house.current_month_moment.toDate(), - abs_max: house.end_of_current_data_moment.toDate(), - current_min: house.toDate(house.power_date_range[0]), - current_max: house.toDate(house.power_date_range[1]) - }); - }, - - destroyGraph: function(){ - var power = this; - document.getElementById('power_graph').innerHTML = ''; - power.graph = undefined; - }, - - setMonth: function(event){ - var power = this, - house = power.props.house, - month = event.target.dataset.value; - if (month !== house.current_month){ - var need_update = house.setMonth(month); - if (need_update) power.updateCurrentMonth(); - } - }, - - updateCurrentMonth: function(){ - var power = this, - house = power.props.house; - power.initDateRange(); - house.setPowerData() - .then(()=>{ - power.forceUpdate(); - if (power.props.view === 'graph') power.updateGraph(); - }); - }, - - render: function() { - return powerRt.call(this); - } -}); - -export default Power; diff --git a/client/dashboard/power/power.rt b/client/dashboard/power/power.rt deleted file mode 100644 index f075273..0000000 --- a/client/dashboard/power/power.rt +++ /dev/null @@ -1,35 +0,0 @@ -
-
- -
-
- Retrieving power data for the {this.props.house.name} household... -
-
- - - - - - - - - - - - - - - - - -
TimeConsumption (W)Production (W)
{power_datum.data.id}{power_datum.time_to_s}{power_datum.consumption_to_s}{power_datum.production_to_s}
-
-
diff --git a/client/dashboard/power/power.rt.js b/client/dashboard/power/power.rt.js deleted file mode 100644 index 7927c9a..0000000 --- a/client/dashboard/power/power.rt.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import _ from 'lodash'; -function repeatMonth1(month, monthIndex) { - return React.createElement('button', { - 'data-value': month, - 'key': 'data-month-' + month, - 'className': 'btn-warning btn btn-sm' + ' ' + _.keys(_.pick({ active: month === this.props.house.current_month }, _.identity)).join(' '), - 'onClick': this.setMonth - }, month); -} -function repeatPower_datum2(power_datum, power_datumIndex) { - return React.createElement('tr', { 'key': power_datum.scoped_id }, React.createElement('td', {}, power_datum.data.id), React.createElement('td', {}, power_datum.time_to_s), React.createElement('td', {}, power_datum.consumption_to_s), React.createElement('td', {}, power_datum.production_to_s)); -} -export default function () { - return React.createElement('div', { 'id': 'power_view' }, React.createElement.apply(this, [ - 'div', - { 'className': 'btn-group' }, - this.props.house ? _.map(this.props.house.availableMonths(), repeatMonth1.bind(this)) : null - ]), this.state.loading_data ? React.createElement('div', { 'className': 'alert alert-warning' }, '\n Retrieving power data for the ', this.props.house.name, ' household...\n ') : null, React.createElement('div', { 'id': 'power_date_setter' }), this.props.view === 'table' ? React.createElement('table', { 'className': 'table' }, React.createElement('thead', {}, React.createElement('tr', {}, React.createElement('th', {}), React.createElement('th', {}, 'Time'), React.createElement('th', {}, 'Consumption (W)'), React.createElement('th', {}, 'Production (W)'))), React.createElement.apply(this, [ - 'tbody', - {}, - _.map(this.props.house.power_data, repeatPower_datum2.bind(this)) - ])) : null, this.props.view === 'graph' ? React.createElement('div', { 'id': 'power_graph' }) : null); -}; \ No newline at end of file diff --git a/client/lib/databasable.js b/client/lib/databasable.js deleted file mode 100644 index abe6b67..0000000 --- a/client/lib/databasable.js +++ /dev/null @@ -1,70 +0,0 @@ -import Loki from 'lokijs/src/lokijs'; -import LokiIndexedAdapter from 'lokijs/src/loki-indexed-adapter'; - -const DEFAULTS = { - autosave: false -}; - -var databasable = { - - accessDb: function(db_name, opts){ - var databasable = this; - opts = Object.assign(Object.assign({ - adapter: new LokiIndexedAdapter(db_name) - }, DEFAULTS), opts || {}); - return new Promise((fnResolve, fnReject)=>{ - if (!databasable.db) { - databasable.db = new Loki(db_name, opts); - databasable.db.loadDatabase({}, ()=>{ - fnResolve(databasable.db); - }); - } else { fnResolve(databasable.db); } - - }); - }, - - closeDb: function(){ - var databasable = this; - if (databasable.db){ - databasable.db.save(); - databasable.db.close(); - databasable.db = undefined; - } - }, - - collection: function(db_name, collection_name, options){ - var databasable = this; - return databasable.accessDb(db_name) - .then((db)=>{ - var collection = db.getCollection(collection_name) - if (!collection){ - collection = db.addCollection(collection_name, options); - if (options && options.unique_indices){ - options.unique_indices.forEach((field)=>{ - collection.ensureUniqueIndex(field); - }); - } - } - return collection; - }); - }, - - rangeToLokiParams: function(attr, range){ - var date_params = {}; - if (range[0] !== undefined && range[0] !== undefined){ - var start_condition = {}, - end_condition = {}; - date_params['$and'] = [start_condition, end_condition]; - start_condition[attr] = {'$gte': range[0]}; - end_condition[attr] = {'$lte': range[1]}; - } else if (range[0] !== undefined) { - date_params[attr] = {'$gte': range[0]} - } else if (range[1] !== undefined) { - date_params[attr] = {'$lte': range[1]} - } - return date_params; - } - -}; - -export default databasable; diff --git a/client/lib/model.js b/client/lib/model.js deleted file mode 100644 index 0a61b40..0000000 --- a/client/lib/model.js +++ /dev/null @@ -1,9 +0,0 @@ -import Loki from 'lokijs'; - - -class Model { - - - - -} diff --git a/client/models/energy_datum.js b/client/models/energy_datum.js deleted file mode 100644 index afc5df4..0000000 --- a/client/models/energy_datum.js +++ /dev/null @@ -1,47 +0,0 @@ -import extend from 'extend'; -import moment from 'moment-timezone'; - -const NAME = 'EnergyDatum'; -const COLLECTION_DEFAULTS = { - indices: ['day'] -}; - -class EnergyDatum { - constructor(data, house){ - var energy_datum = this; - energy_datum.house = house; - energy_datum.data = data; - } - - get react_key(){ - return `energy-datum-${this.data.id}`; - } - - // returns a datestamp that has the client timezone, but actually is house local time. - get day_to_date(){ - var energy_datum = this, - house = energy_datum.house; - return house.toDate(energy_datum.data.day); - } - - get day_to_s(){ - var energy_datum = this; - return moment.tz(energy_datum.data.day * 1000, energy_datum.house.data.timezone).format('YYYY-MM-DD'); - } - - get consumption_to_s(){ - var energy_datum = this; - return Math.round(energy_datum.data.consumption); - } - - get production_to_s(){ - var energy_datum = this; - return Math.round(energy_datum.data.production); - } - -} - -EnergyDatum.NAME = NAME; -EnergyDatum.COLLECTION_DEFAULTS = COLLECTION_DEFAULTS; - -export default EnergyDatum; diff --git a/client/models/house.js b/client/models/house.js deleted file mode 100644 index abfa12a..0000000 --- a/client/models/house.js +++ /dev/null @@ -1,261 +0,0 @@ -import extend from 'extend'; -import Loki from 'lokijs/src/lokijs'; -import moment from 'moment-timezone'; - -import PowerDatum from './power_datum'; -import EnergyDatum from './energy_datum'; -import PowerDataApi from './../api/power_data'; -import EnergyDataApi from './../api/energy_data'; -import HousesApi from './../api/houses'; -import ArrayUtil from './../../shared/utils/array'; -import MathUtil from './../../shared/utils/math'; -import DateRange from './../../shared/utils/date_range'; -import Databasable from './../lib/databasable'; - -const NAME = 'House'; - -class House { - - // must be initiated with a dataset already in Loki database (not directly JSON). - constructor(data){ - var house = this; - house.data = data; - Object.assign(house, Databasable); - - var n_years = house.data_until_moment.year() - house.data_from_moment.year() + 1; - house.years = []; - for (var year=house.data_from_moment.year(); year<=house.data_until_moment.year(); year+=1){ - house.years.push(year); - } - house.current_month = house.data_until_moment.format('MMM'); - house.current_year = house.data_until_moment.year(); - house.setCurrentMonthMoment(); - } - - get data_from_moment(){ - var house = this; - return moment.tz(house.data.data_from * 1000, house.data.timezone); - } - - get data_until_moment(){ - var house = this; - return moment.tz(house.data.data_until * 1000, house.data.timezone); - } - - get end_of_current_data_moment(){ - var house = this, - end_of_month = house.current_month_moment.clone().endOf('month'); - return end_of_month > house.data_until_moment ? house.data_until_moment : end_of_month; - } - - get scoped_id(){ - return `house-${this.data.id}`; - } - - availableMonths(){ - var house = this, - all_months = moment.monthsShort(), - year = house.current_year.toString(); - if ((year) === house.data_from_moment.format('YYYY')){ - return all_months.slice(house.data_from_moment.month(), 12); - } else if (year === house.data_until_moment.format('YYYY')){ - return all_months.slice(0, house.data_until_moment.month() + 1); - } else { - return all_months; - } - } - - setYear(year){ - var house = this; - house.current_year = year; - return house.setCurrentMonthMoment(); - } - - setMonth(month){ - var house = this; - house.current_month = month; - return house.setCurrentMonthMoment(); - } - - setCurrentMonthMoment(){ - var house = this, - month_i = moment.monthsShort().indexOf(house.current_month), - new_month_moment = moment.tz({year: house.current_year, month: month_i, day: 1}, house.data.timezone).startOf('month'); - if (!house.current_month_moment || new_month_moment.unix() !== house.current_month_moment.unix()){ - house.current_month_moment = new_month_moment; - house.power_date_range = [house.end_of_current_data_moment.clone().subtract(4, 'days').unix(), house.end_of_current_data_moment.unix()]; - house.energy_date_range = [house.end_of_current_data_moment.clone().startOf('year').unix(), house.end_of_current_data_moment.clone().endOf('year').unix()] - return true; - } - return false; - } - - offset_diff(unix){ - var house = this, - tz = moment.tz.zone(house.data.timezone); - return (new Date().getTimezoneOffset() - tz.offset(unix * 1000)) * 60; - } - - toDate(unix){ - var house = this; - return new Date((unix + house.offset_diff(unix)) * 1000); - } - - formatDate(unix, format){ - var house = this; - return moment.tz(unix * 1000, house.data.timezone).format(format) - } - - save(){ - var house = this; - return House.collection(House.NAME, House.NAME) - .then((house_collection)=>{ - house_collection.update(house.data); - return House.db.save(); - }); - } - - setPowerData(){ - var house = this; - return house.collection(house.scoped_id, PowerDatum.NAME, PowerDatum.COLLECTION_OPTIONS) - .then((power_collection)=>{ - return house.ensurePowerData() - .then(()=>{ - var params = house.rangeToLokiParams('time', house.power_date_range); - house.power_data = power_collection.find(params) - .sort((pd1, pd2)=>{ - if (pd1.time === pd2.time) return 0; - if (pd1.time > pd2.time) return 1; - if (pd1.time < pd2.time) return -1; - }) - .map((data)=>{ return new PowerDatum(data, house); }); - }); - }); - } - - ensurePowerData(){ - var house = this, - query_ranges; - - query_ranges = DateRange.addRange(house.power_date_range, house.data.power_datum_ranges || []); - if (query_ranges.gaps_filled.length > 0){ - var params = {dates: query_ranges.gaps_filled}; - return house.getPowerData(params) - .then(()=>{ - house.data.power_datum_ranges = query_ranges.new_ranges; - house.save(); - }); - } else { return Promise.resolve(); } - } - - getPowerData(params){ - var house = this; - params.house_id = house.data.id; - return house.collection(house.scoped_id, PowerDatum.NAME, PowerDatum.COLLECTION_OPTIONS) - .then((power_collection)=>{ - return PowerDataApi.index(params) - .then((power_data)=>{ - power_collection.insert(power_data); - house.db.save(); - }); - }) - } - - setEnergyData(){ - var house = this; - return house.collection(house.scoped_id, EnergyDatum.NAME, EnergyDatum.COLLECTION_OPTIONS) - .then((energy_collection)=>{ - return house.ensureEnergyData() - .then(()=>{ - var params = house.rangeToLokiParams('day', house.energy_date_range); - house.energy_data = energy_collection.find(params) - .sort((pd1, pd2)=>{ - if (pd1.day === pd2.day) return 0; - if (pd1.day > pd2.day) return 1; - if (pd1.day < pd2.day) return -1; - }) - .map((data)=>{ return new EnergyDatum(data, house); }); - }); - }); - } - - ensureEnergyData(){ - var house = this, - query_ranges = DateRange.addRange(house.energy_date_range, house.data.energy_datum_ranges || []); - if (query_ranges.gaps_filled.length > 0){ - return house.getEnergyData({dates: query_ranges.gaps_filled}) - .then(()=>{ - house.data.energy_datum_ranges = query_ranges.new_ranges; - house.save(); - }); - } else { return Promise.resolve(); } - } - - getEnergyData(params){ - var house = this; - params.house_id = house.data.id; - return house.collection(house.scoped_id, EnergyDatum.NAME, EnergyDatum.COLLECTION_OPTIONS) - .then((energy_collection)=>{ - return EnergyDataApi.index(params) - .then((energy_data)=>{ - energy_collection.insert(energy_data); - house.db.save(); - }); - }) - } - - // removes all energy and power data from LokiJs (memory and persisted) database. - clearData(){ - var house = this, - all = [ - new Promise((fnResolve, fnReject)=>{ - house.collection(house.scoped_id, PowerDatum.NAME) - .then((power_collection)=>{ - power_collection.removeWhere({}); - house.db.save(fnResolve); - }); - }), - new Promise((fnResolve, fnReject)=>{ - house.collection(house.scoped_id, EnergyDatum.NAME) - .then((energy_collection)=>{ - energy_collection.removeWhere({}); - house.db.save(fnResolve); - }); - }), - new Promise((fnResolve, fnReject)=>{ - House.collection(House.NAME, House.NAME) - .then((house_collection)=>{ - house_collection.remove(house.data); - House.db.save(fnResolve); - }); - }) - ] - return Promise.all(all) - } - - static ensureHouses(ids){ - return House.collection(House.NAME, House.NAME) - .then((house_collection)=>{ - var houses_data = ids ? house_collection.find({id: {$in: ids}}) : house_collection.find(); - if (!ids && houses_data.length === 0 || ids && houses_data.length !== ids.length){ - var required_ids = ids ? ArrayUtil.diff(ids, houses_data.map((data)=>{ return data.id; })) : undefined; - return HousesApi.index({id: ids}) - .then((required_houses)=>{ - required_houses.forEach((house_data)=>{ - house_collection.insert(house_data); - }); - House.db.save(); - return houses_data.concat(required_houses); - }); - } else { return Promise.resolve(houses_data); } - }).then((houses_data)=>{ - return houses_data.map((house_data)=>{ return new House(house_data); }) - }); - } - -} - -House.NAME = NAME; - -Object.assign(House, Databasable); -export default House; diff --git a/client/models/power_datum.js b/client/models/power_datum.js deleted file mode 100644 index c53a7ac..0000000 --- a/client/models/power_datum.js +++ /dev/null @@ -1,46 +0,0 @@ -import extend from 'extend'; -import moment from 'moment-timezone'; - -const NAME = 'PowerDatum'; -const COLLECTION_DEFAULTS = { - indices: ['time'], - unique_indices: ['time'] -}; - -class PowerDatum { - constructor(data, house){ - var power_datum = this; - power_datum.house = house; - power_datum.data = data; - } - - get react_key(){ - return `power-datum-${this.data.id}`; - } - - get time_to_date(){ - var power_datum = this, - house = power_datum.house; - return house.toDate(power_datum.data.time); - } - - get time_to_s(){ - var power_datum = this, - moment_tz = moment.tz(power_datum.data.time * 1000, power_datum.house.data.timezone); - return moment_tz.format('YYYY-MM-DD HH:mm'); - } - get consumption_to_s(){ - var power_datum = this; - return Math.round(power_datum.data.consumption); - } - get production_to_s(){ - var power_datum = this; - return Math.round(power_datum.data.production); - } - -} - -PowerDatum.NAME = NAME; -PowerDatum.COLLECTION_DEFAULTS = COLLECTION_DEFAULTS; - -export default PowerDatum; diff --git a/client/style.js b/client/style.js deleted file mode 100644 index 1903da4..0000000 --- a/client/style.js +++ /dev/null @@ -1,9 +0,0 @@ -// Vendor Stylesheets -require('bootstrap/dist/css/bootstrap.min.css'); -require('font-awesome/css/font-awesome.min.css'); - - -// Component Stylesheets -require(__dirname + '/style.scss'); -require(__dirname + '/dashboard/layout/layout.scss'); -require(__dirname + '/d3/chart.scss'); diff --git a/client/style.scss b/client/style.scss deleted file mode 100644 index df9f399..0000000 --- a/client/style.scss +++ /dev/null @@ -1,16 +0,0 @@ -html, body { - height:100%; -} -#spike_container { - min-height: 100%; - position:relative; - padding-bottom:100px; -} -#spike_footer { - width:100%; - padding:15px; - position:absolute; - bottom:0px; - border-top:2px solid darkgrey; - background-color:#F8F8F8; -} diff --git a/gulpfile.babel.js b/gulpfile.babel.js deleted file mode 100644 index 857be1c..0000000 --- a/gulpfile.babel.js +++ /dev/null @@ -1,68 +0,0 @@ -import gulp from 'gulp'; -import yargs from 'yargs'; -import webpack from 'webpack'; -import gutil from 'gulp-util'; - -import DB from './server/config/database'; -import {PowerDataSeed, HouseSeed} from './server/lib/tasks/seed_data'; -import rtCompile from './server/lib/tasks/react_template_compile'; -import rt_config from './server/config/react_templates'; - -gulp.task('generate_power_csv', function(done){ - DB.sync().then(()=>{ - PowerDataSeed.generateCsv(yargs.argv, done); - }); -}); - -gulp.task('save_power_csv', function(done){ - DB.sync().then(()=>{ - PowerDataSeed.saveCsv(yargs.argv, done); - }); -}); - -gulp.task('save_house_csv', function(done){ - DB.sync().then(()=>{ - HouseSeed.saveCsv(yargs.argv, done); - }); -}); - -gulp.task('compile_react_templates', function() { - gulp.src('./client/dashboard/**/*.rt') - .pipe(rtCompile(rt_config)) - .pipe(gulp.dest('./client/dashboard')); -}); - - -gulp.task('build', function(done) { - var config, env; - - if (yargs.argv.production){ - env = 'production'; - } else if (yargs.argv.design){ - env = 'design'; - } else if (yargs.argv.test){ - env = 'test'; - } else { - throw new gutil.PluginError("webpack", "Must include '--production' or '--design' option."); - } - config = require(`${__dirname}/server/config/webpack/${env}`); - // run webpack - webpack(config, function(err, stats) { - if(err) throw new gutil.PluginError("webpack", err); - gutil.log("[webpack]", stats.toString({ - // output options - })); - done(); - }); -}); - -gulp.task('test', function(done) { - var Jasmine = require('jasmine'); - var jasmine = new Jasmine(); - - jasmine.loadConfigFile('test/jasmine.json'); - jasmine.configureDefaultReporter({ - showColors: true - }); - jasmine.execute(); -}); diff --git a/package.json b/package.json deleted file mode 100644 index f1996bf..0000000 --- a/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "spike_proto", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "babel-node ./server/app.express.js" - }, - "dependencies": { - "body-parser": "~1.12.0", - "debug": "~2.1.1", - "jade": "~1.9.2", - "morgan": "~1.5.1", - "serve-favicon": "~2.2.0", - "node-forge": "~0.6.26", - "sequelize": "~3.15.1", - "pg": "~4.4.3", - "pg-hstore": "~2.3.2", - "fast-csv": "0.6.0", - "babel-polyfill": "6.3.14", - "babel-preset-es2015": "6.3.13", - "babel-preset-react": "6.3.13", - "babel-preset-stage-0": "6.3.13", - "babel-core": "6.3.21", - "babel-loader": "6.2.0", - "express": "4.13.3", - "react": "0.14.3", - "react-dom": "0.14.3", - "webpack": "1.12.9", - "webpack-dev-server": "1.14.0", - "extract-text-webpack-plugin": "1.0.1", - "jquery": "2.2.0", - "bootstrap": "3.3.6", - "d3": "3.5.12", - "font-awesome": "4.5.0", - "raw-loader": "0.5.1", - "sass-loader": "3.1.2", - "style-loader": "^0.12.3", - "json-loader": "0.5.4", - "node-sass": "3.4.2", - "moment-timezone": "0.5.0", - "yargs": "3.32.0", - "extend": "3.0.0", - "through2": "2.0.1", - "lokijs": "1.3.11", - "babel-cli": "^6.3.17", - "babel-standalone": "6.4.4", - "gulp": "^3.9.0", - "gulp-util": "3.0.7", - "jasmine-core": "2.4.1", - "karma": "^0.13.19", - "karma-babel-preprocessor": "^6.0.1", - "karma-chrome-launcher": "^0.2.2", - "karma-jasmine": "^0.3.6", - "react-templates": "0.4.1", - "requirejs": "~2.1", - "jasmine-es6": "0.1.4" - } -} diff --git a/readme.md b/readme.md deleted file mode 100644 index cddb9d8..0000000 --- a/readme.md +++ /dev/null @@ -1 +0,0 @@ -# Spike diff --git a/server/app.express.js b/server/app.express.js deleted file mode 100644 index ff46718..0000000 --- a/server/app.express.js +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Serve GraphQL Backend - */ - -import express from 'express'; -import path from 'path'; -import webpack from 'webpack'; -import WebpackDevServer from 'webpack-dev-server'; -import bodyParser from 'body-parser'; - - -import DB from './config/database'; -import routes from './routes'; - -const API_PORT = 8080; -const APP_PORT = 3000; - -var api = express(); - -/* - * Serve API App - */ - -DB.sync().then(()=>{ - - routes(api); - - api.use(bodyParser.json()); - api.use(bodyParser.urlencoded({ extended: false })); - - - api.listen(API_PORT, () => { - console.log(`API is now running on http://localhost:${API_PORT}`); - }); - -}); - - -/* - * Development Server - */ - -var config = require('./config/webpack/development'), - dev_server = new WebpackDevServer(webpack(config), { - contentBase: __dirname + '/../client/build/development', - publicPath: "/assets/", - proxy: { - '/data*': `http://localhost:${API_PORT}`, - }, - stats: {colors: true} - }), - app = dev_server.app; - -/* - * Serve Vendor Scripts, CSS, and Templates - */ - -import favicon from 'serve-favicon'; -import logger from 'morgan'; - -// uncomment after placing your favicon in /public -app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); - -// serve fonts in /assets/fonts -import assets from "connect-assets"; - -// TODO: These routes need to match references in the bootstrap and font awesome files. -app.use("/assets/fonts", express.static("bootstrap/dist/fonts")); -app.use("/assets/fonts", express.static("font-awesome/fonts")); -// serve compiled vendor assets and application.css. -app.use(assets({ - paths: ["./../node_modules"], - build: true, - buildDir: false, - //compile: false, - compress: true -})); -// serve public static files. -dev_server.app.use('/', express.static(path.resolve(__dirname, 'public'))); - -// view engine set up -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); -app.get("/", (req, res, next)=>{ - res.render("index"); -}); - - -/* - * Handle Errors - */ - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - -dev_server.listen(APP_PORT, () => { - console.log(`App is now running on http://localhost:${APP_PORT}`); -}); - -module.exports = app; diff --git a/server/config/controllers.js b/server/config/controllers.js deleted file mode 100644 index d76d60b..0000000 --- a/server/config/controllers.js +++ /dev/null @@ -1,17 +0,0 @@ -import fs from 'fs'; - -const CONTROLLER_DIR = __dirname + '/../controllers'; - -class Controllers { - - static sync(){ - fs.readdirSync(CONTROLLER_DIR).forEach(function(file) { - var controller = require(CONTROLLER_DIR + '/' + file); - Controllers[controller.NAME] = controller; - }); - return true; - } - -} - -export default Controllers; diff --git a/server/config/database.js b/server/config/database.js deleted file mode 100644 index d13d5d8..0000000 --- a/server/config/database.js +++ /dev/null @@ -1,37 +0,0 @@ -"use strict"; - -import fs from "fs"; -import Sequelize from 'sequelize'; - -var sequelize = new Sequelize("postgres://spikeuser:123456@localhost:5432/spike2", { - pool: { - max: 5, - min: 0, - idle: 10000 - } -}); -const MODEL_DIR = __dirname + '/../models' - -class Database { - - static sync(){ - console.log("syncing db") - fs.readdirSync(MODEL_DIR).forEach(function(file) { - var model = require(MODEL_DIR + '/' + file); - Database[model.NAME] = model; - Database.models.push(model); - }); - - // add associations - for (var model of Database.models){ - model.set(); - } - - return sequelize.sync().then(()=>{ console.log("done syncing db") }); - } -} -Database.sequelize = sequelize; -Database.Sequelize = Sequelize; -Database.models = []; - -export default Database; diff --git a/server/config/react_templates.js b/server/config/react_templates.js deleted file mode 100644 index 3809455..0000000 --- a/server/config/react_templates.js +++ /dev/null @@ -1,7 +0,0 @@ -var config = { - modules: 'es6', - targetVersion: '0.14.0', - suffix: '.rt' -}; - -export default config; diff --git a/server/config/webpack/design.js b/server/config/webpack/design.js deleted file mode 100644 index a9af8e5..0000000 --- a/server/config/webpack/design.js +++ /dev/null @@ -1 +0,0 @@ -design.js diff --git a/server/config/webpack/development.js b/server/config/webpack/development.js deleted file mode 100644 index 897de9e..0000000 --- a/server/config/webpack/development.js +++ /dev/null @@ -1,48 +0,0 @@ -import webpack from 'webpack'; - -const ROOT = __dirname + '/../../../'; - -module.exports = { - entry: { - app: ROOT + 'client/app', - style: ROOT + 'client/style' - }, - output: { - filename: '[name].js', - path: ROOT + 'client/build/development' - }, - module: { - loaders: [ - { - test: /\.scss$/, - loaders: ['style', 'raw', 'sass'] - }, { - test: /\.css$/, - loaders: ['style', 'raw'] - }, { - test: /\.js$/, - loader: 'babel' - }, { - test: /\.json$/, - loader: 'json-loader' - } - ] - }, - sassLoader: { - includePaths: [ROOT + 'client', ROOT + 'node_modules'] - }, - plugins: [ - new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" - }), - new webpack.ProvidePlugin({ - d3: "d3", - "window.d3": "d3" - }) - ], - node: { - fs: "empty" - } -} diff --git a/server/config/webpack/production.js b/server/config/webpack/production.js deleted file mode 100644 index dae28da..0000000 --- a/server/config/webpack/production.js +++ /dev/null @@ -1,58 +0,0 @@ -import ExtractTextPlugin from 'extract-text-webpack-plugin'; -import webpack from 'webpack'; - -const ROOT = __dirname + '/../../../'; - -module.exports = { - entry: { - app: ROOT + 'client/app', - style: ROOT + 'client/style' - }, - devtool: 'source-map', - output: { - filename: '[name].min.js', - path: ROOT + 'client/build/production' - }, - externals: { - jquery: "$", - d3: "d3" - }, - module: { - loaders: [ - { - test: /\.scss$/, - loader: ExtractTextPlugin.extract("style-loader", "raw-loader!sass-loader") - }, { - test: /\.css$/, - loader: ExtractTextPlugin.extract("style-loader", "raw-loader") - }, { - test: /\.js$/, - loader: 'babel' - }, { - test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, - loader: "url-loader?limit=10000&minetype=application/font-woff" - }, { - test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, - loader: "file-loader" - } - ] - }, - sassLoader: { - includePaths: [ROOT + 'client', ROOT + 'node_modules'] - }, - // Use the plugin to specify the resulting filename (and add needed behavior to the compiler) - plugins: [ - new ExtractTextPlugin("style.min.css", { - allChunks: true - }), - new webpack.optimize.UglifyJsPlugin({minimize: true}), - new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" - }) - ], - node: { - fs: "empty" - } -}; diff --git a/server/controllers/energy_controller.js b/server/controllers/energy_controller.js deleted file mode 100644 index 9646461..0000000 --- a/server/controllers/energy_controller.js +++ /dev/null @@ -1,16 +0,0 @@ -import DB from './../config/database.js'; - -const NAME = 'EnergyController'; - -class EnergyController{ - - static index(req, res){ - DB.EnergyDatum.exposeForHouseAtDates(req.query.house_id, req.query.dates).then((energy_data)=>{ - res.json({data: energy_data}); - }); - } - -} - -EnergyController.NAME = NAME; -module.exports = EnergyController; diff --git a/server/controllers/houses_controller.js b/server/controllers/houses_controller.js deleted file mode 100644 index 3fa4d8e..0000000 --- a/server/controllers/houses_controller.js +++ /dev/null @@ -1,18 +0,0 @@ -import DB from './../config/database.js'; - -const NAME = 'HousesController'; - -class HousesController { - - static index(req, res){ - var params = {}; - if (req.query.ids) query.id = ids; - DB.House.findAll({where: params}).then((houses)=>{ - res.json({data: houses.map((house)=>{ return house.dataValues; })}); - }); - } - -} - -HousesController.NAME = NAME; -module.exports = HousesController; diff --git a/server/controllers/power_controller.js b/server/controllers/power_controller.js deleted file mode 100644 index 8c4654b..0000000 --- a/server/controllers/power_controller.js +++ /dev/null @@ -1,16 +0,0 @@ -import DB from './../config/database.js'; - -const NAME = 'PowerController'; - -class PowerController{ - - static index(req, res){ - DB.PowerDatum.exposeForHouseAtDates(req.query.house_id, req.query.dates).then((power_data)=>{ - res.json({data: power_data}); - }); - } - -} - -PowerController.NAME = NAME; -module.exports = PowerController; diff --git a/server/helpers/api_helper.js b/server/helpers/api_helper.js deleted file mode 100644 index 964188e..0000000 --- a/server/helpers/api_helper.js +++ /dev/null @@ -1,29 +0,0 @@ -class ApiHelper { - - // assume all dates from api coming as UNIX timestamps. - static datesParamToSequelize(dates, field_name){ - if (!dates) return {}; - var params = {}; - - if (dates.length > 1){ - params['$or'] = []; - dates.forEach((min_max)=>{ - var condition_n = {}; - condition_n[field_name] = {}; - if (min_max[0]) condition_n[field_name]['$gte'] = min_max[0]; - if (min_max[1]) condition_n[field_name]['$lte'] = min_max[1]; - if (Object.keys(condition_n).length) params['$or'].push(condition_n); - }); - } else { - var min_max = dates[0], - condition = {} - if (min_max[0]) condition['$gte'] = min_max[0]; - if (min_max[1]) condition['$lte'] = min_max[1]; - if (Object.keys(condition).length) params[field_name] = condition; - } - return params; - } - -} - -export default ApiHelper; diff --git a/server/lib/tasks/react_template_compile.js b/server/lib/tasks/react_template_compile.js deleted file mode 100644 index 9db7800..0000000 --- a/server/lib/tasks/react_template_compile.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; -// through2 is a thin wrapper around node transform streams -import through from 'through2'; -import gutil from 'gulp-util'; -import rt from 'react-templates'; -import path from 'path'; -import extend from 'extend'; - -// Consts -const PLUGIN_NAME = 'gulp-react-templates'; -var PluginError = gutil.PluginError; - -function normalizeName(name) { - return name.replace(/-/g, '_'); -} - -export default function (opt) { - function replaceExtension(filePath) { - return filePath + '.js'; - } - - function transform(file, enc, cb) { - if (file.isNull()) { - return cb(null, file); - } - if (file.isStream()) { - return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported')); - } - - var filePath = file.path, - str = file.contents.toString('utf8'), - data; - - var options = extend({ - filename: file.path, - sourceFiles: [file.relative], - generatedFile: replaceExtension(file.relative) - }, opt); - - if (options.suffix && !options.name) { - options.name = normalizeName(path.basename(filePath, path.extname(filePath))) + options.suffix; - } - - try { - data = rt.convertTemplateToReact(str, options); - } catch (err) { - return cb(new PluginError(PLUGIN_NAME, err)); - } - - file.contents = new Buffer(data); - - file.path = replaceExtension(file.path); - cb(null, file); - } - - return through.obj(transform); -}; diff --git a/server/lib/tasks/seed_data.js b/server/lib/tasks/seed_data.js deleted file mode 100644 index 1732dd0..0000000 --- a/server/lib/tasks/seed_data.js +++ /dev/null @@ -1,103 +0,0 @@ -import extend from "extend"; -import moment from "moment"; -import csv from "fast-csv"; -import fs from 'fs'; -import MathUtils from "./../../../shared/utils/math" -import DB from './../../config/database'; - -const DATA_PATH = __dirname + '/../../../shared/data/' - -export class PowerDataSeed { - - static saveCsv(opts, done){ - opts = extend({ - path: DATA_PATH + "power_data.csv" - }, opts || {}); - var stream = fs.createReadStream(opts.path), - csvStream = csv.fromStream(stream, {headers: ['house_id', 'time', 'consumption', 'production']}), - rows = []; - - csvStream.on("data", function(data){ - data.time = data.time; - rows.push(data); - if (rows.length % 100 === 0){ - DB.PowerDatum.bulkCreate(rows, {validate: true}).catch((error)=>{ - console.error(JSON.stringify(error)); - console.error(JSON.stringify(rows)); - }); - rows = []; - } - }); - csvStream.on("end", function(){ - console.log("all rows parsed") - DB.PowerDatum.bulkCreate(rows, {validate: true}).then(()=>{ - return DB.House.findAll().then((houses)=>{ - var promises = []; - for (var house of houses){ - var p = house.aggregatePowerToEnergyData(); - promises.push(p); - } - return Promise.all(promises); - }); - }).then(()=>{ - console.log("DONE!") - }); - }); - } - - static generateCsv(opts, done){ - opts = extend({ - start_date: moment().subtract(120, "months").unix(), - end_date: moment().unix(), - interval: 900, // every 15 minutes (in s) - average: 1400, // Wh - path: DATA_PATH + "power_data.csv" - }, opts || {}); -console.log(opts.start_date, opts.end_date) - var row_date = opts.start_date, - csvStream = csv.format({headers: true}), - writableStream = fs.createWriteStream(opts.path), - house_ids = opts.house_ids.split(",") - - DB.House.findAll({where: {id: house_ids}}).then((houses)=>{ - - csvStream.pipe(writableStream); - writableStream.on("finish", ()=>{ - console.log("DONE!") - done(); - }); - - while (row_date <= opts.end_date){ - for (var house of houses){ - var consumption = MathUtils.normal(opts.average), - production = MathUtils.normal(opts.average) * house.productionMultiplier(row_date * 1000); - csvStream.write([house.id, row_date, consumption, production]); - } - row_date += opts.interval; - } - csvStream.end(); - }); - } -} - -export class HouseSeed { - static saveCsv(opts, done){ - opts = extend({ - path: DATA_PATH + "houses.csv" - }, opts || {}); - var stream = fs.createReadStream(opts.path), - csvStream = csv.fromStream(stream, {headers: ['id', 'name', 'timezone']}), - rows = []; - - csvStream.on("data", function(data){ - rows.push(data); - }); - csvStream.on("end", function(){ - console.log(rows); - DB.House.bulkCreate(rows, {validate: true}).then(()=>{ - console.log("DONE!") - done(); - }); - }); - } -} diff --git a/server/models/energy_datum.js b/server/models/energy_datum.js deleted file mode 100644 index 1521c1a..0000000 --- a/server/models/energy_datum.js +++ /dev/null @@ -1,52 +0,0 @@ -import DB from "./../config/database"; -import extend from 'extend'; -import ApiHelper from './../helpers/api_helper'; - -const NAME = 'EnergyDatum'; - -/** - * Define your own types here - */ - -var EnergyDatum = DB.sequelize.define(NAME, { - id: { - type: DB.Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true // Automatically gets converted to SERIAL for postgres - }, - day: { - type: DB.Sequelize.INTEGER, - }, - production: DB.Sequelize.FLOAT, - consumption: DB.Sequelize.FLOAT -}, { - paranoid: true, - underscored: true, - tableName: "energy_data", - instanceMethods: {}, - classMethods: { - set: ()=>{ - EnergyDatum.associate(); - }, - associate: ()=>{ - EnergyDatum.belongsTo(DB.House); - }, - exposeForHouseAtDates: (house_id, dates)=>{ - var params = {house_id: house_id}; - extend(params, ApiHelper.datesParamToSequelize(dates, 'day')); - console.log('EnergyDatum#exposeForHouseAtDates') - console.log(params, dates) - return EnergyDatum.findAll({ - where: params, - attributes: ['id', 'production', 'consumption', 'day'] - }).then((energy_data)=>{ - return energy_data.map((energy_datum)=>{ - return energy_datum.dataValues; - }); - }); - } - } -}); - -EnergyDatum.NAME = NAME; -module.exports = EnergyDatum; diff --git a/server/models/house.js b/server/models/house.js deleted file mode 100644 index 2700180..0000000 --- a/server/models/house.js +++ /dev/null @@ -1,93 +0,0 @@ -import moment from 'moment-timezone'; -import DB from "./../config/database"; - -const NAME = 'House'; - -/** - * Sequelize Definition - */ - -var House = DB.sequelize.define(NAME, { - id: { - type: DB.Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true // Automatically gets converted to SERIAL for postgres - }, - timezone: DB.Sequelize.STRING, - name: DB.Sequelize.STRING, - data_until: { - type: DB.Sequelize.INTEGER, - }, - data_from: { - type: DB.Sequelize.INTEGER, - } -}, { - paranoid: true, - underscored: true, - tableName: "houses", - instanceMethods: { - productionMultiplier: function(timestamp){ - var house = this, - minute = moment.tz(timestamp, house.timezone).hour() * 60 + moment.tz(timestamp, house.timezone).minute(), - multiplier = 0; - if (minute > 420 && minute < 1140){ - multiplier = 1 - Math.abs(780 - minute) / 360; - } - return multiplier; - }, - unixToLocalDay: function(unix){ - var house = this; - return moment.tz(unix * 1000, house.timezone).startOf('day').unix(); - }, - aggregatePowerToEnergyData: function(){ - var house = this; - return DB.EnergyDatum.destroy({where: {house_id: house.id}}) - .then(()=>{ - return DB.PowerDatum.count({where: {house_id: house.id}}) - }) - .then((count)=>{ - var limit = 0, - energy_data = new Map(), - promises = []; - while (limit < count){ - let complete = DB.PowerDatum.findAll({where: {house_id: house.id}, limit: 1000, offset: limit, order: 'id ASC'}) - .then((power_data)=>{ - power_data.forEach((power_datum)=>{ - var day = house.unixToLocalDay(power_datum.time), - energy_datum = energy_data.get(day) || {production: 0, consumption: 0, day: day, house_id: house.id}; - energy_datum.production += power_datum.production / 1000; // convert Wh to kWh - energy_datum.consumption += power_datum.consumption / 1000; // convert Wh to kWh - energy_data.set(day, energy_datum); - }); - }); - promises.push(complete); - limit += 1000; - } - return Promise.all(promises).then(()=>{ - return DB.EnergyDatum.bulkCreate(Array.from(energy_data.values()), {validate: true}); - }); - }) - .then(()=>{ - return house.getPowerData({order: 'time DESC', limit: 1}); - }) - .then((max_data)=>{ - house.data_until = max_data[0].time; - return house.getPowerData({order: 'time ASC', limit: 1}); - }).then((min_data)=>{ - house.data_from = min_data[0].time; - return house.save(); - }); - } - }, - classMethods: { - set: ()=>{ - House.associate(); - }, - associate: ()=>{ - House.hasMany(DB.PowerDatum, {as: 'PowerData'}); - } - } -}); - -House.NAME = NAME; -module.exports = House; diff --git a/server/models/power_datum.js b/server/models/power_datum.js deleted file mode 100644 index 642a073..0000000 --- a/server/models/power_datum.js +++ /dev/null @@ -1,59 +0,0 @@ -import DB from "./../config/database"; -import extend from 'extend'; -import ApiHelper from './../helpers/api_helper'; - -const NAME = 'PowerDatum'; - -/** - * Define your own types here - */ - -var PowerDatum = DB.sequelize.define(NAME, { - id: { - type: DB.Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true // Automatically gets converted to SERIAL for postgres - }, - time: { - type: DB.Sequelize.INTEGER, - }, - consumption: DB.Sequelize.FLOAT, - production: DB.Sequelize.FLOAT -}, { - paranoid: true, - underscored: true, - tableName: "power_data", - instanceMethods: { - exposeToApi: function(){ - var power_datum = this, - data = power_datum.dataValues; - data.consumption = data.consumption * 4; // convert Wh / 15 minutes, to W - data.production = data.production * 4; // convert Wh / 15 minutes, to W - return data; - } - }, - classMethods: { - exposeForHouseAtDates: (house_id, dates)=>{ - var params = {house_id: house_id}; - params = extend(params, ApiHelper.datesParamToSequelize(dates, 'time')); - console.log(params); - return PowerDatum.findAll({ - where: params, - attributes: ['id', 'production', 'consumption', 'time'] - }).then((power_data)=>{ - return power_data.map((power_datum)=>{ - return power_datum.exposeToApi(); - }); - }); - }, - set: ()=>{ - PowerDatum.associate(); - }, - associate: ()=>{ - PowerDatum.belongsTo(DB.House); - } - } -}); - -PowerDatum.NAME = NAME; -module.exports = PowerDatum; diff --git a/server/public/favicon.ico b/server/public/favicon.ico deleted file mode 100644 index 127c0d9f8e80da40f64df92096c826eb737f6399..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmaizIZs|hpw+3~_AdP0;c zfp~*Ry_=zG>WSw{4oj2dynYm-7^6<;gS9rctf!9jCRZ6{wV1nh@ zjzuYa`}XEpdjH~4US6(hYiq4oT{fHTQ(cN=r-K6%`fMl9CdW zyuQ9x+=Dg1rpwC8?rUmlq_VP7ii?W{{^EAKrLC<^T3cK1tE#Fp4u``ab9Hs4TrQXL zdc6khmv*~d5JT$g>!qWkLk0&2rLnP57_X(JMb_5Vq@kffs;jHN^!N80h^c%&p9S$U zPN!3vo0~ODp6@+9Ju)>lC3ACgvbwq|>2z9_mX>5@W=3XbXOlS30$(?B&q9J+G~dFn&(_d(Y0_dlYCk`sH@-Q8{O*^5vpB!`EGI){~&6#=8alSK_TWU%UfkB*K?EEbc2 zfdReew`eqKp1-`jtnKvg>+8FTL?R!ChK9618P>*n(O=UxJw2`YlamvP$K$3Q^Kk)R z7i@QkBjIpZi~hWG<}xxeA`1%(LN>?K4&6a6%!dW}rI{mULN+%yWov6o-~GhIgiy>m z$MgMrvJXsmkin8qOu8i diff --git a/server/public/index2.html b/server/public/index2.html deleted file mode 100644 index 5a28fda..0000000 --- a/server/public/index2.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - Spike Prototype - - -
-
- -
-
- -
- - - - - - diff --git a/server/routes.js b/server/routes.js deleted file mode 100644 index 3502aa6..0000000 --- a/server/routes.js +++ /dev/null @@ -1,11 +0,0 @@ -import Controllers from './config/controllers' - -export default function(app){ - - Controllers.sync(); - - app.use('/data/v1/power', Controllers.PowerController.index); - app.use('/data/v1/energy', Controllers.EnergyController.index); - app.use('/data/v1/houses', Controllers.HousesController.index); - -}; diff --git a/server/views/error.jade b/server/views/error.jade deleted file mode 100644 index 51ec12c..0000000 --- a/server/views/error.jade +++ /dev/null @@ -1,6 +0,0 @@ -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/server/views/index.jade b/server/views/index.jade deleted file mode 100644 index a3f3ff4..0000000 --- a/server/views/index.jade +++ /dev/null @@ -1,3 +0,0 @@ -extends layout -block content - div(id="root") diff --git a/server/views/layout.jade b/server/views/layout.jade deleted file mode 100644 index 3dc3b6b..0000000 --- a/server/views/layout.jade +++ /dev/null @@ -1,34 +0,0 @@ -doctype html -html - head - meta(charset='utf-8') - meta(http-equiv='content-type', content='text/html; charset=UTF-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - title Spike Prototype - body - #spike_container - #spike_content - nav.navbar.navbar-default(style='margin-bottom:0px;') - .container - .navbar-header - button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#navbar', aria-expanded='false', aria-controls='navbar') - span.sr-only Toggle navigation - span.icon-bar - span.icon-bar - span.icon-bar - a.navbar-brand(href='/') Spike - #navbar.collapse.navbar-collapse - ul.nav.navbar-nav.navbar-right - li - a(href='/') Spike - .container - block content - #spike_footer - .container Footer - script(type='text/javascript'). - // Force `fetch` polyfill to workaround Chrome not displaying request body - // in developer tools for the native `fetch`. - self.fetch = null; - script(src='http://localhost:3000/webpack-dev-server.js') - script(src='/assets/style.js') - script(src='/assets/app.js') diff --git a/shared/models/house.js b/shared/models/house.js deleted file mode 100644 index 8910627..0000000 --- a/shared/models/house.js +++ /dev/null @@ -1,10 +0,0 @@ -import moment from 'moment'; - -class House { - - timeToDateString(timestamp){ - var house = this; - return moment.tz(timestamp, house.timezone).format("YYYY-MM-DD"); - } - -} diff --git a/shared/utils/array.js b/shared/utils/array.js deleted file mode 100644 index bc333bf..0000000 --- a/shared/utils/array.js +++ /dev/null @@ -1,28 +0,0 @@ -class ArrayUtil { - - static diff(a1, a2){ - return a1.filter((a1n)=>{ return a2.indexOf(a1n) < 0; }); - } - - static selectMap(a, fnSelect, fnMap){ - var map = []; - for (var elem of a){ - if (fnSelect(elem)) map.push(fnMap(elem)); - } - return map; - } - - static all(a, fnCondition){ - var all = true; - for (var elem of a){ - if (!fnCondition(elem)){ - all = false; - break; - } - } - return all; - } - -} - -export default ArrayUtil; diff --git a/shared/utils/date_range.js b/shared/utils/date_range.js deleted file mode 100644 index 04be8e1..0000000 --- a/shared/utils/date_range.js +++ /dev/null @@ -1,68 +0,0 @@ -class DateRange { - - static addRange(new_range, ranges){ - var gaps_filled = [], new_ranges = [], - start = new_range[0], end = new_range[1]; - if (start === undefined && end === undefined && ranges.length === 0){ - gaps_filled = [undefined, undefined]; - new_ranges = [[undefined, undefined]]; - } else { - var covered = false, - last_start = start, - last_end = start; - - ranges.forEach((range, i)=>{ - if (covered){ new_ranges.push(range); return true; } - if (DateRange.lte(start, range[0])){ - if (end && !DateRange.eq(end, range[0]) && DateRange.lte(end, range[0])){ - new_ranges.push([last_start, end]); - new_ranges.push(range); - gaps_filled.push([last_end, end]); - covered = true; - } else if (end && !DateRange.gte(end, range[1])) { - new_ranges.push([last_start, range[1]]); - if (range[0] && !DateRange.eq(last_end, range[0])){ gaps_filled.push([last_end, range[0]]); } - covered = true - } else { - if (range[0] && !DateRange.eq(last_end, range[0])) gaps_filled.push([last_end, range[0]]); - last_end = range[1] - } - } else if (start && DateRange.gte(range[1], start)){ - if (!DateRange.eq(end, range[1]) && DateRange.gte(end, range[1])){ - last_start = range[0]; - last_end = range[1]; - } else { - new_ranges.push(range); - covered = true; - } - } else { new_ranges.push(range); } - }); - if (!covered) { - new_ranges.push([last_start, end]); - if (!DateRange.eq(last_end, end)) gaps_filled.push([last_end, end]); - } - } - - return { gaps_filled: gaps_filled, new_ranges: new_ranges } - } - - static gte(date1, date2){ - return (date1 === undefined || (date2 !== undefined && date1 >= date2)); - } - - static lte(date1, date2){ - return (date1 === undefined || (date2 !== undefined && date1 <= date2)); - } - - static eq(date1, date2){ - if (date1 && date1.constructor === Date) date1 = date1.getTime(); - if (date2 && date2.constructor === Date) date2 = date2.getTime(); - return (date1 !== undefined && date2 !== undefined && date1 === date2) || date1 === undefined && date2 === undefined - } - - static add(date, s){ - return new Date(date.getTime() + s); - } - -} -export default DateRange; diff --git a/shared/utils/math.js b/shared/utils/math.js deleted file mode 100644 index b626ed1..0000000 --- a/shared/utils/math.js +++ /dev/null @@ -1,38 +0,0 @@ -export default class { - - static normal(average){ - return average + this.n6() * average; - } - - static n6(){ - return ((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3; - } - - // min_max1 and min_max2 arrays of length two representing mins and maxes of their ranges; - // returns array of array length two, representing mins and maxes not within min_max2. - static minusRange(min_max1, min_max2){ - var minus = []; - - // return undefined if min_max1 not provided - if (!min_max1 || (!min_max1[0] && !min_max2[1])) return undefined; - - if (min_max1[0] >= min_max2[0]){ - if (min_max1[1] > min_max2[1]) minus.push([min_max2[1], min_max1[1]]); - } else if (min_max1[1] <= min_max2[1]){ - if (min_max1[0] < min_max2[0]) minus.push([min_max1[0], min_max2[0]]); - } else if (min_max1[0] < min_max2[0] && min_max1[1] > min_max2[1]){ - minus.push([min_max1[0], min_max2[0]]); - minus.push([min_max2[1], min_max1[1]]); - } else { - minus.push([min_max1[0], min_max1[1]]); - } - return minus; - } - - static inRange(n, min_max){ - var min = min_max[0], - max = min_max[1]; - return ((n >= min) && (n <= max)); - } - -} diff --git a/spec/shared/utils/date_range.test.js b/spec/shared/utils/date_range.test.js deleted file mode 100644 index cbe3dea..0000000 --- a/spec/shared/utils/date_range.test.js +++ /dev/null @@ -1,424 +0,0 @@ -"use strict"; - -import DateRange from './../../../shared/utils/date_range.js'; - -describe('DateRange.gte', ()=>{ - - it('considers undefined as a large date', ()=>{ - var date1 = new Date(), - date2 = new Date(date1.getTime() + 1000); - expect(DateRange.gte(undefined, date1)).toEqual(true); - expect(DateRange.gte(undefined, undefined)).toEqual(true); - expect(DateRange.gte(date1, undefined)).toEqual(false); - expect(DateRange.gte(date1, date2)).toEqual(false); - expect(DateRange.gte(date2, date1)).toEqual(true); - }); -}); - - -describe('DateRange.lte', ()=>{ - it('considers undefined as a small date', ()=>{ - var date1 = new Date(), - date2 = new Date(date1.getTime() + 1000); - expect(DateRange.lte(undefined, date1)).toEqual(true); - expect(DateRange.lte(undefined, undefined)).toEqual(true); - expect(DateRange.lte(date1, undefined)).toEqual(false); - expect(DateRange.lte(date1, date2)).toEqual(true); - expect(DateRange.lte(date2, date1)).toEqual(false); - }); -}); - -describe('DateRange.addRange', ()=>{ - var date1 = new Date(), - date01 = DateRange.add(date1, -1000), - date11 = DateRange.add(date1, 1000), - date2 = DateRange.add(date1, 2000), - date21 = DateRange.add(date2, 1000), - date3 = DateRange.add(date2, 2000), - date31 = DateRange.add(date3, 1000), - date4 = DateRange.add(date3, 2000), - date41 = DateRange.add(date4, 1000), - date5 = DateRange.add(date4, 2000), - date51 = DateRange.add(date5, 1000), - date6 = DateRange.add(date5, 2000), - date61 = DateRange.add(date6, 1000), - date7 = DateRange.add(date6, 2000), - date71 = DateRange.add(date7, 1000); - - describe('no ranges exist', ()=>{ - it('returns the new ranges', ()=>{ - var result = DateRange.addRange([date1, date2], []); - expect(result.gaps_filled).toEqual([[date1, date2]]); - expect(result.new_ranges).toEqual([[date1, date2]]); - }); - }); - - describe('infinite range exists', ()=>{ - it('returns the infinite range, no gaps filled', ()=>{ - var result = DateRange.addRange([date1, date2], [[undefined, undefined]]); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[undefined, undefined]]); - }); - }); - - describe('-Infinity to definite date exists', ()=>{ - describe('with gaps', ()=>{ - var ranges = [[undefined, date1], [date2, date3], [date4, date5]]; - - describe('new range low low', ()=>{ - var new_range = [undefined, date01]; - it('no gaps filled', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]) - expect(result.new_ranges).toEqual(ranges); - }); - }); - - describe('new range low mid', ()=>{ - var new_range = [undefined, date31]; - it('fills mid gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date1, date2], [date3, date31]]); - expect(result.new_ranges).toEqual([[undefined, date31], [date4, date5]]); - }); - }); - - describe('new range low high', ()=>{ - var new_range = [undefined, date61]; - it('fills mid and high gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date1, date2], [date3, date4], [date5, date61]]); - expect(result.new_ranges).toEqual([[undefined, date61]]); - }); - }); - - - describe('new range mid mid', ()=>{ - var new_range = [date11, date41]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date11, date2], [date3, date4]]) - expect(result.new_ranges).toEqual([[undefined, date1], [date11, date5]]); - }); - }); - - describe('new range mid high', ()=>{ - var new_range = [date11, date61]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date11, date2], [date3, date4], [date5, date61]]); - expect(result.new_ranges).toEqual([[undefined, date1], [date11, date61]]); - }); - }); - - describe('new range high high', ()=>{ - var new_range = [date5, date61]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date5, date61]]); - expect(result.new_ranges).toEqual([[undefined, date1], [date2, date3], [date4, date61]]); - }); - }); - - }); - - describe('no gaps', ()=>{ - var ranges = [[undefined, date1]]; - - describe('new range low low', ()=>{ - var new_range = [undefined, date01]; - it('no gaps filled', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]) - expect(result.new_ranges).toEqual([[undefined, date1]]); - }); - }); - - describe('new range low mid', ()=>{ - var new_range = [undefined, date1]; - it('fills mid gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[undefined, date1]]); - }); - }); - - describe('new range low high', ()=>{ - var new_range = [undefined, date61]; - it('fills mid and high gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date1, date61]]); - expect(result.new_ranges).toEqual([[undefined, date61]]); - }); - }); - - - describe('new range mid mid', ()=>{ - var new_range = [date01, date1]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]) - expect(result.new_ranges).toEqual([[undefined, date1]]); - }); - }); - - describe('new range mid high', ()=>{ - var new_range = [date1, date61]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date1, date61]]); - expect(result.new_ranges).toEqual([[undefined, date61]]); - }); - }); - - describe('new range high high', ()=>{ - var new_range = [date5, date61]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date5, date61]]); - expect(result.new_ranges).toEqual([[undefined, date1], [date5, date61]]); - }); - }); - }); - }); - - describe('definite to Infinity range exists', ()=>{ - describe('with gaps', ()=>{ - var ranges = [[date1, date2], [date3, date4], [date5, undefined]]; - - describe('new range low low', ()=>{ - var new_range = [undefined, date01]; - it('no gaps filled', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date01]]); - expect(result.new_ranges).toEqual([[undefined, date01], [date1, date2], [date3, date4], [date5, undefined]]); - }); - }); - - describe('new range low mid', ()=>{ - var new_range = [undefined, date3]; - it('fills mid gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1], [date2, date3]]); - expect(result.new_ranges).toEqual([[undefined, date4], [date5, undefined]]); - }); - }); - - describe('new range low high', ()=>{ - var new_range = [undefined, date61]; - it('fills mid and high gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1], [date2, date3], [date4, date5]]); - expect(result.new_ranges).toEqual([[undefined, undefined]]); - }); - }); - - describe('new range mid mid', ()=>{ - var new_range = [date1, date41]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date2, date3], [date4, date41]]); - expect(result.new_ranges).toEqual([[date1, date41], [date5, undefined]]); - }); - }); - - describe('new range mid high', ()=>{ - var new_range = [date31, date61]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date4, date5]]); - expect(result.new_ranges).toEqual([[date1, date2], [date3, undefined]]); - }); - }); - - describe('new range high high', ()=>{ - var new_range = [date5, date61]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[date1, date2], [date3, date4], [date5, undefined]]); - }); - }); - }); - - describe('no gaps', ()=>{ - var ranges = [[date1, undefined]]; - - describe('new range low low', ()=>{ - var new_range = [undefined, date01]; - it('no gaps filled', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date01]]); - expect(result.new_ranges).toEqual([[undefined, date01], [date1, undefined]]); - }); - }); - - describe('new range low mid', ()=>{ - var new_range = [undefined, date1]; - it('fills mid gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1]]); - expect(result.new_ranges).toEqual([[undefined, undefined]]); - }); - }); - - describe('new range low high', ()=>{ - var new_range = [undefined, date61]; - it('fills mid and high gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1]]); - expect(result.new_ranges).toEqual([[undefined, undefined]]); - }); - }); - - describe('new range mid mid', ()=>{ - var new_range = [date1, date1]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[date1, undefined]]); - }); - }); - - describe('new range mid high', ()=>{ - var new_range = [date1, undefined]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[date1, undefined]]); - }); - }); - - describe('new range high high', ()=>{ - var new_range = [date5, undefined]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[date1, undefined]]); - }); - }); - - }); - }); - - describe('definite range exists', ()=>{ - describe('with gaps', ()=>{ - var ranges = [[date1, date2], [date3, date4], [date5, date6]]; - - describe('new range low low', ()=>{ - var new_range = [undefined, date01]; - it('no gaps filled', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date01]]); - expect(result.new_ranges).toEqual([[undefined, date01], [date1, date2], [date3, date4], [date5, date6]]); - }); - }); - - describe('new range low mid', ()=>{ - var new_range = [undefined, date41]; - it('fills mid gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1], [date2, date3], [date4, date41]]); - expect(result.new_ranges).toEqual([[undefined, date41], [date5, date6]]); - }); - }); - - describe('new range low high', ()=>{ - var new_range = [undefined, date61]; - it('fills mid and high gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1], [date2, date3], [date4, date5], [date6, date61]]); - expect(result.new_ranges).toEqual([[undefined, date61]]); - }); - }); - - describe('new range mid mid', ()=>{ - var new_range = [date11, date41]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date2, date3], [date4, date41]]); - expect(result.new_ranges).toEqual([[date1, date41], [date5, date6]]); - }); - }); - - describe('new range mid high', ()=>{ - var new_range = [date31, undefined]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date4, date5], [date6, undefined]]); - expect(result.new_ranges).toEqual([[date1, date2], [date3, undefined]]); - }); - }); - - describe('new range high high', ()=>{ - var new_range = [date61, undefined]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date61, undefined]]); - expect(result.new_ranges).toEqual([[date1, date2], [date3, date4], [date5, date6], [date61, undefined]]); - }); - }); - - }); - - describe('no gaps', ()=>{ - var ranges = [[date1, date2]]; - - describe('new range low low', ()=>{ - var new_range = [undefined, date01]; - it('no gaps filled', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date01]]); - expect(result.new_ranges).toEqual([[undefined, date01], [date1, date2]]); - }); - }); - - describe('new range low mid', ()=>{ - var new_range = [undefined, date11]; - it('fills mid gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1]]); - expect(result.new_ranges).toEqual([[undefined, date2]]); - }); - }); - - describe('new range low high', ()=>{ - var new_range = [undefined, date61]; - it('fills mid and high gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[undefined, date1], [date2, date61]]); - expect(result.new_ranges).toEqual([[undefined, date61]]); - }); - }); - - describe('new range mid mid', ()=>{ - var new_range = [date11, date2]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([]); - expect(result.new_ranges).toEqual([[date1, date2]]); - }); - }); - - describe('new range mid high', ()=>{ - var new_range = [date11, undefined]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date2, undefined]]); - expect(result.new_ranges).toEqual([[date1, undefined]]); - }); - }); - - describe('new range high high', ()=>{ - var new_range = [date61, undefined]; - it('includes gaps', ()=>{ - var result = DateRange.addRange(new_range, ranges); - expect(result.gaps_filled).toEqual([[date61, undefined]]); - expect(result.new_ranges).toEqual([[date1, date2], [date61, undefined]]); - }); - }); - - }); - }); - -}); diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json deleted file mode 100644 index bcaf67b..0000000 --- a/spec/support/jasmine.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "spec_dir": "spec", - "spec_files": [ - "**/*.test.js" - ], - "helpers": [ - "../node_modules/babel-core/register.js", - "helpers/**/*.js" - ], - "stopSpecOnExpectationFailure": false, - "random": false -}