module Data.GPS.Gps2HtmlReport.JourneyCharts (
renderToPng,
chart1,
chart2
)where
import Data.GPS
import Data.Maybe
import Graphics.Rendering.Chart
import Data.Accessor
import Data.Colour
import Data.Colour.Names
import Data.Time.LocalTime
import Data.GPS.Gps2HtmlReport.JourneyStats (ptsElevation,avrSpeedOverTime,accumDistance,findPoint)
data OutputType = Window | PNG | PS | PDF | SVG
chooseLineWidth Window = 1.0
chooseLineWidth PNG = 1.0
chooseLineWidth PDF = 0.25
chooseLineWidth PS = 0.25
chooseLineWidth SVG = 0.25
speedAndElevationOverTimeChart :: [WptType] -> OutputType -> Renderable ()
speedAndElevationOverTimeChart points otype = toRenderable layout
where
layout = layout1_title ^="Speed, Average Speed & Elevation"
$ layout1_title_style ^= defaultFontStyle { font_size_ = 12.0 }
$ layout1_background ^= solidFillStyle (opaque white)
$ layout1_right_axis ^= defaultLayoutAxis { laxis_title_ = "Elevation (metres)", laxis_override_ = axisGridHide }
$ layout1_left_axis ^: laxis_title ^= "Speed (metres)"
$ layout1_plots ^= [ Right (toPlot elevationArea),
Left (toPlot speedLine),
Left (toPlot avrSpeedLine)
]
$ setLayout1Foreground fg
defaultLayout1
lineStyle c = line_width ^= 1 * chooseLineWidth otype
$ line_color ^= c
$ defaultPlotLines ^. plot_lines_style
theSpeeds = [(utcToLocalTime utc theTime,spd) | (theTime,spd) <- avgSpeeds 10 points]
speedLine = plot_lines_style ^= lineStyle (opaque blue)
$ plot_lines_values ^= [[ (theTime,speed) | (theTime,speed) <- theSpeeds]]
$ plot_lines_title ^= "Speed"
$ defaultPlotLines
avrSpeedLine = plot_lines_style ^= lineStyle (red `withOpacity` 0.5)
$ plot_lines_values ^= [[ (theTime,speed) | (theTime,speed) <- avrSpeedOverTime theSpeeds 0.0 0.0 []]]
$ plot_lines_title ^= "Avr Speed"
$ defaultPlotLines
elevationArea = plot_fillbetween_style ^= solidFillStyle (green `withOpacity` 0.1)
$ plot_fillbetween_values ^= [ (theTime,(0,elevation)) | (theTime,elevation) <- ptsElevation points]
$ plot_fillbetween_title ^= "Elevation"
$ defaultPlotFillBetween
fg = opaque black
accumDistanceAndElevationChart :: [WptType] -> OutputType -> Renderable ()
accumDistanceAndElevationChart points otype = toRenderable layout
where
layout = layout1_title ^="Accumulative Distance & Elevation"
$ layout1_title_style ^= defaultFontStyle { font_size_ = 12.0 }
$ layout1_background ^= solidFillStyle (opaque white)
$ layout1_right_axis ^= defaultLayoutAxis { laxis_title_ = "Distance (metres)", laxis_override_ = axisGridHide }
$ layout1_left_axis ^: laxis_title ^= "Elevation (metres)"
$ layout1_plots ^= [ Right (toPlot accumDistanceArea),
Left (toPlot elevationLine),
Left (toPlot spots)
]
$ setLayout1Foreground fg
defaultLayout1
lineStyle c = line_width ^= 1 * chooseLineWidth otype
$ line_color ^= c
$ defaultPlotLines ^. plot_lines_style
elevationLine = plot_lines_style ^= lineStyle (opaque black)
$ plot_lines_values ^= [[ (theTime,elevation) | (theTime,elevation) <- ptsElevation points]]
$ plot_lines_title ^= "Elevation"
$ defaultPlotLines
accumDistanceArea = plot_fillbetween_style ^= solidFillStyle (red `withOpacity` 0.2)
$ plot_fillbetween_values ^= [ (theTime,(0,accumDist)) | (theTime,accumDist) <- accumDistance points 0.0]
$ plot_fillbetween_title ^= "Distance"
$ defaultPlotFillBetween
spotMaxPoint = let point = findPoint points (head points) ele (>)
in (if isJust point then Just (fst $ fromJust point, snd $ fromJust point, 5 :: Double) else Nothing)
spotMinPoint = let point = findPoint points (head points) ele (<)
in (if isJust point then Just (fst $ fromJust point, snd $ fromJust point, 5 :: Double) else Nothing)
spots = area_spots_title ^= "Altitude"
$ area_spots_max_radius ^= 5
$ area_spots_values ^= (if isJust spotMinPoint && isJust spotMaxPoint then [fromJust spotMinPoint,fromJust spotMaxPoint] else [])
$ defaultAreaSpots
fg = opaque black
renderToPng :: (t, OutputType -> Renderable a) -> FilePath -> IO (PickFn a)
renderToPng (_,ir) = renderableToPNGFile (ir Window) 384 288
chart1 :: [WptType] -> (String, OutputType -> Renderable ())
chart1 points = ("speedAndElevationOverTimeChart", speedAndElevationOverTimeChart points)
chart2 :: [WptType] -> (String, OutputType -> Renderable ())
chart2 points = ("accumDistanceAndElevationChart", accumDistanceAndElevationChart points)