----------------------------------------------------------------------------- -- | -- Module : Graphics.Rendering.Chart.Axis.Int -- Copyright : (c) Tim Docker 2010 -- License : BSD-style (see chart/COPYRIGHT) -- -- Calculate and render integer indexed axes {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# OPTIONS_GHC -XTemplateHaskell #-} module Graphics.Rendering.Chart.Axis.Int( defaultIntAxis, scaledIntAxis, autoScaledIntAxis ) where import Data.List(genericLength) import Graphics.Rendering.Chart.Types import Graphics.Rendering.Chart.Axis.Types import Graphics.Rendering.Chart.Axis.Floating instance PlotValue Int where toValue = fromIntegral fromValue = round autoAxis = autoScaledIntAxis defaultIntAxis instance PlotValue Integer where toValue = fromIntegral fromValue = round autoAxis = autoScaledIntAxis defaultIntAxis defaultIntAxis :: (Show a) => LinearAxisParams a defaultIntAxis = LinearAxisParams { la_labelf_ = show, la_nLabels_ = 5, la_nTicks_ = 10 } autoScaledIntAxis :: (Integral i, PlotValue i) => LinearAxisParams i -> AxisFn i autoScaledIntAxis lap ps = scaledIntAxis lap (min,max) ps where (min,max) = (minimum ps,maximum ps) scaledIntAxis :: (Integral i, PlotValue i) => LinearAxisParams i -> (i,i) -> AxisFn i scaledIntAxis lap (min,max) ps = makeAxis (la_labelf_ lap) (labelvs,tickvs,gridvs) where range [] = (0,1) range _ | min == max = (fromIntegral $ min-1, fromIntegral $ min+1) | otherwise = (fromIntegral $ min, fromIntegral $ max) -- labelvs :: [i] labelvs = stepsInt (fromIntegral $ la_nLabels_ lap) r tickvs = stepsInt (fromIntegral $ la_nTicks_ lap) ( fromIntegral $ minimum labelvs , fromIntegral $ maximum labelvs ) gridvs = labelvs r = range ps stepsInt :: Integral a => a -> Range -> [a] stepsInt nSteps range = bestSize (goodness alt0) alt0 alts where bestSize n a (a':as) = let n' = goodness a' in if n' < n then bestSize n' a' as else a goodness vs = abs (genericLength vs - nSteps) (alt0:alts) = map (\n -> steps n range) sampleSteps sampleSteps = [1,2,5] ++ sampleSteps1 sampleSteps1 = [10,20,25,50] ++ map (*10) sampleSteps1 steps size (min,max) = takeWhile (