Angle.jsx (1734B)
1 import Label from './Label.jsx'; 2 import { useContext } from 'preact/hooks'; 3 import { PlotContext } from '../../scripts/contexts.js'; 4 import { getColourClass, getMidpoint, interpolateDistance, sumVectors, getVector } from '../../scripts/graphUtils.js'; 5 6 function getArc(points, radius) { 7 const start = interpolateDistance(points[1], points[0], radius); 8 const end = interpolateDistance(points[1], points[2], radius); 9 return [start, end]; 10 } 11 12 function RightAngle({ points, radius, colour }) { 13 const [start, end] = getArc(points, radius); 14 const midpoint = sumVectors(start, getVector(points[1], end)); 15 return <polygon points={[points[1], start, midpoint, end]} class={getColourClass(colour)} /> 16 } 17 18 function AngleArc({ points, radius, colour }) { 19 const [start, end] = getArc(points, radius); 20 return <path d={`M ${start} A ${radius} ${radius} 0 0 1 ${end}`} class={getColourClass(colour)} />; 21 } 22 23 function AngleLabel({ points, radius, colour, children }) { 24 const point = interpolateDistance(points[1], getMidpoint(getArc(points, 1)), 1.5 * radius); 25 return <Label point={point} colour={colour}>{children}</Label>; 26 } 27 28 export default function Angle({ points, right = false, arcs = 1, label = null, colour = "auto" }) { 29 const p = useContext(PlotContext); 30 const radius = 10 * p.strokeWidth; 31 const concentricGap = 1.5 * p.strokeWidth; 32 return ( 33 <g> 34 {right ? ( 35 <RightAngle points={points} radius={0.8 * radius} colour={colour} /> 36 ) : Array.from({ length: arcs }).map( 37 (_, i) => <AngleArc points={points} radius={(radius + i*concentricGap)} colour={colour} /> 38 )} 39 {label && <AngleLabel points={points} radius={radius} colour={colour}>{label}</AngleLabel>} 40 </g> 41 ); 42 }