Browse Source

Add CMC chart

Cadel Watson 1 year ago
parent
commit
76630ebabe
3 changed files with 145 additions and 13 deletions
  1. 12 2
      elm.json
  2. 43 0
      src/Deck.elm
  3. 90 11
      src/Main.elm

+ 12 - 2
elm.json

@@ -11,12 +11,22 @@
             "elm/core": "1.0.5",
             "elm/core": "1.0.5",
             "elm/html": "1.0.0",
             "elm/html": "1.0.0",
             "elm/json": "1.1.3",
             "elm/json": "1.1.3",
-            "myrho/elm-round": "1.0.5"
+            "elm-community/list-extra": "8.7.0",
+            "myrho/elm-round": "1.0.5",
+            "terezka/elm-charts": "4.0.0"
         },
         },
         "indirect": {
         "indirect": {
+            "K-Adam/elm-dom": "1.0.0",
+            "danhandrea/elm-time-extra": "1.1.0",
+            "elm/parser": "1.1.0",
+            "elm/svg": "1.0.1",
             "elm/time": "1.0.0",
             "elm/time": "1.0.0",
             "elm/url": "1.0.0",
             "elm/url": "1.0.0",
-            "elm/virtual-dom": "1.0.2"
+            "elm/virtual-dom": "1.0.2",
+            "justinmimbs/date": "4.1.0",
+            "justinmimbs/time-extra": "1.2.0",
+            "ryan-haskell/date-format": "1.0.0",
+            "terezka/intervals": "2.0.2"
         }
         }
     },
     },
     "test-dependencies": {
     "test-dependencies": {

+ 43 - 0
src/Deck.elm

@@ -0,0 +1,43 @@
+module Deck exposing (Deck, cmcCurve, fromDraft)
+
+import Card exposing (CardData)
+import Database exposing (Database)
+import Draft exposing (Draft)
+import List.Extra as List exposing (group)
+import Zipper
+
+
+type alias Deck =
+    { cards : List CardData }
+
+
+fromDraft : Bool -> Database -> Draft -> Deck
+fromDraft includeWholeDeck db draft =
+    let
+        picks =
+            if includeWholeDeck then
+                Zipper.toList draft |> List.map .chosen
+
+            else
+                (Zipper.focus draft :: Zipper.left draft) |> List.map .chosen
+
+        cards =
+            List.filterMap (\pick -> Database.get pick.name db) picks
+    in
+    { cards = cards }
+
+
+cmcCurve : Deck -> List ( Int, Int )
+cmcCurve deck =
+    let
+        maxBucket =
+            7
+
+        cmcs =
+            deck.cards
+                |> List.map (.details >> .cmc)
+    in
+    (List.range 0 maxBucket
+        |> List.map (\cmc -> ( cmc, List.count (\x -> x == cmc) cmcs ))
+    )
+        ++ [ ( maxBucket, List.count (\x -> x >= maxBucket) cmcs ) ]

+ 90 - 11
src/Main.elm

@@ -2,13 +2,18 @@ module Main exposing (..)
 
 
 import Browser exposing (Document)
 import Browser exposing (Document)
 import Card exposing (CardData)
 import Card exposing (CardData)
+import Chart as C
+import Chart.Attributes as CA
 import Database
 import Database
+import Deck
 import Draft exposing (Draft)
 import Draft exposing (Draft)
 import Html exposing (Html, button, div, img, span, text)
 import Html exposing (Html, button, div, img, span, text)
 import Html.Attributes exposing (alt, class, classList, disabled, src)
 import Html.Attributes exposing (alt, class, classList, disabled, src)
 import Html.Events as Events exposing (onClick)
 import Html.Events as Events exposing (onClick)
 import Html.Keyed as Keyed
 import Html.Keyed as Keyed
+import List.Extra as List
 import Round
 import Round
+import Tuple exposing (second)
 import Zipper
 import Zipper
 
 
 
 
@@ -26,6 +31,11 @@ type Model
     | Error ErrorModel
     | Error ErrorModel
 
 
 
 
+type DeckProgress
+    = EntireDeck
+    | DeckUpToPick
+
+
 type FocusStat
 type FocusStat
     = FocusALSA
     = FocusALSA
     | FocusALPA
     | FocusALPA
@@ -39,6 +49,7 @@ type alias ReadyModel =
     , highlighted : Maybe Draft.PickCard
     , highlighted : Maybe Draft.PickCard
     , flipHighlighted : Bool
     , flipHighlighted : Bool
     , focusStat : FocusStat
     , focusStat : FocusStat
+    , deckProgress : DeckProgress
     }
     }
 
 
 
 
@@ -57,6 +68,7 @@ init flags =
                 , highlighted = Nothing
                 , highlighted = Nothing
                 , flipHighlighted = False
                 , flipHighlighted = False
                 , focusStat = FocusPickRate
                 , focusStat = FocusPickRate
