Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

389 fix sorting in numeric columns #460

Merged
merged 3 commits into from
Aug 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 51 additions & 20 deletions eo-phi-normalizer/src/Language/EO/Phi/Report/Html.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
module Language.EO.Phi.Report.Html where

import Data.FileEmbed (embedFileRelative)
import Data.Functor ((<&>))
import Data.List (intercalate)
import Data.Maybe (catMaybes, fromMaybe)
import Data.Text qualified as T
Expand Down Expand Up @@ -89,53 +90,83 @@ instance ToMarkup Percent where
toMarkup :: Percent -> Markup
toMarkup = toMarkup . show

-- >>> pipelineConfig = ReportConfig { general = ReportGeneralConfig { expectedMetricsChange = 0, format = ReportFormat'Markdown } }
class (Num a) => ToDataSort a where
toDataSort :: a -> Integer

-- TODO #389:30m
-- I couldn't make PyF pad doubles with zeros using {n:05} syntax
-- because PyF also counts the digits after .
instance ToDataSort Double where
toDataSort :: Double -> Integer
toDataSort number = round $ number * 1000

instance ToDataSort Percent where
toDataSort :: Percent -> Integer
toDataSort (Percent number) = toDataSort number

instance ToDataSort Integer where
toDataSort :: Integer -> Integer
toDataSort x = x

mkDataSortAttribute :: AttributeValue -> Attribute
mkDataSortAttribute = dataAttribute "sort"

-- >>> pipelineConfig = ReportFormat'Markdown
--
-- >>> renderHtml $ toHtmlChange pipelineConfig (MetricsChange'Bad 0.2)
-- "<td class=\"number bad\">0.2\128308</td>"
-- >>> renderHtml $ toHtmlChange pipelineConfig (MetricsChange'Bad (Percent 0.2))
-- "<td class=\"number bad\" data-sort=\"1000200\">20.00%\128308</td>"
--
-- >>> renderHtml $ toHtmlChange pipelineConfig (MetricsChange'Good 0.5)
-- "<td class=\"number good\">0.5\128994</td>"
-- >>> renderHtml $ toHtmlChange pipelineConfig (MetricsChange'NA :: MetricsChangeCategory Double)
-- "<td class=\"number not-applicable\">N/A\128995</td>"
toHtmlChange :: (ToMarkup a) => ReportFormat -> MetricsChangeCategory a -> Html
-- >>> renderHtml $ toHtmlChange pipelineConfig (MetricsChange'Good (Percent 0.5))
-- "<td class=\"number good\" data-sort=\"1000500\">50.00%\128994</td>"
-- >>> renderHtml $ toHtmlChange pipelineConfig (MetricsChange'NA :: MetricsChangeCategory Percent)
-- "<td class=\"number not-applicable\" data-sort=\"0000000\">N/A\128995</td>"
toHtmlChange :: forall a. (ToMarkup a, ToDataSort a) => ReportFormat -> MetricsChangeCategory a -> Html
toHtmlChange reportFormat = \case
MetricsChange'NA -> td ! class_ "number not-applicable" $ toHtml ("N/A" :: String) <> toHtml ['🟣' | isMarkdown]
MetricsChange'Bad{..} -> td ! class_ "number bad" $ toHtml change <> toHtml ['🔴' | isMarkdown]
MetricsChange'Good{..} -> td ! class_ "number good" $ toHtml change <> toHtml ['🟢' | isMarkdown]
MetricsChange'NA -> td ! class_ [fmt|{number} not-applicable|] ! mkDataSortAttributeNA $ toHtml na <> toHtml ['🟣' | isMarkdown]
MetricsChange'Bad{..} -> td ! class_ [fmt|{number} bad|] ! mkDataSortAttributeChange change $ toHtml change <> toHtml ['🔴' | isMarkdown]
MetricsChange'Good{..} -> td ! class_ [fmt|{number} good|] ! mkDataSortAttributeChange change $ toHtml change <> toHtml ['🟢' | isMarkdown]
where
isMarkdown = reportFormat == ReportFormat'Markdown
mkDataSortAttributeChange change = mkDataSortAttribute [fmt|1{toDataSort change:06}|]
mkDataSortAttributeNA = mkDataSortAttribute [fmt|0{(toDataSort (Percent 0.0)):06}|]
na :: String
na = "N/A"
number :: String
number = "number"

toHtmlMetricsChange :: ReportFormat -> MetricsChangeCategorized -> [Html]
toHtmlMetricsChange reportFormat change = toHtmlChange reportFormat <$> toListMetrics change

toHtmlMetrics :: MetricsCount -> [Html]
toHtmlMetrics metrics =
(td ! class_ "number")
. toHtml
<$> toListMetrics metrics
toListMetrics metrics
<&> (\x -> td ! class_ "number" ! mkDataSortAttribute [fmt|{x:06}|] $ toHtml x)

toHtmlReportRow :: ReportFormat -> Int -> ReportRow -> Html
toHtmlReportRow reportFormat index reportRow =
tr . toHtml $
( td
. toHtml
<$> [ [fmt|{index}|]
, fromMaybe "[N/A]" reportRow.attributeInitial
, fromMaybe "[N/A]" reportRow.attributeNormalized
, fromMaybe na reportRow.attributeInitial
, fromMaybe na reportRow.attributeNormalized
]
)
<> toHtmlMetricsChange reportFormat reportRow.metricsChange
<> toHtmlMetrics reportRow.metricsInitial
<> toHtmlMetrics reportRow.metricsNormalized
<> ( td
. toHtml
<$> [ fromMaybe "[all programs]" reportRow.fileInitial
, intercalate "." $ fromMaybe ["[whole program]"] reportRow.bindingsPathInitial
, fromMaybe "[all programs]" reportRow.fileNormalized
, intercalate "." $ fromMaybe ["[whole program]"] reportRow.bindingsPathNormalized
<$> [ fromMaybe allPrograms reportRow.fileInitial
, intercalate "." $ fromMaybe [wholeProgram] reportRow.bindingsPathInitial
, fromMaybe allPrograms reportRow.fileNormalized
, intercalate "." $ fromMaybe [wholeProgram] reportRow.bindingsPathNormalized
]
)
where
wholeProgram = "[whole program]"
allPrograms = "[all programs]"
na = "[N/A]"

toHtmlReport :: ReportFormat -> PipelineConfig -> Report -> Html
toHtmlReport reportFormat pipelineConfig report =
Expand Down