{-# LANGUAGE TypeSynonymInstances, NoMonomorphismRestriction #-} {-| Import this module to generate charts using the Google Chart API. For more information about the Google Chart API, refer to - Chart API Intro - Getting Started For documentation full Haskell data model, refer to "Graphics.GChart.Types". Here is an example to use the functions in the module to generate a chart URL : @ generatePieChart = getChartUrl $ do setChartSize 640 400 setChartType Pie setChartTitle \"Test\" addChartData ([1,2,3,4,5]::[Int]) addColor \"FF0000\" setLegend $ legend [\"t1\",\"t2\", \"t3\",\"t4\",\"t5\"] setLabels $ [\"Test 1\", \"Test 2\", \"Test 3\", \"Test 4\", \"Test 5\"] @ For examples, refer to @Examples.hs@ in the source tarball, or download it directly from Github : . The module constists of: - Smart Constructors - to make it convenient to construct data types - Functions to set chart data - Functions to retrieve chart data in form of URL or Haskell data type -} module Graphics.GChart ( module Graphics.GChart.Types, -- * Smart Constructors solid , legend , legendWithPosition , makeAxis , makeGrid , simple , text , extended , automatic , automaticWithSpacing , barwidth , barwidthspacing , relative , makeShapeMarker , makeRangeMarker , makeFinancialMarker , makeLineMarker , makeLineStyle , -- * Setting Chart Parameters setChartSize , setChartHeight , setChartType , setChartTitle , setChartTitleWithColor , setChartTitleWithColorAndFontSize, setDataEncoding , addChartData , addDataScale , addChartDataXY , setColors , addColor , addFill , setLegend , addAxis , setGrid , addShapeMarker , addRangeMarker , addFinancialMarker , addLineMarker , addLineFill , setLabels , setLabel , setBarWidthSpacing , setPieChartOrientation , addLineStyle , setFormula , setQREncoding , setQRWidth , setQRErrorCorrection , -- * Retrieving Chart Data getChartData, getChartUrl, convertToUrl ) where import Graphics.GChart.Types import Graphics.GChart.ChartItems import Graphics.GChart.DataEncoding import Data.List -- | generates a 'Solid' fill from a hex color value solid :: Color -> FillType -> Fill solid color filltype = Fill (Solid color) filltype -- | generates a 'ChartLegend' from a list of labels legend :: [String] -> ChartLegend legend labels = Legend labels Nothing -- | generats a 'ChartLegend' from a list of lables and a 'LegendPosition' legendWithPosition :: [String] -> LegendPosition -> ChartLegend legendWithPosition labels position = Legend labels (Just position) {-| returns a default axis. Use this to override the fields with your own values. For e.g : @ makeAxis { 'axisType' = 'AxisTop', 'axisLabels' = [\"0\",\"50\",\"100\"] } @ -} makeAxis :: Axis makeAxis = defaultAxis {-| returns a default axis. Use this to override the fields with your own values. For e.g : @ makeGrid { 'xAxisStep' = 10, 'yAxisStep' = 10, xOffset = Just 5 } @ -} makeGrid :: ChartGrid makeGrid = defaultGrid -- | Use this to specify the 'Simple' encoding for the 'setDataEncoding' -- function. simple :: ChartData simple = Simple [] -- | Use this to specify the 'Text' encoding for the 'setDataEncoding' -- function. text :: ChartData text = Text [] -- | Use this to specify the 'Extended' encoding for the 'setDataEncoding' -- function. extended :: ChartData extended = Extended [] -- | Set automatic bar width for bar chart automatic :: BarChartWidthSpacing automatic = (Just Automatic,Nothing) -- | Set automatic bar width for bar chart, with spacing values automaticWithSpacing :: Int -> Int -> BarChartWidthSpacing automaticWithSpacing b g= (Just Automatic, Just (Fixed (b,g))) -- | Set bar width for chart barwidth :: Int -> BarChartWidthSpacing barwidth n = (Just (BarWidth n), Nothing) -- | Set bar width and spacing for chart barwidthspacing :: Int -> Int -> Int -> BarChartWidthSpacing barwidthspacing bw b g = (Just (BarWidth bw), Just (Fixed (b,g))) -- | Set relative spacing relative :: Float -> Float -> BarChartWidthSpacing relative b g = (Nothing, Just (Relative (b,g))) -- | Shape Marker makeShapeMarker :: ShapeMarker makeShapeMarker = defaultShapeMarker -- | Range Marker makeRangeMarker :: RangeMarker makeRangeMarker = defaultRangeMarker -- | Line Marker makeLineMarker :: LineMarker makeLineMarker = defaultLineMarker -- | Financial Marker makeFinancialMarker :: FinancialMarker makeFinancialMarker = defaultFinancialMarker -- | Line Style makeLineStyle :: LineStyle makeLineStyle = defaultLineStyle -- | Set the chart size by passing the width and the height in pixels -- For e.g : @setChartSize 320 200@ setChartSize :: Int -> Int -> ChartM () setChartSize w h = set (Size w h) -- | Set chart height only. Applicable to 'Formula' charts -- This will set the width to 0 which will automatically -- be excluded when the data is being encoded setChartHeight :: Int -> ChartM () setChartHeight h = set (Size 0 h) -- | Set the chart type by passing a 'ChartType' setChartType :: ChartType -> ChartM () setChartType = set -- | Set the chart title by passing a 'ChartTitle' setChartTitle :: String -> ChartM () setChartTitle title = set $ ChartTitle title Nothing Nothing -- | Set the chart title with a color setChartTitleWithColor :: String -> Color -> ChartM() setChartTitleWithColor title color = set $ ChartTitle title (Just color) Nothing -- | Set the chart title with color and font size setChartTitleWithColorAndFontSize :: String -> Color -> FontSize -> ChartM () setChartTitleWithColorAndFontSize title color fontsize = set $ ChartTitle title (Just color) (Just fontsize) {-| Use this with 'simple', 'text' or 'extended' to specify the encoding. For e.g @ setDataEncoding simple @ Make sure you pass in values of the right type, Int for simple and extended encoding, and Float for text encoding. -} setDataEncoding :: ChartData -> ChartM () setDataEncoding = set {-| Add data to chart. Make sure you have set the data encoding using 'setDataEncoding' before calling this function, otherwise it may generate gibberish, or throw an error -} addChartData :: ChartDataEncodable a => [a] -> ChartM () addChartData = addDataToChart -- | Add a scale to chart.If more than one scale is added, it applies -- the scale in order to each data series addDataScale :: DataScale -> ChartM () addDataScale = addScaleToChart -- | Works like 'addChartData', but for XY datasets for line XY chart etc addChartDataXY :: ChartDataEncodable a => [(a,a)] -> ChartM () addChartDataXY series = do addDataToChart xseries addDataToChart yseries where xseries = map fst series yseries = map snd series -- | Pass a list of colors corresponding to the datasets in the chart setColors :: [Color] -> ChartM () setColors = set . ChartColors {-| Add a color to the chart. This color will be added to the list 'ChartColors'. Make sure you do not include a call to 'setColors' at any time after a call to 'addColor', since this will lead to all previous values being erased. -} addColor :: Color -> ChartM() addColor = addColorToChart -- | Add a 'Fill' to the chart addFill :: Fill -> ChartM () addFill = addFillToChart -- | Set a Legend for the chart setLegend :: ChartLegend -> ChartM () setLegend = set -- | Add an 'Axis' to the chart addAxis :: Axis -> ChartM () addAxis = addAxisToChart -- | Set a 'ChartGrid' for the chart setGrid :: ChartGrid -> ChartM () setGrid = set -- | Adds a shape marker. Use `makeShapeMarker` smart constructor when calling -- this function If value of data set index is not specified when using -- 'makeShapeMarker', it automatically adds a data index to refer to the latest -- data set addShapeMarker :: ShapeMarker -> ChartM () addShapeMarker marker | shapeDataSetIdx marker > (- 1) = addMarker marker | otherwise = do idx <- getDataSetIdx let newmarker = marker { shapeDataSetIdx = idx } addMarker marker -- | Adds a range marker. You can use 'makeRangeMarker' smart constructor when -- calling this function addRangeMarker :: RangeMarker -> ChartM () addRangeMarker = addMarker -- | Adds a financial marker. Use 'makeFinancialMarker' smart constructor when -- calling this function. If value of data set index is not specified when using -- 'makeFinancialMarker', it automatically adds a data index to refer to the latest -- data set addFinancialMarker :: FinancialMarker -> ChartM () addFinancialMarker marker | financeDataSetIdx marker > (- 1) = addMarker marker | otherwise = do idx <- getDataSetIdx let newmarker = marker { financeDataSetIdx = idx } addMarker newmarker -- | Adds a line marker. Use 'makeLineMarker' smart constructor when calling -- this function. If value of data set index is not specified when using -- 'makeLineMarker', it automatically adds a data index to refer to the -- latest data set addLineMarker :: LineMarker -> ChartM () addLineMarker marker | lineDataSetIdx marker > (- 1) = addMarker marker | otherwise = do idx <- getDataSetIdx let newmarker = marker { lineDataSetIdx = idx } addMarker newmarker -- | Adds a line fill to the chart addLineFill :: LineFillType -> Color -> ChartM () addLineFill fillType color = addMarker (LineFillMarker fillType color) -- | Set labels for the chart setLabels :: [String] -> ChartM () setLabels = set . ChartLabels -- | Set label for a chart setLabel :: String -> ChartM () setLabel label = set $ ChartLabels [label] -- | Set bar and width spacing setBarWidthSpacing :: BarChartWidthSpacing -> ChartM () setBarWidthSpacing = set -- | Set pie chart orientation in radians setPieChartOrientation :: Float -> ChartM () setPieChartOrientation = set . PCO -- | Add line style addLineStyle :: LineStyle -> ChartM() addLineStyle = addLineStyleToChart -- | Set formula. Applies only to 'Formula' charts setFormula :: String -> ChartM () setFormula formula = setLabels [formula] -- | Set QR code output encoding. Valid for 'QRCode' only setQREncoding :: QREncoding -> ChartM () setQREncoding = set -- | Sets the error correction level for 'QRCode' setQRErrorCorrection :: ErrorCorrectionLevel -> ChartM () setQRErrorCorrection ec = set qrLabelData where qrLabelData = QRLabelData ec defMargin QRLabelData _ defMargin = defaultQREncodingLabelData -- | Sets the width (in rows) of the white border around the data portion of the 'QRCode' setQRWidth :: Int -> ChartM () setQRWidth m = set qrLabelData where qrLabelData = QRLabelData defEC m QRLabelData defEC _ = defaultQREncodingLabelData -- | Extracts the data out of the monad and returns a value of type 'Chart' getChartData :: ChartM () -> Chart getChartData = getChartDataFromChartM -- | Extracts the data out of the monad and returns a URL string for the chart getChartUrl :: ChartM () -> String getChartUrl = convertToUrl . getChartData -- | Converts a value of type 'Chart' to a URL convertToUrl :: Chart -> String convertToUrl chart = baseURL ++ intercalate "&" urlparams where baseURL = "http://chart.apis.google.com/chart?" urlparams = [urlEnc a ++ "=" ++ urlEnc b | (a,b) <- getParams chart]