x labels and selected graph

feature/frontend-charts
Kenneth Barbour 2020-07-26 19:18:07 -04:00
parent d021baf9ce
commit 999cfd433f
2 changed files with 48 additions and 3 deletions

View File

@ -9,7 +9,6 @@ function translator(minX, minY, maxX, maxY, width, height, top, left, bottom, ri
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)];
}
}
@ -20,13 +19,33 @@ function colorFactory(i) {
return `hsl(${hue}, 60%, 43%)`;
}
class GraphDatasetSelector {
view(vnode) {
const { options, selectedIndex, onSelect } = vnode.attrs;
return (<div class="tabs is-centered is-boxed">
<ul>
{options.map((v, i) => (
<li class={selectedIndex == i ? 'is-active' : ''}>
<a onclick={() => (onSelect(i))} style={`color: ${colorFactory(i)};`}>{v}</a>
</li>
))}
</ul>
</div>)
}
}
class Graph {
oninit(vnode) {
vnode.state.selected = 0;
}
view(vnode) {
const { title, width, height, margins, datasets} = {...Graph.defaults, ...vnode.attrs};
return (
<div class="Graph-container">
<GraphDatasetSelector onSelect={(i) => {vnode.state.selected = i;}} selectedIndex={vnode.state.selected} options={datasets.map((v)=>(v.title))} />
<svg width="100%" viewBox={`0 0 ${width} ${height}`}>
{title && <title>{title}</title>}
@ -47,11 +66,16 @@ class Graph {
const minY = props.minY ?? 0.95 * props.data.reduce((p,c) => Math.min(p, c[0]), props.data[0][(hasX ? 1 : 0)]);
const maxY = props.maxY ?? 1.05 * 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 isSelected = i == vnode.state.selected;
const datasetLabel = (
<button>Foo</button>
);
const points = props.data.map((datum) => tx(...datum));
const line = (<polyline fill="none" stroke={color} stroke-width='0.1' points={points.map((v) => v.join(',')).join(' ')} />)
const line = (<polyline fill="none" stroke={color} stroke-width={isSelected ? '0.3':'0.1'} points={points.map((v) => v.join(',')).join(' ')} />)
const yLabels = (props.yLabels.map((label) => {
if (!isSelected) return null;
const yPos = tx(0, label.position)[1];
return (
<>
@ -67,7 +91,23 @@ class Graph {
</>
);
}));
return [line, ...yLabels];
const xLabels = (props.xLabels.map((label) => {
if (!isSelected) return null;
const xPos = tx(label.position, 0)[0];
return (
<>
<text
x={xPos}
y={height - margins[2]}
dy="1"
text-anchor="middle"
style="font-size:1px; font-weight: normal; text-align: center;"
>{label.label}</text>
{label.line && <line x1={xPos} y1={margins[0]} x2={xPos} y2={height - margins[2]} stroke-width=".1" stroke="#00000033" />}
</>
)
}))
return [datasetLabel, line, ...yLabels, ...xLabels];
})}
</svg>

View File

@ -36,6 +36,11 @@ class HistoryView {
{ position: 20, label: '20'},
{ position: 0, label: '0', line: true},
],
xLabels: [
{ position: 0, label: '0'},
{ position: 3, label: '3', line: true},
{ position: 6, label: '6', line: true},
]
},
{
title: "Pressure",