x labels and selected graph
parent
d021baf9ce
commit
999cfd433f
|
@ -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>
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue