From 2a4b5702af192d61eee780dc573189e008d815f3 Mon Sep 17 00:00:00 2001 From: Nathan McRae Date: Wed, 20 Aug 2025 21:49:23 -0700 Subject: [PATCH] Add tick size control --- index.html | 10 ++++++++-- src/Main.purs | 14 +++++++++++++- src/TernaryGraph.purs | 23 +++++++++++++++-------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index 683546d..4714c1a 100644 --- a/index.html +++ b/index.html @@ -2,8 +2,14 @@ - ticks: - +
+ ticks: + +
+
+ tick size (px): + +
diff --git a/src/Main.purs b/src/Main.purs index b6827cc..7a8cf6a 100644 --- a/src/Main.purs +++ b/src/Main.purs @@ -16,6 +16,7 @@ import Effect.Console (log) import Effect.Class (liftEffect) import Effect.Exception (throw) import TernaryGraph (Dimension, svgTextID, ternaryGraph, ternaryGraphSvg, TextStyle, tickLabelStrings) +import TernaryGraph as TernaryGraph import Web.DOM.Document (contentType , createElement , Document @@ -118,6 +119,12 @@ update e = do Just e -> pure e ticks <- (liftM1 Int.round) $ HTMLInput.valueAsNumber inputHTMLElement + tickSizeElMay <- myGetElementById document "tick-size" + tickSizeEl <- case HTMLInput.fromElement tickSizeElMay of + Nothing -> throw "'tick-size' element is not an input tag" + Just e -> pure e + tickSize <- HTMLInput.valueAsNumber tickSizeEl + svgContainer <- getNodeById document "svg-container" let graphDef = { axis1Label: "axis 1" @@ -130,6 +137,7 @@ update e = do , tickTextStyle: { sizePx: 12.0 , typeface: "Liberation Sans" } + , tickSize: TernaryGraph.Pixels tickSize , axisTitleTextStyle: { sizePx: 16.0 , typeface: "Liberation Mono" } @@ -189,6 +197,7 @@ main = do , tickTextStyle: { sizePx: 12.0 , typeface: "Liberation Sans" } + , tickSize: TernaryGraph.Pixels 10.0 , axisTitleTextStyle: { sizePx: 16.0 , typeface: "Liberation Mono" } @@ -229,7 +238,10 @@ main = do inputElement <- myGetElementById dd "ticks" addEventListener (EventType "input") listener true (Element.toEventTarget inputElement) - log "20250727T183907" + + tickSizeEl <- myGetElementById dd "tick-size" + addEventListener (EventType "input") listener true (Element.toEventTarget tickSizeEl) + --inputMay <- getElementById "ticks" $ toNonElementParentNode dd --inputNode <- case inputMay of --Nothing -> throw $ "Unable to find " <> containerID diff --git a/src/TernaryGraph.purs b/src/TernaryGraph.purs index 4107a93..393ef55 100644 --- a/src/TernaryGraph.purs +++ b/src/TernaryGraph.purs @@ -18,6 +18,13 @@ import Data.Set as Set import Data.Tuple as Tup import Data.Tuple.Nested (Tuple3, tuple3, get1, get2, get3) +-- A spatial value (position, size) in pixels +-- TODO: Apply this across all spatial values +newtype Pixels = Pixels Number + +unpixel :: Pixels -> Number +unpixel (Pixels value) = value + type Dimension = { widthPx :: Number , heightPx :: Number @@ -42,6 +49,7 @@ type GraphDefinition = , axis3Start :: Int , numTicks :: Int , tickTextStyle :: TextStyle + , tickSize :: Pixels , axisTitleTextStyle :: TextStyle } @@ -101,21 +109,20 @@ svgTextID idMaybe text { x: x, y: y } angle style dimension = Maybe.Nothing -> "" Maybe.Just id -> "id=\"" <> id <> "\"" --- TODO: Make axis tick size a parameter -getTick :: Number -> Int -> Int -> Line -getTick scale numTicks tickI = - {start: {x: x, y: -(0.5 + 5.0 / scale)}, end: {x: x, y: y}} +getTick :: Number -> Int -> Pixels -> Int -> Line +getTick scale numTicks tickSize tickI = + {start: {x: x, y: -(0.5 + (unpixel tickSize) / scale)}, end: {x: x, y: y}} where x = 2.0 * (sin (pi / 3.0)) * (Int.toNumber tickI) / (Int.toNumber numTicks) - (sin (pi / 3.0)) y = if tickI <= numTicks / 2 then 1.0 + x * 1.5 / (sin (pi / 3.0)) else 1.0 - x * 1.5 / (sin (pi / 3.0)) -getTicks :: Number -> Number -> Int -> Tuple3 (Array Line) (Array Line) (Array Line) -getTicks scale angle numTicks = +getTicks :: Number -> Number -> Pixels -> Int -> Tuple3 (Array Line) (Array Line) (Array Line) +getTicks scale angle tickSize numTicks = tuple3 axis1Lines axis2Lines axis3Lines where - foo = map (getTick scale numTicks) (Array.range 0 numTicks) + foo = map (getTick scale numTicks tickSize) (Array.range 0 numTicks) axis1Lines = map (rotateLine angle) foo axis2Lines = map (rotateLine (2.0 * pi / 3.0)) axis1Lines axis3Lines = map (rotateLine (2.0 * pi / 3.0)) axis2Lines @@ -159,7 +166,7 @@ tickLabelStrings def = ternaryGraph :: Number -> Number -> Number -> GraphDefinition -> Map.Map (Tup.Tuple String TextStyle) Dimension -> Either.Either String String ternaryGraph scale xOffset yOffset definition textDimensions = result where - axisTickLines = getTicks scale pi definition.numTicks + axisTickLines = getTicks scale pi definition.tickSize definition.numTicks axis1TickLines = map (transformLine scale xOffset yOffset) (get1 axisTickLines) axis2TickLines = map (transformLine scale xOffset yOffset) (get2 axisTickLines) axis3TickLines = map (transformLine scale xOffset yOffset) (get3 axisTickLines)