diff --git a/frontend/src/components/Graph.js b/frontend/src/components/Graph.js index 13b1a7e..e88654e 100644 --- a/frontend/src/components/Graph.js +++ b/frontend/src/components/Graph.js @@ -4,17 +4,25 @@ function normalize(x, min, max) { return (x - min)/(max - min); } +function translator(minX, minY, maxX, maxY, width, height, top, left, bottom, right) { + return (x, y) => { + const normalized = [normalize(x, minX, maxX), normalize(y, minY, maxY)]; + const dataWidth = width - left - right; + const dataHeight = height - top - bottom; + console.log('translator',{x, y, minX, maxX, minY, maxY, normalized, dataWidth, dataHeight, top, left, bottom, right}); + return [normalized[0] * dataWidth + left, (((1 - normalized[1]) * dataHeight) + top)]; + } +} + +function colorFactory(i) { + const seed = (140 + i * 46); + const hue = seed % 360; + return `hsl(${hue}, 60%, 43%)`; +} + class Graph { view(vnode) { - const { title, width, height, margins, origin, maximums, data } = {...Graph.defaults, ...vnode.attrs}; - - const tx = (x, y) => { - const normalized = [normalize(x, origin[0], maximums[0]), normalize(y, origin[1], maximums[1])]; - const dataWidth = width - margins[1] - margins[3]; - const dataHeight = height - margins[0] - margins[2]; - console.log('tx',{x,y, normalized}); - return [normalized[0] * dataWidth + margins[3], ((1-normalized[1]) * dataHeight) + margins[0]]; - } + const { title, width, height, margins, datasets} = {...Graph.defaults, ...vnode.attrs}; return (
@@ -27,11 +35,23 @@ class Graph { { /* Left margin */ } - {data.map((datum, i) => { - const translated = tx(datum[0],datum[1]); - const [x, y] = tx(...datum); - console.log({translated, datum}); - return () + {datasets.map((userProps, i) => { + const props = {...Graph.datasetDefaults, ...userProps}; + const title = props.title ? props.title : `Dataset ${i}`; + const color = props.color ? props.color : colorFactory(i); + if (props.data.length == 0) return; + const hasX = props.data[0].length > 1; + const minX = props.minX ?? 0; + const maxX = props.maxX ?? hasX ? props.data.reduce((p,c) => Math.max(p, c[0]), 0) : props.data.length; + const minY = props.minY ?? 0; + const maxY = props.maxY ?? props.data.reduce((prev, current) => Math.max(prev, hasX ? current[1] : current[0]), 0); + const tx = translator(minX, minY, maxX, maxY, width, height, ...margins); + + const points = props.data.map((datum) => tx(...datum)); + const line = ( v.join(',')).join(' ')} />) + return [line, ...points.map(([x,y]) => ())] + + })}
@@ -43,9 +63,15 @@ Graph.defaults = { width: 100, height: 40, margins: [5, 3, 2, 3], // top right bottom left - origin: [0, 0], - maximums: [100, 100], - data: [[0,0], [100,0], [100, 100], [0, 100], [25,60]], + datasets: [], +} +Graph.datasetDefaults = { + title: null, + minY: null, + maxY: null, + minX: null, + maxX: null, + data: [], } export default Graph; \ No newline at end of file diff --git a/frontend/src/views/HistoryView.js b/frontend/src/views/HistoryView.js new file mode 100644 index 0000000..c1c78b9 --- /dev/null +++ b/frontend/src/views/HistoryView.js @@ -0,0 +1,44 @@ +import m from 'mithril'; +import Layout from '../components/Layout'; +import Graph from '../components/Graph'; + + + +const datasets = [ + { + title: "Foo", + data: [ + [0, 1], + [1, 2], + [2, 4], + [3, 5], + [4, 4], + ], + }, + { + title: "Bar", + data: [ + [0, 2], + [1, 3], + [2, 10], + ] + }, + { + title: 'Sin', + data: [...Array(100).keys()].map((i) => [i/10, Math.sin(i/10)+1]), + } +] + +class HistoryView { + view() { + const title = 'Recent Conditions'; + return ( + +

{title}

+ +
+ ) + } +} + +export default HistoryView; \ No newline at end of file