lhae-0.0.2: src/Controller/Menu/File/Export/Diagram/BoxPlot.hs
module Controller.Menu.File.Export.Diagram.BoxPlot (eventHandler)
where
import Control.Applicative ((<$>))
import Control.Monad (when)
import Text.Printf (printf)
import Data.List (sort)
import Controller (Controller,getFromConfig,onView
,onGridView,setOnConfig)
import Controller.Menu.File.Export.Diagram.BoxPlotParameters (Parameters(..))
import qualified Controller.Menu.File.Export.Diagram.Common as Common
import Controller.Dialog (nonNumericDataWarningText
,noColumnsSelectedText,saveFileDialog)
import Config (boxPlotExportParameters)
import View.Component.Grid (getColumnLabels)
import View.Dialog.Complex (Layout (..),Widget (..),Modifier (..)
,showDialog,cancelButton)
import Util.FileType (justPngWildcard)
import qualified Model.CellExpression.Evaluator.Math as Math
import I18n (__)
data Action = Preview | Export
eventHandler :: Controller ()
eventHandler = getFromConfig boxPlotExportParameters
>>= \params -> eventHandlerWith $ params {columns = []}
eventHandlerWith :: Parameters -> Controller ()
eventHandlerWith initParams = do
result <- do d <- dialog <$> onGridView getColumnLabels
onView $ showDialog (__ "Export") d initParams
case result of
Nothing -> return ()
Just (params,Export) ->
do saveFile <- saveFileDialog (__ "Export") justPngWildcard
setOnConfig $ \c -> c {boxPlotExportParameters = params}
case saveFile of
Nothing -> eventHandlerWith params
Just imageFilePath ->
do success <- Common.plot (gpFileContent params)
(dataFileContent params) imageFilePath
when (not success) $ eventHandlerWith params
Just (params,Preview) ->
do setOnConfig $ \c -> c {boxPlotExportParameters = params}
_ <- Common.showPreview (gpFileContent params)
(dataFileContent params)
eventHandlerWith params
dialog :: [String] -> Layout Parameters Action
dialog columnLabels =
let setCols p cols = p {columns = cols}
setBoxWidth p w = p {boxWidth = w}
setGaps p g = p {gaps = g}
in
Modifier Margin $ Column
[ Row [ Grid [[ Label $ __ "Box width"
, Widget $ NumberEntry boxWidth setBoxWidth]
,[ Label $ __ "Gaps"
, Widget $ Spinner 1 maxBound gaps setGaps]
]
, Modifier Center $ Modifier (Boxed $ __ "Columns")
$ Widget $ MultiListBox columnLabels columns setCols
]
, Modifier Center $ Row
[ Widget $ DefaultButton (__ "&Export") Export
, Widget $ Button (__ "&Preview") Preview
, cancelButton]]
dataFileContent :: Parameters -> Controller (Either String String)
dataFileContent (Parameters {columns = []}) = return $ Left noColumnsSelectedText
dataFileContent (Parameters {columns = cols,gaps = gaps}) = do
numericColumns <- Common.getNumericColumns cols
case numericColumns of
Left nonNumeric -> return $ Left $ nonNumericDataWarningText nonNumeric
Right columns ->
let toLine (i,(label,values)) =
let sorted = sort values
max = maximum sorted
min = head sorted
firstQuartile = Math.firstQuartileSorted sorted
thirdQuartile = Math.thirdQuartileSorted sorted
median = Math.medianSorted sorted
values' = [firstQuartile,min,max,thirdQuartile,median]
in unwords $ [show label,show i] ++ (map show values')
in
return $ Right $ unlines $ map toLine $ zip [0,gaps..] columns
gpFileContent :: Parameters -> FilePath -> String
gpFileContent params dataFilePath =
printf (unlines
[ "set key off"
, "set xrange [%d:%d]"
, "set boxwidth %f"
, "plot '%s' using 2:3:4:5:6:xtic(1) with candlesticks whiskerbars,"
++ "'' using 2:7:7:7:7 with candlesticks"
])
(-(gaps params)) (length (columns params) + (gaps params) - 1)
(boxWidth params) dataFilePath