Skip to content

Commit

Permalink
make targets editable (<input type="number" />s)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryan-williams committed Oct 4, 2023
1 parent eb119a5 commit b73f033
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 17 deletions.
19 changes: 16 additions & 3 deletions pages/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@
.activeRegion {
background-color: #eee;
}
.negativeKey {
background-color: #fcc;
}

.grid {
width: 100%;
Expand Down Expand Up @@ -260,8 +263,10 @@
max-height: 1em;
text-align: right;
}
th.goalHeading {
//padding-right: 0.8em;
}
td.sparkNum {
//width: 5em;
min-width: 5em;
max-width: 5em;
overflow: hidden;
Expand All @@ -273,12 +278,20 @@
td.val {
min-width: 3em;
max-width: 3em;
overflow: hidden;
text-align: right;
span {
width: 100%;
}
}
td.targetVal {
//padding-right: 0;
input {
background-color: transparent;
text-align: right;
width: 100%;
border: none;
//padding-right: 0;
}
}
}
}

Expand Down
15 changes: 9 additions & 6 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ const ThreeEqualCircles: Target[] = [
]

const FizzBuzz: Target[] = [
[ "0*", 1/3 ],
[ "*1", 1/5 ],
[ "01", 1/15 ],
[ "0*", 5 ],
[ "*1", 3 ],
[ "01", 1 ],
]

