happy-hour (empty) → 0.0.0.1
raw patch · 4 files changed
+167/−0 lines, 4 filesdep +Chartdep +Chart-diagramsdep +base
Dependencies added: Chart, Chart-diagrams, base
Files
- changelog.md +5/−0
- happy-hour.cabal +39/−0
- library/Graphics/HappyHour.hs +105/−0
- license.txt +18/−0
+ changelog.md view
@@ -0,0 +1,5 @@+# Changelog++## v0.0.0.1 -- 2019 June 30++Initial release
+ happy-hour.cabal view
@@ -0,0 +1,39 @@+cabal-version: 2.4++name: happy-hour+version: 0.0.0.1+category: Graphics+synopsis: Generate simple okay-looking bar plots without much effort++description:+ The purpose of this library is to generate okay-looking bar plots+ for you without much effort on your part. The style of the plots+ may change in newer releases as we find ways to make them look+ nicer. If happy-hour generates a plot for you that is not+ aesthetically pleasing,please let us know so that we may improve.++tested-with: GHC==8.6.3++extra-source-files: changelog.md++copyright: 2019 Typeclass Consulting, LLC+license: MIT+license-file: license.txt++homepage: https://typeclasses.github.io/happy-hour/+bug-reports: https://github.com/typeclasses/happy-hour/issues++author: Chris Martin+maintainer: Chris Martin, Julie Moronuki++library+ hs-source-dirs: library+ default-language: Haskell2010++ exposed-modules:+ Graphics.HappyHour++ build-depends:+ base ^>= 4.12.0.0+ , Chart ^>= 1.9.1+ , Chart-diagrams ^>= 1.9.2
+ library/Graphics/HappyHour.hs view
@@ -0,0 +1,105 @@+{-# OPTIONS_GHC -Wall #-}++module Graphics.HappyHour (writeBarGraphSvgFile) where++-- base+import Data.List (genericLength)++-- Chart+import Graphics.Rendering.Chart.Easy hiding (bars)++-- Chart-diagrams+import Graphics.Rendering.Chart.Backend.Diagrams (renderableToFile, FileOptions, fo_size)++-- | Create an SVG file containing a bar graph.++writeBarGraphSvgFile+ :: FilePath+ -- ^ Where the file will be written. The containing directory must already exist. If there already exists a file at this path, it will be overwritten. If there exists a directory at this path, the action will fail.+ -> [(String, Int)]+ -- ^ The data to visualize. Each list entry represents a bar on the plot, ordered from left to right. The @String@ is the label on the X axis, and the @Int@ is the height of the bar.+ -> IO ()++writeBarGraphSvgFile path bars =+ do+ let layout = applyBarPlot bars def :: Layout PlotIndex Int+ let r = toRenderable layout :: Renderable ()+ let fo = applyFileOptions bars def :: FileOptions+ _ <- renderableToFile fo path r+ return ()++type Bars = [(String, Int)]++type Endo a = a -> a++foldEndo :: [a -> a] -> (a -> a)+foldEndo = foldr (.) id++applyFileOptions :: Bars -> Endo FileOptions+applyFileOptions bars =+ set fo_size (maximum ([l x | (x, _) <- bars]) * l bars * 50, 600)+ where+ l = genericLength++-- | Add a single bar plot to a layout, configure its X axis labels to match the data, and style the layout to look nice with a bar plot.+applyBarPlot :: Bars -> Endo (Layout PlotIndex Int)+applyBarPlot bars =+ foldEndo+ [ applyLayoutStyle+ , applyLabels bars+ , set layout_plots [plotBars (( applyBarStyle . applyValues bars ) def)]+ ]++-- | Set the data values on a bar plot.+applyValues :: Bars -> Endo (PlotBars PlotIndex Int)+applyValues bars =+ set plot_bars_values (addIndexes [ [y] | (_, y) <- bars ])++-- | Set up the X axis of a layout in preparation for adding the bar plot.+applyLabels :: Integral x => Bars -> Endo (Layout x y)+applyLabels bars =+ set (layout_x_axis . laxis_generate) (autoIndexAxis [ x | (x, _) <- bars ])++-- | Set some layout styles that look nice.+applyLayoutStyle :: Endo (Layout x y)+applyLayoutStyle =+ foldEndo+ [ set layout_margin 40+ , setAxisLineWidth 5+ , over yGridStyle (set line_width 5 . set line_dashes [40, 20])+ , set (layout_y_axis . laxis_style . axis_label_gap) 25+ , set (layout_title_style . font_size) 80+ , setAxisFontSize 40+ ]++-- | Lens for the grid style on the Y axis+yGridStyle :: Lens' (Layout x y) LineStyle+yGridStyle = layout_y_axis . laxis_style . axis_grid_style++-- | Lens for the width of an axis+axisLineWidth :: Lens' (LayoutAxis x) Double+axisLineWidth = laxis_style . axis_line_style . line_width++-- | Lens for the label font size of an axis+axisLabelSize :: Lens' (LayoutAxis x) Double+axisLabelSize = laxis_style . axis_label_style . font_size++-- | Set the line width on both axes.+setAxisLineWidth :: Double -> Endo (Layout x y)+setAxisLineWidth v =+ foldEndo [ set l v | l <- [ layout_x_axis . axisLineWidth+ , layout_y_axis . axisLineWidth ] ]++-- | Set the label size on both axes.+setAxisFontSize :: Double -> Endo (Layout x y)+setAxisFontSize v =+ foldEndo [ set l v | l <- [ layout_x_axis . axisLabelSize+ , layout_y_axis . axisLabelSize ] ]++-- | Set some bar styles that look nice.+applyBarStyle :: Endo (PlotBars x y)+applyBarStyle =+ foldEndo+ [ set plot_bars_spacing (BarsFixGap 80 20)+ , set plot_bars_item_styles [(FillStyleSolid (opaque steelblue), Nothing)]+ ]
+ license.txt view
@@ -0,0 +1,18 @@+Copyright 2019 Typeclass Consulting, LLC++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of+the Software, and to permit persons to whom the Software is furnished to do so,+subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.