-
Notifications
You must be signed in to change notification settings - Fork 0
/
Variable.js
67 lines (61 loc) · 1.61 KB
/
Variable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import React from "react";
import {XYPlot, XAxis, YAxis, HorizontalGridLines, LineSeries, MarkSeries} from 'react-vis';
import "./Variable.css";
const graphSteps = 50;
const stepsRange = range(graphSteps);
function range(n) {
return [...new Array(n).keys()];
}
const Variable = ({ displayName, values, onChange, name, fn, min, max }) => {
const value = values[name];
const y = fn({ ...values, [name]: value });
const graphStepSize = (max - min) / graphSteps;
const xValues = stepsRange.map(i => min + i * graphStepSize);
const chartData = calculateSeries({
values,
name,
fn,
xValues
});
return (
<div className="Variable">
<label>
{displayName}:
<br />
<XYPlot
width={600}
height={200}>
<HorizontalGridLines />
<XAxis />
<YAxis />
<LineSeries data={chartData} style={{ fill: 'none' }}/>
<MarkSeries data={[{ x: value, y }]} />
</XYPlot>
<input
type="range"
value={value}
min={min}
max={max}
step="any"
onChange={e => onChange(name, parseFloat(e.target.value))}
/>
<input
type="number"
value={value}
min={min}
max={max}
step={graphStepSize}
onChange={e => onChange(name, parseFloat(e.target.value))}
/>
</label>
</div>
);
};
function calculateSeries({ name, values, fn, xValues }) {
const fnInput = { ...values };
return xValues.map(x => {
fnInput[name] = x;
return { x, y: fn(fnInput) };
});
}
export default Variable;