hs-gchart (empty) → 0.1
raw patch · 9 files changed
+1198/−0 lines, 9 filesdep +basedep +mtlsetup-changed
Dependencies added: base, mtl
Files
- Graphics/GChart.hs +216/−0
- Graphics/GChart/ChartItems.hs +282/−0
- Graphics/GChart/DataEncoding.hs +52/−0
- Graphics/GChart/Types.hs +340/−0
- LICENSE +26/−0
- README.md +154/−0
- Setup.hs +3/−0
- examples/Examples.hs +106/−0
- hs-gchart.cabal +19/−0
+ Graphics/GChart.hs view
@@ -0,0 +1,216 @@+{-# LANGUAGE TypeSynonymInstances, NoMonomorphismRestriction #-}+{-|++Import this module to generate charts using the Google Chart API.++For more examples, refer to @Examples.hs@ in the source tarball, or download it+directly from Github : <http://github.com/hs-gchart/>.++For documentation regarding the full data model, refer to +"Graphics.GChart.Types".++For more information about the Google Chart API, refer to+<http://code.google.com/apis/chart/>++-}+module Graphics.GChart ( + module Graphics.GChart.Types,++ -- * Setting Chart Parameters+ {-| ++Use these functions to set the parameters of the chart.++These functions must be called inside a @do@ block, which can then be passed+onto 'getChartUrl' or 'getChartData'. For e.g, here is a simple pie chart function++@+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\"]+@++-} + setChartSize, setChartType, setDataEncoding, setChartTitle,addChartData, addChartDataXY, setColors, addColor, addFill,+ setLegend, addAxis, setGrid, setLabels,+ -- * Retrieving Chart data+ getChartData, getChartUrl, convertToUrl,++ -- * Smart Constructors + -- | These functions can be used to construct chart+ -- parameters more conveniently+ solid, legend, legendWithPosition, makeAxis, makeGrid,+ simple,text,extended+) where++import Graphics.GChart.Types+import Graphics.GChart.ChartItems+import Graphics.GChart.DataEncoding++import Data.List++{- Smart Constructors -}++-- | generates a 'Solid' fill from a hex color value+solid = Fill . Solid++-- | 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 []++{- Setting Chart Parameters-}++-- | 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 the chart type by passing a 'ChartType'+setChartType :: ChartType -> ChartM ()+setChartType = set++-- | Set the chart title by passing a 'ChartTitle'+setChartTitle :: String -> ChartM ()+setChartTitle = set++{-| Use it 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++-- | 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++-- | Set labels for the chart+setLabels :: [String] -> ChartM ()+setLabels = set . ChartLabels++{- Retrieving Chart Data -}++-- | 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]++debugPieChart = 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"]++debugBarChart = getChartUrl $ do setChartSize 640 400+ setChartType BarVerticalGrouped+ setDataEncoding text+ addChartData ([100,200,300,400,500]::[Float])+ addChartData ([3,4,5,6,7]::[Float])+ addChartData ([4.0,5.0,6.0,7.0,8]::[Float])+ addAxis $ makeAxis { axisType = AxisLeft,axisLabels = Just ["0","100"] }+ setColors ["FF0000","00FF00","0000FF"]+ setLegend $ legend ["Set 1", "Set 2", "Set 3"]
+ Graphics/GChart/ChartItems.hs view
@@ -0,0 +1,282 @@+{-# LANGUAGE TypeSynonymInstances, NoMonomorphismRestriction #-}+{-# OPTIONS_HADDOCK hide #-}+module Graphics.GChart.ChartItems (+ ChartM,+ ChartItem, set,+ ChartDataEncodable,+ getChartDataFromChartM,+ addDataToChart,+ addColorToChart,+ addFillToChart,+ addAxisToChart,+ getParams+) where++import Graphics.GChart.Types+import Graphics.GChart.DataEncoding++import Control.Monad.State+import Data.List+import Data.Maybe++-- Monad+type ChartM a = State Chart a++-- Typeclass abstracting all the fields in a chart+class ChartItem c where+ -- set the field+ set :: c -> ChartM ()+ -- encode the field into string params+ encode :: c -> [(String,String)]+++-- Setting/Encoding Chart Data++updateChart u = do chart <- get+ put $ u chart++asList a = [a]++getChartDataFromChartM m = execState m defaultChart++-- size+instance ChartItem ChartSize where+ set size = updateChart $ \chart -> chart { chartSize = size }++ encode size = asList ("chs", show width ++ "x" ++ show height) where+ Size width height = size+++-- type+instance ChartItem ChartType where+ set cType = updateChart $ \chart -> chart { chartType = cType }++ encode cType = asList ("cht",t)+ where t = case cType of+ Line -> "lc"+ LineXY -> "lxy"+ Sparklines -> "ls"+ Pie -> "p"+ Pie3D -> "p3"+ PieConcentric -> "pc"+ BarHorizontalStacked -> "bhs"+ BarVerticalStacked -> "bvs"+ BarHorizontalGrouped -> "bhg"+ BarVerticalGrouped -> "bvg"+ Venn -> "v"+ ScatterPlot -> "s"+ Radar -> "r"+ GoogleOMeter -> "gom"++-- title+instance ChartItem ChartTitle where+ set title = updateChart $ \chart -> chart { chartTitle = Just title }++ encode title = asList ("chtt", title)+++-- data+-- FIXME just a placeholder for now+instance ChartItem ChartData where+ set cData = updateChart $ \chart -> chart { chartData = cData }++ encode datas = asList ("chd", encodeData datas)+ where encodeData (Simple d) = encodeSimple d+ encodeData (Text d) = encodeText d+ encodeData (Extended d) = encodeExtended d+++class Num a => ChartDataEncodable a where+ addEncodedChartData :: [a] -> ChartData -> ChartData++instance ChartDataEncodable Int where+ addEncodedChartData d cd@(Simple old) = Simple $ old ++ [d]+ addEncodedChartData d cd@(Extended old) = Extended $ old ++ [d]+ addEncodedChartData d _ = error "Invalid type for specified encoding. Use float data"++instance ChartDataEncodable Float where+ addEncodedChartData d cd@(Text old) = Text $ old ++ [d]+ addEncodedChartData d _ = error "Invalid type for specified encoding. Use int data"++addDataToChart d = do c <- get+ let old = chartData c+ set $ addEncodedChartData d old++-- color++instance ChartItem ChartColors where+ set colors = updateChart $ \chart -> chart { chartColors = Just colors }++ encode (ChartColors colors) = asList ("chco", intercalate "," colors)++++addColorToChart color = do chart <- get+ let (ChartColors old) = fromMaybe (ChartColors []) $ chartColors chart+ new = ChartColors $ old ++ [color]+ set new++-- fill++instance ChartItem ChartFills where+ set fills = updateChart $ \chart -> chart { chartFills = Just fills }++ encode fills = asList ("chf",intercalate "|" $ map encodeFill fills)+++encodeFill (Fill kind fType) = case kind of+ Solid color -> intercalate "," [fillType,"s",color]++ LinearGradient angle offsets -> intercalate "," [fillType,+ "lg",+ show angle,+ intercalate "," $ map (\(c,o) -> c ++ "," ++ show o ) offsets]++ LinearStripes angle widths -> intercalate "," [fillType,+ "ls",+ show angle,+ intercalate "," $ map (\(c,w) -> c ++ "," ++ show w) widths]+ where fillType = case fType of+ Background -> "bg"+ Area -> "c"+ Transparent -> "a"+++addFillToChart fill = do chart <- get+ let fills = fromMaybe [] $ chartFills chart+ newFills = fills ++ asList fill+ set newFills+++-- legend++instance ChartItem ChartLegend where+ set legend = updateChart $ \chart -> chart { chartLegend = Just legend }++ encode (Legend labels position) = encodeTitle : encodePosition position where+ encodeTitle = ("chdl", intercalate "|" labels)+ encodePosition Nothing = []+ encodePosition (Just p) = let pos = case p of+ LegendBottom -> "b"+ LegendTop -> "t"+ LegendVBottom -> "bv"+ LegendVTop -> "tv"+ LegendRight -> "r"+ LegendLeft -> "l"+ in asList ("chdlp",pos)++-- AXIS+instance ChartItem ChartAxes where+ set axes = updateChart $ \chart -> chart { chartAxes = Just axes }++ encode axes = filter (/= ("","")) $ map (\f -> f axes) [encodeAxesTypes,+ encodeAxesLabels,+ encodeAxesPositions,+ encodeAxesRanges,+ encodeAxesStyles]++addAxisToChart axis = do chart <- get+ let old = fromMaybe [] $ chartAxes chart+ new = old ++ [axis]+ set new+++convertFieldToString encoder field = intercalate "|" .+ map encoder .+ filter (\(_,maybeField) -> maybeField /= Nothing) .+ indexed . map field++indexed = zip [0..]++encodeFieldToParams fieldParam fieldStr | fieldStr == "" = ("","")+ | otherwise = (fieldParam, fieldStr)++encodeAxesTypes axes = ("chxt",a) where+ a = intercalate "," $ map toParam axes+ toParam axes = case axisType axes of+ AxisBottom -> "x"+ AxisTop -> "t"+ AxisLeft -> "y"+ AxisRight -> "r"++-- axis labels+strAxisLabels (idx,Just labels) = show idx ++ ":|" ++ intercalate "|" labels++strAxesLabels = convertFieldToString strAxisLabels axisLabels++encodeAxesLabels = encodeFieldToParams "chxl" . strAxesLabels++-- axis positions+strAxisPositions (idx, Just positions) = show idx ++ "," ++ intercalate "," (map show positions)++strAxesPositions = convertFieldToString strAxisPositions axisPositions++encodeAxesPositions = encodeFieldToParams "chxp" . strAxesPositions++-- axis ranges+strAxisRange (idx, Just range) = show idx ++ "," ++ intercalate "," (encodeRange range)+ where encodeRange (Range (start,end) interval) | interval == Nothing = [show start, show end]+ | otherwise = [show start, show end, show (fromJust interval)]++strAxesRanges = convertFieldToString strAxisRange axisRange++encodeAxesRanges = encodeFieldToParams "chxr" . strAxesRanges++-- axis style+strAxisStyle (idx, Just style) = show idx ++ "," ++ intercalate "," (catMaybes (encodeStyle style))+ where encodeStyle (Style a b c d e) = [Just a,+ liftM show b,+ liftM encodeAlign c,+ liftM encodeDrawingControl d,+ liftM id e]+ encodeAlign c = case c of+ AxisStyleLeft -> "-1"+ AxisStyleCenter -> "0"+ AxisStyleRight -> "1"+ encodeDrawingControl d = case d of+ DrawLines -> "l"+ DrawTicks -> "t"+ DrawLinesTicks -> "lt"++strAxesStyles = convertFieldToString strAxisStyle axisStyle++encodeAxesStyles = encodeFieldToParams "chxs" . strAxesStyles+++-- GRID+instance ChartItem ChartGrid where+ set grid = updateChart $ \chart -> chart { chartGrid = Just grid }++ encode grid = asList ("chg", encodeGrid grid) where+ encodeGrid (ChartGrid a b c d e f)= intercalate "," $ catMaybes [Just (show a),+ Just (show b),+ liftM show c,+ liftM show d,+ liftM show e,+ liftM show f]++-- LABELS (Pie Chart, Google-O-Meter+instance ChartItem ChartLabels where+ set labels = updateChart $ \chart -> chart { chartLabels = Just labels }++ encode (ChartLabels labels) = asList ("chl", intercalate "|" labels)+++++-- URL Conversion+-- FIXME : too much boilerplate. Can it be reduced?+encodeMaybe Nothing = [("","")]+encodeMaybe (Just x) = encode x++getParams chart = filter (/= ("","")) $ concat [encode $ chartType chart,+ encode $ chartSize chart,+ encode $ chartData chart,+ encodeMaybe $ chartTitle chart,+ encodeMaybe $ chartColors chart,+ encodeMaybe $ chartFills chart,+ encodeMaybe $ chartLegend chart,+ encodeMaybe $ chartAxes chart,+ encodeMaybe $ chartGrid chart,+ encodeMaybe $ chartLabels chart]+
+ Graphics/GChart/DataEncoding.hs view
@@ -0,0 +1,52 @@+{-# OPTIONS_HADDOCK hide #-}+module Graphics.GChart.DataEncoding where++import Graphics.GChart.Types++import Data.List+import Data.Char (chr, ord)+import Numeric (showHex)+++-- Data Encodings++encodeSimple :: [[Int]] -> String+encodeSimple datas = "s:" ++ intercalate "," (map (map enc) datas) where+ enc :: Int -> Char+ enc i | i >= 0 && i <= 25 = chr (ord 'A' + i)+ | i >= 26 && i <= 51 = chr (ord 'a' + (i - 26))+ | i >= 52 && i <= 61 = chr (ord '0' + (i - 52))+ | otherwise = '_'+++encodeText datas = "t:" ++ intercalate "|" (map encData datas) where+ encData = intercalate "," . map encDatum+ encDatum i | i >= 0 && i <= 100 = showDecimal i+ | otherwise = "-1"+ showDecimal :: Float -> String+ showDecimal i | ((makeFloat (truncate i)) - i) == 0 = show $ truncate i+ | otherwise = show (fromIntegral (round (i * 10.0)) / 10.0)+ makeFloat i = fromIntegral i :: Float++encodeExtended datas = "e:" ++ intercalate "," (map (concatMap encDatum) datas) where+ encDatum i | i >= 0 && i < 4096 = let (a, b) = i `quotRem` 64 in+ [encChar a, encChar b]+ | otherwise = "__"+ encChar i | i >= 0 && i <= 25 = chr (ord 'A' + i)+ | i >= 26 && i <= 51 = chr (ord 'a' + (i - 26))+ | i >= 52 && i <= 61 = chr (ord '0' + (i - 52))+ | i == 62 = '-'+ | i == 63 = '.'+++-- | URL-encode a string.+urlEnc str = concatMap enc str where+ enc c | c >= 'A' && c <= 'Z' = [c]+ | c >= 'a' && c <= 'z' = [c]+ | c >= '0' && c <= '9' = [c]+ | c `elem` safe = [c]+ | c == ' ' = "+"+ | otherwise = '%': showHex (ord c) ""+ -- Argh, different resources differ on which characters need escaping.+ -- This is likely wrong.+ safe = "$-_.!*'(),|:"
+ Graphics/GChart/Types.hs view
@@ -0,0 +1,340 @@+{-| This module contains the Haskell data model for the Google Chart API.++Details about the parameters can be found on the Google Chart API website :+<http://code.google.com/apis/chart/>++Some chart types are not supported yet :++- Maps <http://code.google.com/apis/chart/types.html#maps>++- QRCodes <http://code.google.com/apis/chart/types.html#qrcodes>++Some parameters are not supported yet :++- Data Scaling <http://code.google.com/apis/chart/formats.html#data_scaling>++- Shape markers <http://code.google.com/apis/chart/styles.html#shape_markers>++- Range markers <http://code.google.com/apis/chart/styles.html#range_markers>++- Financial markers <http://code.google.com/apis/chart/styles.html#financial_markers>++- Line Styles <http://code.google.com/apis/chart/styles.html#line_styles>++- Fill area <http://code.google.com/apis/chart/colors.html#fill_area_marker>++- Bar width and spacing <http://code.google.com/apis/chart/styles.html#bar_width>++- Bar chart zero line <http://code.google.com/apis/chart/styles.html#zero_line>++- Data point labels <http://code.google.com/apis/chart/labels.html#data_point_labels>++- Chart margins <http://code.google.com/apis/chart/styles.html#chart_margins>++- Chart title color and font customisation <http://code.google.com/apis/chart/labels.html#chart_title>++- Pie chart orientation <http://code.google.com/apis/chart/types.html#pie_charts>++-}++module Graphics.GChart.Types (+ -- * Chart data+ -- | This type represents the Chart+ Chart(..),++ -- * Required Parameters+ -- | These parameters are required for all charts++ -- ** Chart Size+ ChartSize(..),+ -- ** Chart Data+ ChartData(..),+ -- ** Chart Type+ ChartType(..),++ -- * Optional Parameters+ -- | All other parameters are optional++ -- ** Chart Colors+ ChartColors(..), Color,++ -- ** Solid Fill, Linear Gradient, Linear Stripes+ ChartFills, Fill(..), FillKind(..), FillType(..),+ Offset, Width, Angle,+ -- ** Chart Title+ ChartTitle,++ -- ** Chart Legend+ ChartLegend(..), LegendPosition(..),++ -- ** Axis styles and labels+ ChartAxes, Axis(..), AxisType(..), AxisLabel, AxisPosition, FontSize,+ AxisRange(..), AxisStyle(..), DrawingControl(..), AxisStyleAlignment(..),++ -- ** Grid Lines+ ChartGrid(..),++ -- ** Pie chart and Google-o-meter labels+ ChartLabels(..),++ -- * Default Values+ {-| These functions return default values for complex parameters, which can be+ used as starting points to construct parameters when creating charts. -}+ defaultChart, defaultAxis, defaultGrid+) where++++-- | Size of the chart. width and height specified in pixels+data ChartSize = Size Int Int deriving Show+++-- | Chart type <http://code.google.com/apis/chart/types.html>+data ChartType+ = Line -- ^ Line Chart+ | Sparklines -- ^ Sparklines+ | LineXY -- ^ Line Chart w/ XY co-ordinates+ | BarHorizontalStacked -- ^ Horizontal bar chart w/ stacked bars+ | BarVerticalStacked -- ^ Vertical bar chart w/ stacked bars+ | BarHorizontalGrouped -- ^ Horizontal bar chart w/ grouped bars+ | BarVerticalGrouped -- ^ Vertical bar chart w/ grouped bars+ | Pie -- ^ Two dimensional pie chart+ | Pie3D -- ^ Three dimensional pie chart+ | PieConcentric -- ^ Concentric pie chart+ | Venn -- ^ Venn Diagram+ | ScatterPlot -- ^ Scatter Plot+ | Radar -- ^ Radar Chart+ | GoogleOMeter -- ^ Google-o-meter+ deriving Show++-- | Title of the chart+-- | <http://code.google.com/apis/chart/labels.html#chart_title>+type ChartTitle = String+++-- | Chart data along with encoding. XY data for is encoded a pair of+-- | consecutive data sets+-- | <http://code.google.com/apis/chart/formats.html>+data ChartData+ = Simple [[Int]] -- ^ Simple - lets you specify integer values from 0—61, inclusive+ | Text [[Float]] -- ^ Text - supports floating point numbers from 0—100, inclusive+ | Extended [[Int]] -- ^ Extended - lets you specify integer values from 0—4095, inclusive+ deriving Show++-- | Color data specified as a hex string+type Color = String++-- | Chart colors specified as a list of 'Color' values for each data point.+-- | <http://code.google.com/apis/chart/colors.html#chart_colors>+data ChartColors = ChartColors [Color] deriving Show+++-- | Specifies the angle of the gradient between 0 (horizontal) and 90+-- | (vertical). Applicable to 'LinearGradient' and 'LinearStripes'+type Angle = Float++-- | Specifies at what point the color is pure. In this parameter, 0 specifies+-- | the right-most chart position and 1 specifies the left-most chart+-- | position. Applicable to 'LinearGradient'+type Offset = Float++-- | Width of the stripe. must be between 0 and 1, where 1 is the full width of+-- | the chart+type Width = Float++-- | Specifies the kind of fill+data FillKind+ = Solid Color -- ^ Solid Fill <http://code.google.com/apis/chart/colors.html#solid_fill>+ | LinearGradient Angle [(Color,Offset)] -- ^ Linear Gradient <http://code.google.com/apis/chart/colors.html#linear_gradient>+ | LinearStripes Angle [(Color,Width)] -- ^ Linear Stripes <http://code.google.com/apis/chart/colors.html#linear_stripes>+ deriving Show++-- | Specifies the type of fill+data FillType+ = Background -- ^ Background fill+ | Area -- ^ Chart area fill+ | Transparent -- ^ Apply transparency to whole chart (applicable to 'Solid' fill only)+ deriving Show++-- | Constructor for a chart fill+data Fill = Fill FillKind FillType deriving Show++-- | Chart fills, as a list of `Fill's+type ChartFills = [Fill]++-- | Position of legend on chart. Applies to 'ChartLegend'+data LegendPosition+ = LegendBottom -- ^ Bottom of chart, horizontally+ | LegendTop -- ^ Top of chart, horizontally+ | LegendVBottom -- ^ Bottom of chart, vertically+ | LegendVTop -- ^ Bottom of chart, vertically+ | LegendRight -- ^ Left of chart+ | LegendLeft -- ^ Right of chart+ deriving Show++-- | Specifies a chart legend+-- | <http://code.google.com/apis/chart/labels.html#chart_legend>+data ChartLegend = Legend [String] (Maybe LegendPosition) deriving Show++-- | Type of 'Axis'+-- | <http://code.google.com/apis/chart/labels.html#axis_type>+data AxisType+ = AxisBottom -- ^ Bottom x-axis+ | AxisTop -- ^ Top x-axis+ | AxisLeft -- ^ Left y-axis+ | AxisRight -- ^ Right y-axis+ deriving Show++-- | 'Axis' Labels.+-- | <http://code.google.com/apis/chart/labels.html#axis_labels>+type AxisLabel = String++{-| 'Axis' Label Positions. <http://code.google.com/apis/chart/labels.html#axis_label_positions>++Labels with a specified position of 0 are placed at the bottom of the y- or+r-axis, or at the left of the x- or t-axis.++Labels with a specified position of 100 are placed at the top of the y- or+r-axis, or at the right of the x- or t-axis.++-}+type AxisPosition = Float++{-| 'Axis' Range <http://code.google.com/apis/chart/labels.html#axis_range>++The range is specifies with a tuple containing the start and end values. An+optional interval value can be specified.++-}+data AxisRange = Range (Float,Float) (Maybe Float) deriving (Show,Eq)++-- | Font size in pixels. Applicable to 'AxisStyle'+type FontSize = Int++-- | Alignment of 'Axis' labels. Applies to 'AxisStyle'+data AxisStyleAlignment+ = AxisStyleLeft -- ^ Left aligned labels+ | AxisStyleCenter -- ^ Centered labels+ | AxisStyleRight -- ^ Right aligned labels+ deriving (Show,Eq)++-- | Control drawing of 'Axis'. Applicable to 'AxisStyle'+data DrawingControl+ = DrawLines -- ^ Draw axis lines only+ | DrawTicks -- ^ Draw tick marks only+ | DrawLinesTicks -- ^ Draw axis lines and tick marks+ deriving (Show,Eq)++-- | Specify 'Axis' style+-- | <http://code.google.com/apis/chart/labels.html#axis_styles>+data AxisStyle = Style { axisColor :: Color,+ axisFontSize :: Maybe FontSize,+ axisStyleAlign :: Maybe AxisStyleAlignment,+ axisDrawingControl :: Maybe DrawingControl,+ tickMarkColor :: Maybe Color } deriving (Show,Eq)++-- | Specify an axis for chart.+-- | <http://code.google.com/apis/chart/labels.html#axis_styles>+data Axis = Axis { axisType :: AxisType,+ axisLabels :: Maybe [AxisLabel],+ axisPositions :: Maybe [AxisPosition],+ axisRange :: Maybe AxisRange,+ axisStyle :: Maybe AxisStyle } deriving Show++-- | List of 'Axis' for chart+type ChartAxes = [Axis]++-- | Grid Lines for Chart+-- | <http://code.google.com/apis/chart/styles.html#grid>+data ChartGrid =+ ChartGrid {+ xAxisStep :: Float -- ^ x-axis step size (0-100)+ , yAxisStep :: Float -- ^ y-axis step size (0-100)+ , lineSegmentLength :: Maybe Float -- ^ length of line segment+ , blankSegmentLength :: Maybe Float -- ^ length of blank segment+ , xOffset :: Maybe Float -- ^ x axis offset+ , yOffset :: Maybe Float -- ^ y axis offset+ } deriving Show+++{-+data ShapeType = ShapeArrow | ShapeCross | ShapeDiamond | ShapeCircle | ShapeSquare | VerticalLine | VerticalLineFull | HorizontalLine | ShapeX deriving Show+data ShapeDataPoint = DataPoint Int | DataPointEvery | DataPointEveryN Int | DataPointEveryNRange Int Int Int | DataPointXY Float Float deriving Show+data RangeMarkerType = RangeMarkerHorizontal | RangeMarkerVertical deriving Show+++data ChartMarker = ShapeMarker { shapeType :: ShapeType,+ shapeColor :: Color,+ shapeDataSetIdx :: Int,+ shapeDataPoint :: ShapeDataPoint,+ shapeSize :: Int,+ shapePriority :: Int+ } |+ RangeMarker { rangeType :: RangeMarkerType,+ rangeColor :: Color,+ rangeSpan :: (Float,Float) } deriving Show++type ChartMarkers = [ChartMarker]+-}++-- | Labels for Pie Chart and Google-o-meter.+-- | Specify a list with a single label for Google-o-meter+data ChartLabels = ChartLabels [String] deriving Show++-- | Data type for the chart+data Chart = Chart { chartSize :: ChartSize,+ chartType :: ChartType,+ chartData :: ChartData,+ chartTitle :: Maybe ChartTitle,+ chartColors :: Maybe ChartColors,+ chartFills :: Maybe ChartFills,+ chartLegend :: Maybe ChartLegend,+ chartAxes :: Maybe ChartAxes,+ chartGrid :: Maybe ChartGrid,+ -- chartMarkers :: Maybe ChartMarkers,+ chartLabels :: Maybe ChartLabels } deriving Show++-- | Default value for a chart+defaultChart = Chart { chartSize = Size 320 200,+ chartType = Line,+ chartData = Simple [],+ chartTitle = Nothing,+ chartColors = Nothing,+ chartFills = Nothing,+ chartLegend = Nothing,+ chartAxes = Nothing,+ chartGrid = Nothing,+ -- chartMarkers = Nothing,+ chartLabels = Nothing }++-- | Default value for an axis+defaultAxis = Axis { axisType = AxisBottom,+ axisLabels = Nothing,+ axisPositions = Nothing,+ axisRange = Nothing,+ axisStyle = Nothing }++-- | Default value for an axis style+defaultAxisStyle = Style { axisColor = "0000DD",+ axisFontSize = Nothing,+ axisStyleAlign = Nothing,+ axisDrawingControl = Nothing,+ tickMarkColor = Nothing }++-- | Default value for a chart grid+defaultGrid = ChartGrid { xAxisStep = 20,+ yAxisStep = 20,+ lineSegmentLength = Nothing,+ blankSegmentLength = Nothing,+ xOffset = Nothing,+ yOffset = Nothing }+++{-+defaultShapeMarker = ShapeMarker { shapeType = ShapeCircle,+ shapeColor = "0000DD",+ shapeDataSetIdx = 0,+ shapeDataPoint = DataPointEvery,+ shapeSize = 5,+ shapePriority = 0 }+-}
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) 2010 Deepak Jois <deepak.jois@gmail.com>+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:+* Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.+* Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+* Neither the name of the author nor the names of contributors may be+ used to endorse or promote products derived from this software without+ specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,154 @@+## Introduction++ **GChart** is a Haskell wrapper around [Google Chart API].++[Google Chart API]: http://code.google.com/apis/chart/++There is a library on Hackage called [GoogleChart] which provides another+wrapper, however it has not been updated in a long while. GChart improves upon+that effort by trying to design a more elegant API, and supporting more chart+types and features.++[GoogleChart]: http://hackage.haskell.org/packages/archive/GoogleChart/0.2/doc/html/Graphics-Google-Chart.html++## Installation++Coming Soon++## Getting Started++These examples below are available in `examples/Examples.hs` in the source+tarball. All examples are taking from [this article](http://24ways.org/2007/tracking-christmas-cheer-with-google-charts)++For examples 1 and 2, the following code is common++ dataSeries1 :: [Int]+ dataSeries1 = [10,20,8,25,5,3,15,9,5]++ labelSeries1 = ["Egg nog",+ "Christmas Ham",+ "Milk (not including egg nog)",+ "Cookies",+ "Roasted Chestnuts",+ "Chocolate",+ "Various Other Beverages",+ "Various Other Foods",+ "Snacks"]++### Example 1 : Pie Chart++The code below++ christmasPie = getChartUrl $ do setChartSize 600 300+ setDataEncoding simple+ setChartType Pie+ addChartData dataSeries1+ setChartTitle "Food and Drink Consumed Christmas 2007"+ setLabels labelSeries1+ setColors ["00AF33",+ "4BB74C",+ "EE2C2C",+ "CC3232",+ "33FF33",+ "66FF66",+ "9AFF9A",+ "C1FFC1",+ "CCFFCC" ]++Generates the following chart.++++### Example 2 : Bar Chart++The code below++ barGraph = getChartUrl $ do setChartSize 600 300+ setChartType BarHorizontalGrouped+ addChartData dataSeries1+ setChartTitle "Food and Drink Consumed Christmas 2007"+ addAxis $ makeAxis { axisType = AxisBottom }+ addAxis $ makeAxis { axisType = AxisLeft,+ axisLabels = Just labelSeries1 }+ addColor "00AF33"++Generates the following chart+++++### Example 3 : Line XY Chart 1++The code below++ linexyGraph1 =+ getChartUrl $ do setChartSize 800 300+ setChartType LineXY+ setDataEncoding text+ setChartTitle "Projected Christmas Cheer for 2007"+ setGrid $ makeGrid { xAxisStep = 3.333,+ yAxisStep = 10,+ lineSegmentLength = Just 1,+ blankSegmentLength = Just 3 }+ addAxis $ makeAxis { axisType = AxisLeft,+ axisRange = Just $ Range (0,100) (Just 50) }+ addAxis $ makeAxis { axisType = AxisBottom,+ axisLabels = Just $ ["Dec 1st"] ++ blanks 4 ++ ["6th"] ++ blanks 18 ++ ["25th","26th"] ++ blanks 4 ++ ["Dec 31st"] }+ addChartDataXY dataSeries2+ + dataSeries2 :: [(Float,Float)]+ dataSeries2 = [(0,0),(100,100)]+ + blanks x = take x $ repeat ""++Generates the following chart++++### Example 4 : Line XY Chart 2++The code below++ linexyGraph2 = + getChartUrl $ do setChartSize 800 300+ setChartType LineXY+ setDataEncoding text+ setChartTitle "Projected Christmas Cheer for 2007"+ + setGrid $ makeGrid { xAxisStep = 3.333,+ yAxisStep = 10,+ lineSegmentLength = Just 1,+ blankSegmentLength = Just 3 }+ + addAxis $ makeAxis { axisType = AxisLeft,+ axisRange = Just $ Range (0,100) (Just 50) }+ addAxis $ makeAxis { axisType = AxisBottom,+ axisLabels = Just $ ["Dec 1st"] ++ blanks 4 ++ ["6th"] ++ blanks 18 ++ ["25th","26th"] ++ blanks 4 ++ ["Dec 31st"] }+ + addChartDataXY dataSeries3+ addColor "458B00"+ + addChartDataXY dataSeries4+ addColor "CD2626"+ + setLegend $ legendWithPosition ["2006","2007"] LegendRight+ + dataSeries3 :: [(Float,Float)]+ dataSeries3 = zip [0,16.7,23.3,33.3,60,76.7,83.3,86.7,93.3,96.7,100] [30,45,20,50,15,80,60,70,40,55,80]+ + dataSeries4 :: [(Float,Float)]+ dataSeries4 = zip [0,10,16.7,26.7,33.3] [50,10,30,55,60]++ blanks x = take x $ repeat ""++Generates the following chart++++## Documentation++* API functions reference++* Haskell data types reference, along with pending features and chart types++* [Google Chart API]
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple++main = defaultMain
+ examples/Examples.hs view
@@ -0,0 +1,106 @@+import Graphics.GChart++{-++Some examples to demonstrate usage of GChart.++All examples are taken from this article : http://24ways.org/2007/tracking-christmas-cheer-with-google-charts++-}++christmasPie = getChartUrl $ do setChartSize 600 300+ setDataEncoding simple+ setChartType Pie+ addChartData dataSeries1+ setChartTitle "Food and Drink Consumed Christmas 2007"+ setLabels labelSeries1+ setColors ["00AF33",+ "4BB74C",+ "EE2C2C",+ "CC3232",+ "33FF33",+ "66FF66",+ "9AFF9A",+ "C1FFC1",+ "CCFFCC" ]+++barGraph = getChartUrl $ do setChartSize 600 300+ setChartType BarHorizontalGrouped+ addChartData dataSeries1+ setChartTitle "Food and Drink Consumed Christmas 2007"+ addAxis $ makeAxis { axisType = AxisBottom }+ addAxis $ makeAxis { axisType = AxisLeft,+ axisLabels = Just labelSeries1 }+ addColor "00AF33"++linexyGraph1 = + getChartUrl $ do setChartSize 800 300+ setChartType LineXY+ setDataEncoding text+ setChartTitle "Projected Christmas Cheer for 2007"+ setGrid $ makeGrid { xAxisStep = 3.333,+ yAxisStep = 10,+ lineSegmentLength = Just 1,+ blankSegmentLength = Just 3 }+ addAxis $ makeAxis { axisType = AxisLeft,+ axisRange = Just $ Range (0,100) (Just 50) }+ addAxis $ makeAxis { axisType = AxisBottom,+ axisLabels = Just $ ["Dec 1st"] ++ blanks 4 ++ ["6th"] ++ blanks 18 ++ ["25th","26th"] ++ blanks 4 ++ ["Dec 31st"] }+ addChartDataXY dataSeries2++linexyGraph2 = + getChartUrl $ do setChartSize 800 300+ setChartType LineXY+ setDataEncoding text+ setChartTitle "Projected Christmas Cheer for 2007"++ setGrid $ makeGrid { xAxisStep = 3.333,+ yAxisStep = 10,+ lineSegmentLength = Just 1,+ blankSegmentLength = Just 3 }++ addAxis $ makeAxis { axisType = AxisLeft,+ axisRange = Just $ Range (0,100) (Just 50) }+ addAxis $ makeAxis { axisType = AxisBottom,+ axisLabels = Just $ ["Dec 1st"] ++ blanks 4 ++ ["6th"] ++ blanks 18 ++ ["25th","26th"] ++ blanks 4 ++ ["Dec 31st"] }++ addChartDataXY dataSeries3+ addColor "458B00"++ addChartDataXY dataSeries4+ addColor "CD2626"++ setLegend $ legendWithPosition ["2006","2007"] LegendRight+++++blanks x = take x $ repeat ""++dataSeries1 :: [Int]+dataSeries1 = [10,20,8,25,5,3,15,9,5]++dataSeries2 :: [(Float,Float)]+dataSeries2 = [(0,0),(100,100)]++dataSeries3 :: [(Float,Float)]+dataSeries3 = zip [0,16.7,23.3,33.3,60,76.7,83.3,86.7,93.3,96.7,100] [30,45,20,50,15,80,60,70,40,55,80]++dataSeries4 :: [(Float,Float)]+dataSeries4 = zip [0,10,16.7,26.7,33.3] [50,10,30,55,60]++labelSeries1 = ["Egg nog",+ "Christmas Ham",+ "Milk (not including egg nog)",+ "Cookies",+ "Roasted Chestnuts",+ "Chocolate",+ "Various Other Beverages",+ "Various Other Foods",+ "Snacks"]++main = do putStrLn christmasPie+ putStrLn barGraph+ putStrLn linexyGraph1+ putStrLn linexyGraph2
+ hs-gchart.cabal view
@@ -0,0 +1,19 @@+Cabal-Version: >= 1.2+Name: hs-gchart+Version: 0.1+Synopsis: Haskell wrapper for the Google Chart API+Description: Haskell wrapper for the Google Chart API+Category: Graphics+License: BSD3+License-File: LICENSE+Author: Deepak Jois+Maintainer: deepak.jois@gmail.com+Copyright: (c) 2010 Deepak Jois <deepak.jois@gmail.com>+Homepage: http://github.com/deepakjois/hs-gchart+Build-Type: Simple+data-files: README.md, examples/Examples.hs+Library+ Build-Depends: base >= 3 && < 5, mtl+ hs-source-dirs: .+ exposed-modules: Graphics.GChart,Graphics.GChart.Types+ other-modules: Graphics.GChart.ChartItems, Graphics.GChart.DataEncoding