Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 3000x 3000x 3000x 3000x 3000x 3000x 2999x 2999x 2999x 6x 6x 6x 1x 3000x 3000x 3000x 3000x 3000x 3000x 3000x 3000x 3000x 3000x 1x 6x 6x | import { Parser, Expression } from "expr-eval"
import { scaleLinear, scaleLog } from "d3-scale"
import { ScaleType } from "../core/GrapherConstants"
export function generateComparisonLinePoints(
lineFunction: string = "x",
xScaleDomain: [number, number],
yScaleDomain: [number, number],
xScaleType: ScaleType,
yScaleType: ScaleType
): [number, number][] {
const expr = parseEquation(lineFunction)?.simplify({
e: Math.E,
pi: Math.PI,
})
const yFunc = (x: number): number | undefined =>
evalExpression(expr, { x }, undefined)
// Construct control data by running the equation across sample points
const numPoints = 500
const scaleFunction = xScaleType === ScaleType.log ? scaleLog : scaleLinear
const scale = scaleFunction().domain(xScaleDomain).range([0, numPoints])
const controlData: Array<[number, number]> = []
for (let i = 0; i < numPoints; i++) {
const x = scale.invert(i)
const y = yFunc(x)
if (y === undefined || Number.isNaN(x) || Number.isNaN(y)) continue
if (xScaleType === ScaleType.log && x <= 0) continue
if (yScaleType === ScaleType.log && y <= 0) continue
if (y > yScaleDomain[1]) continue
controlData.push([x, y])
}
return controlData
}
function evalExpression<D>(
expr: Expression | undefined,
context: Record<string, number>,
defaultOnError: D
): number | D {
if (expr === undefined) return defaultOnError
try {
return expr.evaluate(context) as number
} catch (e) {
return defaultOnError
}
}
function parseEquation(equation: string): Expression | undefined {
try {
return Parser.parse(equation)
} catch (e) {
console.error(e)
return undefined
}
}
|