packages feed

GoogleChart 0.1 → 0.2

raw patch · 2 files changed

+157/−23 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Graphics.Google.Chart: AlignCenter :: AxisAlignment
+ Graphics.Google.Chart: AlignLeft :: AxisAlignment
+ Graphics.Google.Chart: AlignRight :: AxisAlignment
+ Graphics.Google.Chart: AxisBottom :: AxisType
+ Graphics.Google.Chart: AxisLeft :: AxisType
+ Graphics.Google.Chart: AxisRight :: AxisType
+ Graphics.Google.Chart: AxisTop :: AxisType
+ Graphics.Google.Chart: class Chart c => AxisLabelChart c
+ Graphics.Google.Chart: data AxisAlignment
+ Graphics.Google.Chart: data AxisType
+ Graphics.Google.Chart: data VennDiagram
+ Graphics.Google.Chart: instance AxisLabelChart BarChart
+ Graphics.Google.Chart: instance AxisLabelChart LineChart
+ Graphics.Google.Chart: instance Chart VennDiagram
+ Graphics.Google.Chart: instance LegendChart VennDiagram
+ Graphics.Google.Chart: newVennDiagram :: VennDiagram
+ Graphics.Google.Chart: setAxisLabelPositions :: AxisLabelChart c => [[Int]] -> c -> c
+ Graphics.Google.Chart: setAxisLabels :: AxisLabelChart c => [[String]] -> c -> c
+ Graphics.Google.Chart: setAxisRanges :: AxisLabelChart c => [(Int, Int)] -> c -> c
+ Graphics.Google.Chart: setAxisStyles :: AxisLabelChart c => [(String, Int, AxisAlignment)] -> c -> c
+ Graphics.Google.Chart: setAxisTypes :: AxisLabelChart c => [AxisType] -> c -> c
+ Graphics.Google.Chart: setDataColors :: Chart c => [String] -> c -> c
- Graphics.Google.Chart: chartURL :: (Chart c) => c -> String
+ Graphics.Google.Chart: chartURL :: Chart c => c -> String
- Graphics.Google.Chart: class (Chart c) => LegendChart c
+ Graphics.Google.Chart: class Chart c => LegendChart c
- Graphics.Google.Chart: encodeDataText :: [[Int]] -> ChartData
+ Graphics.Google.Chart: encodeDataText :: RealFrac a => [[a]] -> ChartData
- Graphics.Google.Chart: setData :: (Chart c) => ChartData -> c -> c
+ Graphics.Google.Chart: setData :: Chart c => ChartData -> c -> c
- Graphics.Google.Chart: setLegend :: (LegendChart c) => [String] -> c -> c
+ Graphics.Google.Chart: setLegend :: LegendChart c => [String] -> c -> c
- Graphics.Google.Chart: setSize :: (Chart c) => Int -> Int -> c -> c
+ Graphics.Google.Chart: setSize :: Chart c => Int -> Int -> c -> c
- Graphics.Google.Chart: setTitle :: (Chart c) => String -> c -> c
+ Graphics.Google.Chart: setTitle :: Chart c => String -> c -> c
- Graphics.Google.Chart: setTitleOpts :: (Chart c) => String -> Int -> c -> c
+ Graphics.Google.Chart: setTitleOpts :: Chart c => String -> Int -> c -> c

Files