const FizzBuzzBazz: Target[] = [ // Fractions scaled up by LCM
Expand Down Expand Up @@ -451,14 +451,12 @@ export function Body() {
(shapes: Shapes, targets: Targets, push: boolean) => {
if (stateInUrlFragment) {
const param = { shapes, precisionSchemeId: urlShapesPrecisionScheme }
// setUrlFragmentTargets(targets)
// setUrlFragmentShapes(param)
const newHashMap = { s: param, t: targets, }
if (historyLog) console.log(`history push (${push ? "push" : "replace"}, ${targets.numShapes}, ${shapes.length}`, newHashMap)
updateHashParams(params, newHashMap, { push, log: historyLog })
}
},
[ stateInUrlFragment, urlShapesPrecisionScheme, /*setUrlFragmentTargets, setUrlFragmentShapes, */]
[ stateInUrlFragment, urlShapesPrecisionScheme, ]
)

const [ curStep, sets, shapes, ] = useMemo(
Expand Down Expand Up @@ -1499,6 +1497,11 @@ export function Body() {
<TargetsTable
initialShapes={initialSets}
targets={rawTargets}
setTargets={newTargets => {
setTargets(newTargets)
setUrlFragmentTargets(newTargets)
pushHistoryState(shapes, newTargets, false)
}}
showDisjointSets={!rawTargets.givenInclusive}
curStep={curStep}
error={error}
Expand Down
80 changes: 72 additions & 8 deletions src/components/tables/targets.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
import {Model, Step} from "../../lib/regions";
import {Dual} from "apvd"
import React, {useCallback, useMemo, useState} from "react";
import React, {Dispatch, useCallback, useMemo, useState} from "react";
import css from "../../../pages/index.module.scss";
import {SparkLineCell, SparkLineProps, SparkNum} from "../spark-lines";
import {S} from "../../lib/shape";
import {abs} from "../../lib/math";
import {Targets} from "../../lib/targets";
import {makeTargets, Target, Targets} from "../../lib/targets";

export function getNegativeEntries(targets: Targets): Map<string, number> {
const entries: Target[] = []
targets
.exclusive
.filter(([ _, v ]) => v < 0)
.forEach(([ k, v ]) => {
entries.push([k, v])
const inclusiveKey = k.replaceAll('-', '*')
const inclusiveVal = targets.all.get(inclusiveKey)
if (inclusiveVal === undefined) {
throw Error(`getNegativeKeys: inclusiveVal === undefined for key ${inclusiveKey}`)
}
entries.push([ inclusiveKey, inclusiveVal ])
})
return new Map(entries)
}

export function TargetsTable(
{ initialShapes, targets, showDisjointSets, model, curStep, error, stepIdx, hoveredRegion, ...sparkLineProps }: {
{ initialShapes, targets, setTargets, showDisjointSets, model, curStep, error, stepIdx, hoveredRegion, ...sparkLineProps }: {
initialShapes: S[]
targets: Targets
setTargets: Dispatch<Targets>
showDisjointSets: boolean
model: Model
curStep: Step
Expand All @@ -20,6 +38,8 @@ export function TargetsTable(
} & SparkLineProps
) {
// console.log(`TargetsTable: ${initialShapes.length} shapes`)
const [ negativeEntries, setNegativeEntries ] = useState<Map<string, number> | null>(null)
const negativePropsEntries = useMemo(() => getNegativeEntries(targets), [ targets ])
const targetName = useCallback(
(key: string) =>
key.split('').map((ch: string, idx: number) => {
Expand Down Expand Up @@ -78,18 +98,62 @@ export function TargetsTable(
() => new Map(displayTargets.map(([ key, value ]) => [ key, value ])),
[ displayTargets, ],
)

const [ editingValue, setEditingValue ] = useState<[ string, string ] | null>(null)
const totalTargetArea = curStep.targets.total_area
const [ showTargetCurCol, setShowTargetCurCol ] = useState(false)
const { showSparkLines } = sparkLineProps
const cellProps = { model, stepIdx, ...sparkLineProps, }
const targetTableRows = displayTargets.map(([ key, value ]) => {
const name = targetName(key)
const err = curStep.errors.get(key)
const negativeKey = negativeEntries && negativeEntries.has(key) || negativePropsEntries.has(key)
const activeRegion = key == hoveredRegion || (!(hoveredRegion && targetsMap.has(hoveredRegion)) && regionContains(key, hoveredRegion))
return <tr className={activeRegion ? css.activeRegion : ''} key={key}>
<td className={css.val}>{name}</td>
<td className={css.val}>{value.toPrecision(3).replace(/\.?0+$/, '')}</td>
const className = negativeKey ? css.negativeKey : activeRegion ? css.activeRegion : ''
const valueStr =
editingValue && editingValue[0] == key
? editingValue[1]
: value.toPrecision(3).replace(/\.?0+$/, '')
return <tr className={className} key={key}>
<td className={`${css.val} ${negativeKey}`}>{name}</td>
<td className={`${css.val} ${css.targetVal}`}>
<input
onFocus={e => {
console.log("onFocus:", key, e)
setEditingValue([ key, e.target.value ])
}}
onBlur={e => {
console.log("onBlur:", key, e)
if (editingValue && editingValue[0] == key) {
setEditingValue(null)
}
}}
type={"number"}
value={valueStr}
onKeyDown={e => { e.stopPropagation() }}
onKeyUp={e => { e.stopPropagation() }}
onChange={e => {
const newValueStr = e.target.value
const newValue = parseFloat(newValueStr)
console.log("onChange:", key, newValueStr, newValue, "isNaN(newValue):", isNaN(newValue))
setEditingValue([ key, newValueStr ])
if (isNaN(newValue)) {
return
}
const entries: Target[] = showDisjointSets ? targets.exclusive : targets.inclusive
const newEntries: Target[] = entries.map(([k, v]) => k == key ? [k, newValue] : [k, v])
const newTargets = makeTargets(newEntries)
const newNegativeEntries = getNegativeEntries(newTargets)
if (newNegativeEntries.size) {
console.log("negative entries:", newNegativeEntries)
setNegativeEntries(newNegativeEntries)
} else {
setNegativeEntries(null)
}
console.log("newTargets:", newTargets)
setTargets(newTargets)
}}
/>
</td>
{
showTargetCurCol &&
<td className={css.val}>{
Expand All @@ -110,7 +174,7 @@ export function TargetsTable(
<thead>
<tr>
<th></th>
<th>Goal</th>
<th className={css.goalHeading}>Goal</th>
{showTargetCurCol && <th>Cur</th>}
<th style={{ textAlign: "center" }} colSpan={showSparkLines ? 2 : 1}>Error</th>
</tr>
Expand Down

0 comments on commit b73f033

Please sign in to comment.