feature/layout-updates #1
14
src/app.js
14
src/app.js
@ -64,7 +64,19 @@ const Audiogram =()=>
|
||||
<svg class="absolute top-0 w-full h-full overflow-visible stroke(blue-700 bold draw) opacity-50">${testMarksL}${testLinesL}</svg>
|
||||
<svg class="absolute top-0 w-full h-full overflow-visible stroke(red-700 bold draw) opacity-50">${testMarksR}${testLinesR}</svg>
|
||||
<svg class="absolute top-0 w-full h-full overflow-visible stroke(blue-700 2 draw)">${userMarksL}${userLinesL}</svg>
|
||||
<svg class="absolute top-0 w-full h-full overflow-visible stroke(red-700 2 draw)">${userMarksR}${userLinesR}</svg>`;
|
||||
<svg class="absolute top-0 w-full h-full overflow-visible stroke(red-700 2 draw)">${userMarksR}${userLinesR}</svg>
|
||||
<svg class="absolute top-0 w-full h-full overflow-visible" >
|
||||
<ellipse cx="0" cy="0" rx="5" ry="30" fill="url(#glow)"></ellipse>
|
||||
<ellipse cx="0" cy="0" rx="30" ry="5" fill="url(#glow)"></ellipse>
|
||||
<defs>
|
||||
<radialGradient id="glow">
|
||||
<stop stop-color="blue" stop-opacity="0.6" offset="0.0"></stop>
|
||||
<stop stop-color="blue" stop-opacity="0.3" offset="0.2"></stop>
|
||||
<stop stop-color="blue" stop-opacity="0.0" offset="1.0"></stop>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
React.render(html`
|
||||
|
64
src/store.js
64
src/store.js
@ -28,8 +28,6 @@ export const ColumnLookup =(inFrequency)=>
|
||||
/** @type {(freq:Store.TestFrequency, chan:number, user:boolean)=>Store.TestFrequencySample|undefined} */
|
||||
export const MarkGet =(freq, chan, user)=> freq[/** @type {Store.PlotKey} */ (`${user ? "User" : "Test"}${chan ? "R" : "L"}`)];
|
||||
|
||||
/** @type {(freq:Store.TestFrequency, chan:number, mark:Store.TestFrequencySample|undefined)=>Store.TestFrequencySample|undefined} */
|
||||
export const MarkSet =(freq, chan, mark)=> freq[ chan ? "UserR" : "UserL" ] = mark;
|
||||
|
||||
/** @type {Store.State} */
|
||||
export const Initial =
|
||||
@ -67,47 +65,37 @@ export const Initial =
|
||||
]
|
||||
};
|
||||
|
||||
/** @type {Record<string, Store.ContextUpdater>} */
|
||||
const Update =
|
||||
|
||||
/** @type {(inState:Store.State, inTest?:Store.Test)=>Store.Context} */
|
||||
const Reselect =(inState, inTest)=>
|
||||
{
|
||||
Freq(inState)
|
||||
{
|
||||
/** @type {Store.Context} */
|
||||
const output = { Test:inTest??inState.Live.Test };
|
||||
const column = ColumnMapping[inState.Freq.Value];
|
||||
if(column && inState.Live.Test)
|
||||
{
|
||||
const hz = column[0];
|
||||
inState.Live.Freq = undefined;
|
||||
for(let i=0; i<inState.Live.Test.Plot.length; i++)
|
||||
{
|
||||
const plot = inState.Live.Test.Plot[i];
|
||||
if(plot.Hz == hz)
|
||||
{
|
||||
inState.Live.Freq = plot;
|
||||
return true;
|
||||
output.Freq = plot;
|
||||
output.Mark = plot[`User${inState.Chan.Value ? "R" : "L"}`];
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
Mark(inState)
|
||||
{
|
||||
const freq = inState.Live.Freq;
|
||||
if(freq)
|
||||
{
|
||||
inState.Live.Mark = MarkGet(freq, inState.Chan.Value, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/** @type {(inTest:Store.Test, inChan:number, inStim:Store.Range, inIsUser:boolean)=>Store.DrawGroup} */
|
||||
export function Congtiguous(inTest, inChan, inStim, inIsUser)
|
||||
/** @type {(inTest:Store.Test|undefined, inChan:number, inStim:Store.Range, inIsUser:boolean)=>Store.DrawGroup} */
|
||||
const Redraw =(inTest, inChan, inStim, inIsUser)=>
|
||||
{
|
||||
/** @type {Store.DrawGroup} */
|
||||
const output = {Points:[], Paths:[]};
|
||||
|
||||
if(inTest)
|
||||
{
|
||||
let plot;
|
||||
for(let i=0; i<inTest.Plot.length; i++)
|
||||
{
|
||||
@ -137,6 +125,7 @@ export function Congtiguous(inTest, inChan, inStim, inIsUser)
|
||||
output.Paths.push(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -149,24 +138,27 @@ export function Reducer(inState, inAction)
|
||||
|
||||
if(Name == "Test")
|
||||
{
|
||||
clone.Live.Test = clone.Tests[Data];
|
||||
Update.Freq(clone);
|
||||
Update.Mark(clone);
|
||||
const test = clone.Tests[Data];
|
||||
clone.Live = Reselect(clone, test);
|
||||
clone.Draw = {
|
||||
UserL: Congtiguous(clone.Live.Test, 0, clone.Stim, true ),
|
||||
UserR: Congtiguous(clone.Live.Test, 1, clone.Stim, true ),
|
||||
TestL: Congtiguous(clone.Live.Test, 0, clone.Stim, false),
|
||||
TestR: Congtiguous(clone.Live.Test, 1, clone.Stim, false)
|
||||
UserL: Redraw(test, 0, clone.Stim, true ),
|
||||
UserR: Redraw(test, 1, clone.Stim, true ),
|
||||
TestL: Redraw(test, 0, clone.Stim, false),
|
||||
TestR: Redraw(test, 1, clone.Stim, false)
|
||||
};
|
||||
clone.Live = {...clone.Live};
|
||||
}
|
||||
else if (Name == "Mark")
|
||||
{
|
||||
if(clone.Live.Test && clone.Live.Freq)
|
||||
{
|
||||
clone.Live.Mark = MarkSet(clone.Live.Freq, clone.Chan.Value, Data !== null ? {Stim:clone.Stim.Value, Resp:Data} : undefined);
|
||||
clone.Draw[clone.Chan.Value == 0 ? "UserL" : "UserR"] = Congtiguous(clone.Live.Test, clone.Chan.Value, clone.Stim, true);
|
||||
const key = clone.Chan.Value == 0 ? "UserL" : "UserR";
|
||||
|
||||
clone.Live.Mark = Data !== null ? {Stim:clone.Stim.Value, Resp:Data} : undefined;
|
||||
clone.Live.Freq[key] = clone.Live.Mark;
|
||||
clone.Live.Freq = {...clone.Live.Freq};
|
||||
clone.Live = {...clone.Live};
|
||||
|
||||
clone.Draw[key] = Redraw(clone.Live.Test, clone.Chan.Value, clone.Stim, true);
|
||||
clone.Draw = {...clone.Draw};
|
||||
}
|
||||
}
|
||||
@ -179,9 +171,7 @@ export function Reducer(inState, inAction)
|
||||
clone[Name] = tone;
|
||||
if(Name != "Stim")
|
||||
{
|
||||
Update.Freq(clone);
|
||||
Update.Mark(clone);
|
||||
clone.Live = {...clone.Live};
|
||||
clone.Live = Reselect(clone);
|
||||
}
|
||||
}
|
||||
|
||||
|
12
src/ui.js
12
src/ui.js
@ -1,6 +1,6 @@
|
||||
import React from "https://esm.sh/preact@10.11.3/compat";
|
||||
import { html } from "https://esm.sh/htm@3.1.1/preact";
|
||||
import { ColumnMapping } from "./store.js";
|
||||
import * as Store from "./store.js";
|
||||
|
||||
/** @typedef {({children}:{children?:preact.ComponentChildren})=>preact.VNode} BasicElement */
|
||||
|
||||
@ -37,10 +37,11 @@ export function Button({children, icon, light, disabled, inactive, onClick})
|
||||
/** @type {BasicElement} */
|
||||
export function Chart({children})
|
||||
{
|
||||
const [State] = Store.Consumer();
|
||||
const inset = 20;
|
||||
/** @type {Array<preact.VNode>} */
|
||||
const rules = [];
|
||||
ColumnMapping.forEach(([label, position, normal])=>
|
||||
Store.ColumnMapping.forEach(([label, position, normal])=>
|
||||
{
|
||||
rules.push(html`
|
||||
<span class="block absolute top-[-${inset}px] left-[${position*100}%] w-0 h-[calc(100%+${inset*2}px)] border-r(1 slate-400) ${!normal && "border-dashed"}">
|
||||
@ -49,12 +50,10 @@ export function Chart({children})
|
||||
);
|
||||
});
|
||||
|
||||
const dbMin = -10;
|
||||
const dbMax = 120;
|
||||
for(let db = dbMin; db <= dbMax; db+=10)
|
||||
for(let db = State.Stim.Min; db <= State.Stim.Max; db+=10)
|
||||
{
|
||||
rules.push(html`
|
||||
<span class="block absolute left-[-${inset}px] top-[${((db-dbMin) / (dbMax-dbMin))*100}%] h-0 w-[calc(100%+${inset*2}px)] border-b(${db == 0 ? "2 black" : "1 slate-400"})">
|
||||
<span class="block absolute left-[-${inset}px] top-[${((db-State.Stim.Min) / (State.Stim.Max-State.Stim.Min))*100}%] h-0 w-[calc(100%+${inset*2}px)] border-b(${db == 0 ? "2 black" : "1 slate-400"})">
|
||||
<span class="block absolute top-0 left-0 -translate-x-full -translate-y-1/2 pr-2">${db}</span>
|
||||
</span>`
|
||||
);
|
||||
@ -87,7 +86,6 @@ const Glyph = {
|
||||
<line vector-effect="non-scaling-stroke" x1="100%" y1="100%" x2="25%" y2="100%"></line>
|
||||
<line vector-effect="non-scaling-stroke" x1="100%" y1="100%" x2="100%" y2="25%" ></line>`,
|
||||
|
||||
//style="transform: translate(50%, 50%) rotate(-15deg) scale(0.5);"
|
||||
X: ({children})=> html`
|
||||
<line x1="-50%" y1="-50%" x2="50%" y2="50%" ></line>
|
||||
<line x1="-50%" y1="50%" x2="50%" y2="-50%"></line>
|
||||
|
Loading…
Reference in New Issue
Block a user