From 92a302caa945f48e798aa4e053373d1b8bfc2cfb Mon Sep 17 00:00:00 2001 From: stuebinm Date: Wed, 15 May 2024 01:54:29 +0200 Subject: Frontend.SpaceTime: make diagram's y axis scalable in preparation for using these elsewhere, where they are less cramped --- lib/Server/Frontend/SpaceTime.hs | 43 ++++++++++++++++++++-------------------- lib/Server/Frontend/Tickets.hs | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/Server/Frontend/SpaceTime.hs b/lib/Server/Frontend/SpaceTime.hs index 87b9ace..16e8205 100644 --- a/lib/Server/Frontend/SpaceTime.hs +++ b/lib/Server/Frontend/SpaceTime.hs @@ -37,7 +37,7 @@ getSpaceTimeDiagramR = do Just day -> pure day Nothing -> liftIO $ getCurrentTime <&> utctDay - mkSpaceTimeDiagramHandler day >>= \case + mkSpaceTimeDiagramHandler 1 day [ TicketDay ==. day ] >>= \case Nothing -> notFound Just widget -> defaultLayout [whamlet|

_{MsgSpaceTimeDiagram} @@ -45,12 +45,12 @@ getSpaceTimeDiagramR = do ^{widget} |] -mkSpaceTimeDiagramHandler :: Day -> Handler (Maybe Widget) -mkSpaceTimeDiagramHandler day = do - tickets <- runDB $ selectList [ TicketDay ==. day ] [ Asc TicketId ] >>= mapM (\ticket -> do +mkSpaceTimeDiagramHandler :: Double -> Day -> [Filter Ticket] -> Handler (Maybe Widget) +mkSpaceTimeDiagramHandler scale day filter = do + tickets <- runDB $ selectList filter [ Asc TicketId ] >>= mapM (\ticket -> do stops <- selectList [StopTicket ==. entityKey ticket] [] >>= mapM (\(Entity _ stop@Stop{..}) -> do - arrival <- lift $ timeToPos day stopArrival - departure <- lift $ timeToPos day stopDeparture + arrival <- lift $ timeToPos scale day stopArrival + departure <- lift $ timeToPos scale day stopDeparture pure (stop, arrival, departure)) anchors <- selectList [TrainAnchorTicket ==. entityKey ticket] [Desc TrainAnchorSequence] pure (ticket, stops, anchors)) @@ -59,15 +59,16 @@ mkSpaceTimeDiagramHandler day = do [] -> pure Nothing _ -> - mkSpaceTimeDiagram day tickets + mkSpaceTimeDiagram scale day tickets <&> Just -- | Safety: tickets may not be empty mkSpaceTimeDiagram - :: Day + :: Double + -> Day -> [(Entity Ticket, [(Stop, Double, Double)], [Entity TrainAnchor])] -> Handler Widget -mkSpaceTimeDiagram day tickets = do +mkSpaceTimeDiagram scale day tickets = do -- we take the longest trip of the day. This will lead to unreasonable results -- if there's more than one shape (this whole route should probably take a shape id tbh) stations <- runDB $ fmap (\(_,stops,_) -> stops) tickets @@ -88,15 +89,15 @@ mkSpaceTimeDiagram day tickets = do (minY, maxY) <- tickets <&> (\(_,stops,_) -> stops) & concat - & mapM (timeToPos day . stopDeparture . (\(stop, _, _) -> stop)) + & mapM (timeToPos scale day . stopDeparture . (\(stop, _, _) -> stop)) <&> (\ys -> (minimum ys - 10, maximum ys + 30)) let timezone = head reference & stopArrival & GTFS.tzname - timeLines <- ([0,3600..(24*3600)] - & mapM ((\a -> timeToPos day a <&> (,a)) . \seconds -> GTFS.Time seconds timezone)) + timeLines <- ([0,(double2Int $ 3600 / scale)..(24*3600)] + & mapM ((\a -> timeToPos scale day a <&> (,a)) . \seconds -> GTFS.Time seconds timezone)) <&> takeWhile ((< maxY - 20) . fst) . filter ((> minY) . fst) pure [whamlet| @@ -131,7 +132,7 @@ mkSpaceTimeDiagram day tickets = do > |] @@ -144,8 +145,8 @@ mkStopsline scaleSequence reference stops = stops +|scaleSequence s|+","+|departure|+"" where s = mapSequenceWith reference stop & int2Double -mkAnchorline :: (Double -> Double) -> [Stop] -> [(Stop, Double, Double)] -> [Entity TrainAnchor] -> Text -mkAnchorline scaleSequence reference stops anchors = +mkAnchorline :: Double -> (Double -> Double) -> [Stop] -> [(Stop, Double, Double)] -> [Entity TrainAnchor] -> Text +mkAnchorline scale scaleSequence reference stops anchors = anchors <&> (mkAnchor . entityVal) & T.concat @@ -153,7 +154,7 @@ mkAnchorline scaleSequence reference stops anchors = mkAnchor TrainAnchor{..} = " "+|scaleSequence transformed|+"," -- this use of secondsToPos is correct; trainAnchorWhen saves in the correct timezone already - +|secondsToPos trainAnchorWhen|+"" + +|secondsToPos scale trainAnchorWhen|+"" where transformed = int2Double (mapSequence lastStop) + offset @@ -184,11 +185,11 @@ mapSequenceWith reference stop = filter & stopSequence -- | SAFETY: ignores time zones -secondsToPos :: Seconds -> Double -secondsToPos = (/ 600) . int2Double . GTFS.unSeconds +secondsToPos :: Double -> Seconds -> Double +secondsToPos scale = (* scale) . (/ 600) . int2Double . GTFS.unSeconds -timeToPos :: Day -> GTFS.Time -> Handler Double -timeToPos day time = do +timeToPos :: Double -> Day -> GTFS.Time -> Handler Double +timeToPos scale day time = do settings <- getYesod <&> getSettings tzseries <- liftIO $ getTzseries settings (GTFS.tzname time) - pure $ secondsToPos (GTFS.toSeconds time tzseries day) + pure $ secondsToPos scale (GTFS.toSeconds time tzseries day) diff --git a/lib/Server/Frontend/Tickets.hs b/lib/Server/Frontend/Tickets.hs index 839aeba..c3de1a1 100644 --- a/lib/Server/Frontend/Tickets.hs +++ b/lib/Server/Frontend/Tickets.hs @@ -63,7 +63,7 @@ getTicketsR = do Just day -> (day, day == today) Nothing -> (today, True) - maybeSpaceTime <- mkSpaceTimeDiagramHandler day + maybeSpaceTime <- mkSpaceTimeDiagramHandler 1 day [ TicketDay ==. day ] let prevday = (T.pack . iso8601Show . addDays (-1)) day let nextday = (T.pack . iso8601Show . addDays 1) day -- cgit v1.2.3