GoogleChart.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: >= 1.2 Name: GoogleChart-Version: 0.1+Version: 0.2 Synopsis: Generate web-based charts using the Google Chart API Category: Graphics License: BSD3
Graphics/Google/Chart.hs view
@@ -25,6 +25,17 @@ This produces: <http://chart.apis.google.com/chart?chs=400x257&chtt=My+Chart&chd=s%3aBCDEFGHIJKLMNOPQRSTU&chdl=1+to+20&cht=lc> +Remaining features to implement:++- lxy line charts++- chbh bar charts++- scatter plots++- background\/fill colors++- all style attributes -}  module Graphics.Google.Chart (@@ -35,11 +46,22 @@   setSize, setTitle, setTitleOpts, setData,   -- ** Chart data   -- | There are multiple options for encoding chart data.  See-  -- <http://code.google.com/apis/chart/#chart_data> for more details.+  -- <http://code.google.com/apis/chart/#chart_data> for more details on+  -- the tradeoffs of the different encoding options.   ChartData, encodeDataSimple, encodeDataText, encodeDataExtended, +  setDataColors,+   -- * Chart features+  -- ** Legends   LegendChart, setLegend,+  -- ** Axis labels+  -- | The order of elements in the lists passed to these functions matter:+  -- If the first 'AxisType' passed to 'setAxisTypes' is 'AxisBottom', then+  -- the first set of labels passed to 'setAxisLabels' refers to that bottom+  -- axis.+  AxisLabelChart, setAxisTypes, AxisType(..), setAxisLabels,+  setAxisLabelPositions, setAxisRanges, AxisAlignment(..), setAxisStyles,    -- * Specific chart types   -- ** Line charts@@ -49,21 +71,27 @@   PieChart, newPieChart, PieStyle(..), setLabels,    -- ** Bar charts-  BarChart, newBarChart, Orientation(..), BarStyle(..)+  BarChart, newBarChart, Orientation(..), BarStyle(..),++  -- ** Venn diagrams+  VennDiagram, newVennDiagram ) where  import Data.Char (chr, ord) import Data.List (intercalate) import Numeric (showHex) --- | Bar-+-- | URL-encode a string. urlEnc str = concatMap enc str where-  enc c | c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' = [c]-        | c >= '0' && c <= '9'                         = [c]-        | c == '-' || c == '_' || c == '.' || c == '~' = [c]-        | c == ' '                                     = "+"+  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 = "$-_.!*'(),|:"  -- All charts are internally represented as a list of (key,value) pairs. -- We could switch this to Data.Map if it matters.@@ -104,10 +132,10 @@ -- |All the encoding methods produce 'ChartData', which is usable by 'setData'. newtype ChartData = ChartData String deriving Show --- |Encode data using the \"simple\" encoding.  This produces minimal URLs but--- doesn't have as much resolution.  Input values must be in the range @0 <= x--- <= 61@.  Values outside the valid input range will be considered missing--- data.+-- |Encode data using the \"simple\" encoding, which maps each input value+-- to a single letter in the URL.  This produces minimal URLs but doesn't have+-- as lot of resolution.  Input values must be in the range @0 <= x <= 61@.+-- Values outside the valid input range will be considered missing data. encodeDataSimple :: [[Int]] -> ChartData encodeDataSimple datas =   ChartData $ "s:" ++ intercalate "," (map (map enc) datas) where@@ -116,26 +144,117 @@         | i >= 52 && i <= 61 = chr (ord '0' + (i - 52))         | otherwise          = '_' --- |Encode data using the \"text\" encoding.  XXX unimplemented.-encodeDataText :: [[Int]] -> ChartData-encodeDataText = undefined+-- |Encode data using the \"text\" encoding, which maps each input value to+-- its string representation (e.g. \"3.4\") in the URL.  This has more+-- resolution than simple encoding but produces larger URLs.  Input values must+-- be in the range @0 <= x <= 100@.  Values outside the valid input range will+-- be considered missing data.  Values with more than one decimal place of+-- resolution will be rounded.+encodeDataText :: RealFrac a => [[a]] -> ChartData+-- I chose RealFrac because it's necessary for floor; what is appropriate here?+-- The input must effectively be fixed-point.+encodeDataText datas =+  ChartData $ "t:" ++ intercalate "|" (map encData datas) where+  encData = intercalate "," . map encDatum+  encDatum i | i >= 0 && i <= 100 = showDecimal i+             | otherwise          = "-1"+  showDecimal :: RealFrac a => a -> String+  showDecimal i = show (fromIntegral (round (i * 10.0)) / 10.0) --- |Encode data using the \"extended\" encoding.  XXX unimplemented.+-- |Encode data using the \"extended\" encoding, which maps each input value+-- to a two-character pair in base 64.  This has more resolution than text+-- encoding and is more compact.  Input values must be in the range @0 <= x <=+-- 4095@.  Values outside the valid input range will be considered missing+-- data. encodeDataExtended :: [[Int]] -> ChartData-encodeDataExtended = undefined+encodeDataExtended datas =+  ChartData $ "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            = '.' +-- |Set data set colors.  The nth color specified here colors the nth data+-- set in the 'ChartData' passed to 'setData'.  See+-- <http://code.google.com/apis/chart/#line_bar_pie_colors> for more+-- information.+setDataColors :: Chart c => [String] -> c -> c+setDataColors colors = setParam "chco" (intercalate "," colors)+ -- |LegendChart represents charts that can display legends with 'setLegend'.-class Chart c => LegendChart c where-  -- |Set the legend for the corresponding data sets.  The colors are taken-  -- from the data set colors.-  setLegend :: [String] -> c -> c-  setLegend strs = setParam "chdl" (intercalate "|" strs)+class Chart c => LegendChart c+-- |Set the legend for the corresponding data sets.  The colors are taken+-- from the data set colors.+setLegend :: LegendChart c => [String] -> c -> c+setLegend strs = setParam "chdl" (intercalate "|" strs) +-- |AxisLabelChart represents charts that can display axis labels.+class Chart c => AxisLabelChart c++-- |Where to display an axis.+data AxisType = AxisBottom | AxisTop | AxisLeft | AxisRight++-- |Set which axes to display.  Repeating an 'AxisType' produces multiple+-- sets of labels on that axis.+setAxisTypes :: AxisLabelChart c => [AxisType] -> c -> c+setAxisTypes axes = setParam "chxt" (intercalate "," (map axisChar axes)) where+  axisChar AxisBottom = "x"+  axisChar AxisTop    = "t"+  axisChar AxisLeft   = "y"+  axisChar AxisRight  = "r"++-- |Set axis labels.  The nth list of strings in the argument sets the labels+-- for the nth axis specified with 'setAxisTypes'.  An empty list of strings+-- skips labelling the corresponding axis.+setAxisLabels :: AxisLabelChart c => [[String]] -> c -> c+setAxisLabels axislabels =+  setParam "chxl" (intercalate "|" (zipWith axisLabel [0..] axislabels)) where+  axisLabel :: Int -> [String] -> String+  axisLabel _     []     = ""+  axisLabel index labels = show index ++ ":|" ++ intercalate "|" labels++-- |Set axis label positions.  The nth list of Ints in the argument sets the+-- positions for the nth axis specified with 'setAxisTypes'.  An empty list+-- skips setting position for the corresponding axis.+setAxisLabelPositions :: AxisLabelChart c => [[Int]] -> c -> c+setAxisLabelPositions positions =+  setParam "chxp" (intercalate "|" (zipWith axisPosn [0..] positions)) where+  axisPosn _     [] = ""+  axisPosn index xs = intercalate "," (map show (index:xs))++-- |Set axis ranges.  The nth pair of Ints in the argument sets the range+-- for the nth axis specified with 'setAxisTypes'.+setAxisRanges :: AxisLabelChart c => [(Int,Int)] -> c -> c+setAxisRanges ranges =+  setParam "chxr" (intercalate "|" (zipWith axisRange [0..] ranges)) where+  axisRange index (min,max) = intercalate "," (map show [index,min,max])++-- |Text alignment for labels on an axis.+data AxisAlignment = AlignLeft | AlignCenter | AlignRight++-- |Set axis styles.  The nth element in the argument sets the style for the+-- nth axis specified with 'setAxisTypes'.  Each style is a tuple of+-- (color, font size, text alignment).+setAxisStyles :: AxisLabelChart c => [(String,Int,AxisAlignment)] -> c -> c+setAxisStyles styles =+  setParam "chxs" (intercalate "|" (zipWith axisStyle [0..] styles)) where+  axisStyle index (color, size, align) =+    intercalate "," [show index, color, show size, alignString align]+  alignString AlignLeft   = "-1"+  alignString AlignCenter = "0"+  alignString AlignRight  = "1"++ newtype LineChart = LineChart Params instance Chart LineChart where   params (LineChart p) = p   fromParams = LineChart instance LegendChart LineChart+instance AxisLabelChart LineChart  newLineChart :: LineChart newLineChart = fromParams [("cht","lc")]@@ -149,6 +268,7 @@ newPieChart Pie2D = fromParams [("cht","p")] newPieChart Pie3D = fromParams [("cht","p3")] +-- |Set labels for the different data points on the chart. -- Specify missing values by passing an empty string. setLabels :: [String] -> PieChart -> PieChart setLabels labels = setParam "chl" $ intercalate "|" labels@@ -158,6 +278,7 @@   params (BarChart p) = p   fromParams = BarChart instance LegendChart BarChart+instance AxisLabelChart BarChart data Orientation = Horizontal | Vertical data BarStyle = Stacked | Grouped newBarChart :: Orientation -> BarStyle -> BarChart@@ -167,3 +288,16 @@   oLetter Vertical   = 'v'   sLetter Stacked = 's'   sLetter Grouped = 'g'++-- |Venn diagram data is specified in a particular format.  There should be+-- exactly seven data values, which represent, in order:+--   circle A size, circle B size, circle C size,+--   A\/B overlap, A\/C overlap, B\/C overlap,+--   A\/B\/C overlap.+newtype VennDiagram = VennDiagram Params+instance Chart VennDiagram where+  params (VennDiagram p) = p+  fromParams = VennDiagram+instance LegendChart VennDiagram+newVennDiagram :: VennDiagram+newVennDiagram = fromParams [("cht", "v")]