website

source code for the ttmaths.uk website
Log | Files | Refs | README

commit f7b9168c3ad040fae4ab0577aa27a0010f4a31d2
parent 0297888791bca3593376d11d38520139a1eb49b8
Author: fen123456 <fenwthompson@gmail.com>
Date:   Fri, 14 Aug 2026 16:47:05 +0100

Merge branch 'main' of https://github.com/hrryt/website

Diffstat:
Msrc/components/graphing/Angle.jsx | 4++--
Msrc/components/graphing/Graph.jsx | 56+++++++++++++++++++++++++++++++++-----------------------
Msrc/components/graphing/Label.jsx | 7++++---
Msrc/components/graphing/Point.jsx | 2+-
Msrc/scripts/contexts.js | 2+-
Msrc/styles/svg.css | 1+
6 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/src/components/graphing/Angle.jsx b/src/components/graphing/Angle.jsx @@ -1,6 +1,6 @@ import Label from './Label.jsx'; import { useContext } from 'preact/hooks'; -import { ScaleFactorContext } from '../../scripts/contexts.js'; +import { StrokeWidthContext } from '../../scripts/contexts.js'; import { getColourClass, getMidpoint, interpolateDistance } from '../../scripts/utils.js'; function getArc(points, radius) { @@ -20,7 +20,7 @@ function AngleLabel({ points, radius, colour, children }) { } export default function Angle({ points, radius = 0.5, arcs = 1, label = null, colour = "auto" }) { - const concentricGap = 7 * useContext(ScaleFactorContext); + const concentricGap = 3 * useContext(StrokeWidthContext); return ( <g> {Array.from({ length: arcs }).map( diff --git a/src/components/graphing/Graph.jsx b/src/components/graphing/Graph.jsx @@ -1,4 +1,5 @@ -import { ScaleFactorContext } from '../../scripts/contexts.js'; +import { useContext } from 'preact/hooks'; +import { StrokeWidthContext } from '../../scripts/contexts.js'; import Label from './Label.jsx'; function Grid({ viewBox }) { @@ -9,49 +10,58 @@ function Grid({ viewBox }) { function Axes({ viewBox }) { const [ minX, minY, width, height ] = viewBox; + const arrowheadHeight = 4 * useContext(StrokeWidthContext); return ( <g> - <path class="axis" d={`M ${minX},0 h ${width-.1}`} marker-end="url(#arrow)"/> - <path class="axis" d={`M 0,${minY} v ${height-.1}`} marker-end="url(#arrow)"/> + <path class="axis" d={`M ${minX},0 h ${ width - arrowheadHeight}`} marker-end="url(#arrowhead)"/> + <path class="axis" d={`M 0,${minY} v ${height - arrowheadHeight}`} marker-end="url(#arrowhead)"/> </g> ); } -function AxisTicks({ every = 1, viewBox }) { +function AxisTicks({ viewBox }) { + const every = Math.floor(20 * useContext(StrokeWidthContext)); const [ minX, minY, width, height ] = viewBox; return ( <g> <g> - {Array.from({ length: width - 1 }).map((_, i) => { - const x = i + minX + 1; - if (x == 0 || x % every) { return; } - return <Label point={[x, 0]} position="bottom">{x}</Label>; - })} + <g> + {Array.from({ length: width - 1 }).map((_, i) => { + const x = i + minX + 1; + if (x == 0 || x % every) { return; } + return <Label point={[x, 0]} position="bottom">{x}</Label>; + })} + </g> + <g> + {Array.from({ length: height - 1 }).map((_, i) => { + const y = i + minY + 1; + if (y == 0 || y % every) { return; } + return <Label point={[0, y]} position="left">{y}</Label>; + })} + </g> + <Label point={[0, 0]} position="bottom-left">0</Label> </g> <g> - {Array.from({ length: height - 1 }).map((_, i) => { - const y = i + minY + 1; - if (y == 0 || y % every) { return; } - return <Label point={[0, y]} position="left">{y}</Label>; - })} + <Label weight="bold" point={[minX + width, 0]} position="bottom-left" spacing={3}>x</Label> + <Label weight="bold" point={[0, minY + height]} position="bottom-left" spacing={3}>y</Label> </g> - <Label point={[0, 0]} position="bottom-left">0</Label> </g> ) } export default function Graph({ children, viewBox, width="300", height="300" }) { const scaleFactor = Math.max(viewBox[2] / width, viewBox[3] / height); + const strokeWidth = 2.5 * scaleFactor; const style = ` text { font-size: ${scaleFactor}em; - stroke-width: ${4 * scaleFactor}; + stroke-width: ${1.6 * strokeWidth}; } path,polygon,line,polyline,circle,ellipse { - stroke-width: ${2.5 * scaleFactor}; + stroke-width: ${strokeWidth}; } path#grid { - stroke-width: ${0.5 * scaleFactor}; + stroke-width: ${0.2 * strokeWidth}; } `; return ( @@ -61,9 +71,9 @@ export default function Graph({ children, viewBox, width="300", height="300" }) > <defs> <marker - id='arrow' + id='arrowhead' viewBox="0 0 4 4" - refX="3" refY="2" + refX="0" refY="2" markerWidth="4" markerHeight="4" orient="auto" > @@ -120,12 +130,12 @@ export default function Graph({ children, viewBox, width="300", height="300" }) {style} </style> </defs> - <ScaleFactorContext value={scaleFactor}> + <StrokeWidthContext value={strokeWidth}> <Grid viewBox={viewBox} /> <Axes viewBox={viewBox} /> - <AxisTicks every={Math.floor(50 * scaleFactor)} viewBox={viewBox} /> + <AxisTicks viewBox={viewBox} /> {children} - </ScaleFactorContext> + </StrokeWidthContext> </svg> ); } diff --git a/src/components/graphing/Label.jsx b/src/components/graphing/Label.jsx @@ -1,5 +1,5 @@ import { useContext } from 'preact/hooks'; -import { ScaleFactorContext } from '../../scripts/contexts.js'; +import { StrokeWidthContext } from '../../scripts/contexts.js'; import { getColourClass } from '../../scripts/utils.js'; function getPosition(position) { @@ -19,16 +19,17 @@ function getPosition(position) { } } -export default function Label({ point, position='central', spacing=3, colour='auto', children }) { +export default function Label({ point, position='central', spacing=1, weight="normal", colour='auto', children }) { const [x, y] = point; const [dominantBaseline, textAnchor, dx, dy] = getPosition(position); - const scaledSpacing = spacing * useContext(ScaleFactorContext); + const scaledSpacing = spacing * useContext(StrokeWidthContext); return ( <text x={x} y={-y} dx={scaledSpacing * dx} dy={scaledSpacing * -dy} transform='scale(1 -1)' dominant-baseline={dominantBaseline} text-anchor={textAnchor} class={getColourClass(colour)} + font-weight={weight} > {children} </text> diff --git a/src/components/graphing/Point.jsx b/src/components/graphing/Point.jsx @@ -5,7 +5,7 @@ export default function Point({ point, label=null, colour="auto", position="top" return ( <g> <path marker-start="url(#cross)" d={`M ${point}`} class={getColourClass(colour)}/> - {label && <Label point={point} position={position} spacing={10} colour={colour}>{label}</Label>} + {label && <Label point={point} position={position} spacing={5} colour={colour}>{label}</Label>} </g> ); } diff --git a/src/scripts/contexts.js b/src/scripts/contexts.js @@ -1,3 +1,3 @@ import { createContext } from 'preact'; -export const ScaleFactorContext = createContext(null); +export const StrokeWidthContext = createContext(null); diff --git a/src/styles/svg.css b/src/styles/svg.css @@ -31,6 +31,7 @@ line.marker, polyline.marker { polygon.marker { fill-opacity: 1; + stroke-width: 0; } text {