+                , deckProgress = DeckUpToPick
                 }
                 }
             , Cmd.none
             , Cmd.none
             )
             )
@@ -77,6 +89,7 @@ type Msg
     | Highlight Draft.PickCard
     | Highlight Draft.PickCard
     | FlipHighlightedCard
     | FlipHighlightedCard
     | SetFocusStat FocusStat
     | SetFocusStat FocusStat
+    | SetDeckProgress DeckProgress
 
 
 
 
 update : Msg -> Model -> ( Model, Cmd Msg )
 update : Msg -> Model -> ( Model, Cmd Msg )
@@ -105,6 +118,9 @@ update msg model =
                 SetFocusStat stat ->
                 SetFocusStat stat ->
                     ( Ready { mdl | focusStat = stat }, Cmd.none )
                     ( Ready { mdl | focusStat = stat }, Cmd.none )
 
 
+                SetDeckProgress progress ->
+                    ( Ready { mdl | deckProgress = progress }, Cmd.none )
+
         Error mdl ->
         Error mdl ->
             ( Error mdl, Cmd.none )
             ( Error mdl, Cmd.none )
 
 
@@ -135,19 +151,82 @@ viewReady model =
 viewSidebar : ReadyModel -> Html Msg
 viewSidebar : ReadyModel -> Html Msg
 viewSidebar model =
 viewSidebar model =
     div [ class "col-span-2 p-6 bg-slate-600" ]
     div [ class "col-span-2 p-6 bg-slate-600" ]
-        [ button
-            [ onClick Decrement
-            , disabled (not (Zipper.hasLeft model.draft))
-            , class "bg-slate-900 rounded text-white p-2 shadow disabled:opacity-50"
+        [ div []
+            [ button
+                [ onClick Decrement
+                , disabled (not (Zipper.hasLeft model.draft))
+                , class "bg-slate-900 rounded text-white p-2 shadow disabled:opacity-50"
+                ]
+                [ text "Previous" ]
+            , span [ class "text-white px-3 font-medium" ] [ text ("Pick " ++ String.fromInt (Zipper.position model.draft)) ]
+            , button
+                [ onClick Increment
+                , class "bg-slate-900 rounded text-white p-2 shadow disabled:opacity-50"
+                , disabled (not (Zipper.hasRight model.draft))
+                ]
+                [ text "Next" ]
+            ]
+        , viewDeck model
+        ]
+
+
+viewDeck : ReadyModel -> Html Msg
+viewDeck model =
+    div [ class "mt-6" ]
+        [ div [ class "w-full flex" ]
+            [ button
+                [ onClick (SetDeckProgress DeckUpToPick)
+                , disabled (model.deckProgress == DeckUpToPick)
+                , classList
+                    [ ( "grow border-b-2 text-white pb-2", True )
+                    , ( "border-slate-300 font-medium"
+                      , model.deckProgress == DeckUpToPick
+                      )
+                    , ( "border-slate-900"
+                      , model.deckProgress /= DeckUpToPick
+                      )
+                    ]
+                ]
+                [ text "Up to current pick" ]
+            , button
+                [ onClick (SetDeckProgress EntireDeck)
+                , disabled (model.deckProgress == EntireDeck)
+                , classList
+                    [ ( "grow border-b-2 text-white pb-2", True )
+                    , ( "border-slate-300 font-medium"
+                      , model.deckProgress == EntireDeck
+                      )
+                    , ( "border-slate-900"
+                      , model.deckProgress /= EntireDeck
+                      )
+                    ]
+                ]
+                [ text "Entire deck" ]
+            ]
+        , viewCmcChart model
+        ]
+
+
+viewCmcChart : ReadyModel -> Html Msg
+viewCmcChart model =
+    let
+        deck =
+            Deck.fromDraft (model.deckProgress == EntireDeck) model.database model.draft
+
+        cmcs =
+            Deck.cmcCurve deck
+
+        bars =
+            C.bars [] [ C.bar (second >> toFloat) [] ] cmcs
+    in
+    div [ class "m-4" ]
+        [ C.chart
+            [ CA.height 300
             ]
             ]
-            [ text "Previous" ]
-        , span [ class "text-white px-3 font-medium" ] [ text ("Pick " ++ String.fromInt (Zipper.position model.draft)) ]
-        , button
-            [ onClick Increment
-            , class "bg-slate-900 rounded text-white p-2 shadow disabled:opacity-50"
-            , disabled (not (Zipper.hasRight model.draft))
+            [ C.xLabels []
+            , C.yLabels [ CA.withGrid ]
+            , bars
             ]
             ]
-            [ text "Next" ]
         ]
         ]