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

Added many plots support and bounds input #37

Merged
merged 11 commits into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
62 changes: 34 additions & 28 deletions src/Components/Canvas/Draw.purs
Original file line number Diff line number Diff line change
@@ -1,98 +1,107 @@
module Components.Canvas.Draw where

import Prelude
import Data.Traversable (for_)
import Components.Canvas.Context (DrawOperation, withLocalDrawContext)
import Data.Array (head, tail)
import Data.Maybe (fromMaybe)
import Data.String (joinWith)
import Data.Traversable (for_)
import Draw.Color (Color, rgba)
import Effect (Effect)
import Graphics.Canvas (LineCap(..), beginPath, clearRect, fill, fillText, lineTo, moveTo, setFillStyle, setFont, setLineCap, setLineDash, setLineWidth, setStrokeStyle, stroke)
import Types (Position, Polygon)
import Components.Canvas.Context (DrawOperation, withLocalDrawContext)
import Types (Polygon, Position)

-- | Draws text
drawText :: String -> Number -> Position -> DrawOperation
drawText text size { x, y } =
withLocalDrawContext \drawContext -> do
let
font = joinWith " " [ show size <> "px", "Arial" ]
-- Set up the context for drawing the text

color = rgba 0.0 0.0 0.0 1.0
setFont drawContext.context font
setFillStyle drawContext.context "#000000"
-- Draw the text
setFillStyle drawContext.context $ show color
fillText drawContext.context text x y

clearCanvas :: DrawOperation
clearCanvas =
withLocalDrawContext \drawContext -> do
clearRect drawContext.context { height: drawContext.canvasHeight, width: drawContext.canvasWidth, x: 0.0, y: 0.0 }

drawLine :: Boolean -> Position -> Position -> DrawOperation
drawLine isDashed { x: x1, y: y1 } { x: x2, y: y2 } =
drawLine :: Boolean -> Color -> Position -> Position -> DrawOperation
drawLine isDashed color { x: x1, y: y1 } { x: x2, y: y2 } =
withLocalDrawContext \drawContext -> do
beginPath drawContext.context
moveTo drawContext.context x1 y1
lineTo drawContext.context x2 y2
setStrokeStyle drawContext.context $ show color
when isDashed do
setLineDash drawContext.context [ 1.0, 3.0 ]
setStrokeStyle drawContext.context $ toRGBA 0.0 0.0 0.0 0.3
stroke drawContext.context

drawPlotLine :: Position -> Position -> DrawOperation
drawPlotLine = drawLine false
drawPlotLine = drawLine false $ rgba 0.0 0.0 0.0 1.0

drawXAxisLine :: Number -> Number -> DrawOperation
drawXAxisLine xZero range drawContext = drawPlotLine a b drawContext
where
relativeX = (xZero * drawContext.canvasWidth) / range
a = { x: relativeX, y: 0.0 }
b = { x: relativeX, y: drawContext.canvasHeight }
relativeX = (xZero * drawContext.canvasWidth) / range

a = { x: relativeX, y: 0.0 }

b = { x: relativeX, y: drawContext.canvasHeight }

drawYAxisLine :: Number -> Number -> DrawOperation
drawYAxisLine yZero range drawContext = drawPlotLine a b drawContext
where
relativeY = drawContext.canvasHeight - (yZero * drawContext.canvasHeight) / range
a = { x: 0.0, y: relativeY }
b = { x: drawContext.canvasWidth, y: relativeY }
relativeY = drawContext.canvasHeight - (yZero * drawContext.canvasHeight) / range

a = { x: 0.0, y: relativeY }

b = { x: drawContext.canvasWidth, y: relativeY }

drawXGridLine :: Number -> Number -> Number -> DrawOperation
drawXGridLine x value range drawContext = do
drawLine true { x: relativeX, y: 0.0 } { x: relativeX, y: drawContext.canvasHeight } drawContext
drawLine true color { x: relativeX, y: 0.0 } { x: relativeX, y: drawContext.canvasHeight } drawContext
drawText (show value) 10.0 { x: relativeX, y: drawContext.canvasHeight - 12.0 } drawContext
where
relativeX = (x * drawContext.canvasWidth) / range

color = rgba 0.0 0.0 0.0 0.3

drawYGridLine :: Number -> Number -> Number -> DrawOperation
drawYGridLine y value range drawContext = do
drawLine true { x: 0.0, y: relativeY } { x: drawContext.canvasWidth, y: relativeY } drawContext
drawLine true color { x: 0.0, y: relativeY } { x: drawContext.canvasWidth, y: relativeY } drawContext
drawText (show value) 10.0 { x: drawContext.canvasWidth - 40.0, y: relativeY } drawContext
where
relativeY = drawContext.canvasHeight - ((y * drawContext.canvasHeight) / range)

color = rgba 0.0 0.0 0.0 0.3

drawPolygon :: Polygon -> DrawOperation
drawPolygon [] drawContext = pure unit

drawPolygon points drawContext = do
let
{ x: x1, y: y1 } = fromMaybe origin $ head points
beginPath drawContext.context
moveTo drawContext.context x1 y1
for_ (fromMaybe [] (tail points)) drawPolygonLine
fill drawContext.context
stroke drawContext.context
where
{ x: x1, y: y1 } = fromMaybe origin $ head points

drawPolygonLine :: Position -> Effect Unit
drawPolygonLine { x: xi, y: yi } = lineTo drawContext.context xi yi

drawEnclosure :: Boolean -> Array Polygon -> DrawOperation
drawEnclosure isSelected polygons =
withLocalDrawContext \drawContext -> do
if isSelected then do
setFillStyle drawContext.context $ toRGBA 255.0 192.0 203.0 0.7
setStrokeStyle drawContext.context $ toRGBA 0.0 0.0 0.0 1.0
setFillStyle drawContext.context $ show $ rgba 255.0 192.0 203.0 0.7
setStrokeStyle drawContext.context $ show $ rgba 0.0 0.0 0.0 1.0
else do
setFillStyle drawContext.context $ toRGBA 255.0 192.0 2013.0 0.4
setStrokeStyle drawContext.context $ toRGBA 0.0 0.0 0.0 0.7
setFillStyle drawContext.context $ show $ rgba 255.0 192.0 203.0 0.4
setStrokeStyle drawContext.context $ show $ rgba 0.0 0.0 0.0 0.7
for_ polygons (\polygon -> drawPolygon polygon drawContext)

drawRootEnclosure :: Number -> Number -> Number -> DrawOperation
Expand All @@ -103,11 +112,8 @@ drawRootEnclosure yZero l r =
lineTo drawContext.context r yZero
setLineWidth drawContext.context 5.0
setLineCap drawContext.context Round
setStrokeStyle drawContext.context $ toRGBA 255.0 0.0 0.0 1.0
setStrokeStyle drawContext.context $ show $ rgba 255.0 0.0 0.0 1.0
stroke drawContext.context

origin :: Position
origin = { x: 0.0, y: 0.0 }

toRGBA :: Number -> Number -> Number -> Number -> String
toRGBA r g b a = "rgb(" <> (show r) <> "," <> (show g) <> "," <> (show b) <> "," <> (show a) <> ")"
20 changes: 12 additions & 8 deletions src/Components/ExpressionInput/ExpressionInput.purs
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,21 @@ type ExpressionInputSlot p
type State
= { input :: String
, error :: Maybe String
, id :: Int
}

data ExpressionInputMessage
= Parsed Expression String
= Parsed Int Expression String

data Action
= Init
| HandleInput String
| Parse

expressionInputComponent :: forall query m. MonadEffect m => ExpressionInputController -> H.Component HH.HTML query String ExpressionInputMessage m
expressionInputComponent controller =
expressionInputComponent :: forall query m. MonadEffect m => ExpressionInputController -> Int -> H.Component HH.HTML query String ExpressionInputMessage m
expressionInputComponent controller id =
H.mkComponent
{ initialState
{ initialState: initialState id
, render
, eval:
H.mkEval
Expand All @@ -45,10 +46,11 @@ expressionInputComponent controller =
}
}

initialState :: String -> State
initialState input =
initialState :: Int -> String -> State
initialState id input =
{ input
, error: Nothing
, id
}

render :: forall slots m. State -> HH.ComponentHTML Action slots m
Expand Down Expand Up @@ -79,14 +81,16 @@ handleAction controller = case _ of
handleAction controller (HandleInput input)
pure unit
Parse -> do
{ input } <- H.get
{ input, id } <- H.get
let
result = controller.parse input
case result of
Left parseError -> H.modify_ _ { error = Just $ show parseError }
Right expression -> case checkExpression expression of
Left evaluationError -> H.modify_ _ { error = Just $ show evaluationError }
Right _ -> H.raise (Parsed expression input)
Right _ -> do
H.modify_ _ { error = Nothing }
H.raise (Parsed id expression input)
HandleInput input -> do
H.modify_ _ { input = input }
pure unit
Expand Down
Loading