-
Notifications
You must be signed in to change notification settings - Fork 85
How to use backends
After writing your first chart you want to render it to some output. At the time of writing there are two backends to do so:
- Chart-cairo - The original backend based on the Cairo library.
- Chart-diagrams - A backend based on the Diagrams library.
To use one of them you have to import their main module and call their rendering function runBackend
. As a result you will get backend specific rendering instructions to use.
Usually runBackend
function has two parameters. The first is a backend specific environment to configure the backend and the second is a ChartBackend
instance that contains the rendering instructions to execute.
The backend will provide a way to construct a environment for your needs. Cairo and Diagrams both offer a defaultEnv
function for this purpose.
The environments usually needs to be configured with a AlignmentFns
. They are used to realign lines and fills in a diagrams to pixels boundaries in case you render to a bitmap. Charts provides the two instances bitmapAlignmentFns
and vectorAlignmentFns
. Use the first when rendering to bitmaps (e.g. PNGs) and the second when rendering vector based graphics (e.g. SVG, EPS, PDF).
To use the Cairo backend use the following import:
import Graphics.Rendering.Chart.Backend.Cairo
A configuration environment can be created using defaultEnv
function. Afterwards you can call runBackend
to create a Cairo Render
instance from your ChartBackend
.
defaultEnv :: AlignmentFns -> CEnv
runBackend :: CEnv -> ChartBackend a -> Graphics.Rendering.Cairo.Render a
But these are fairly low level functions that assume you want to be working with cairo output directly. As a convenience the module also offers some utilities to get started quickly:
data FileFormat = PNG | SVG | PS| PDF
data FileOptions = FileOptions {
_fo_size :: (Int,Int),
_fo_format :: FileFormat
}
renderableToFile :: FileOptions -> FilePath -> Renderable a -> IO (PickFn a)
FileOptions
has a Default
instance, so that renderableToFile def path r
will produce a 800x600 PNG output file of the Renderable r
. Generally chart are produced as Renderables, or there are appropriate conversion functions.
Have a look at this example to see how this works in action.
SVG files generated by the cairo backend embed glyph names that are generated within the cairo library. The SVG standard requires that these names be unique. Individual SVG files generated by cairo will meet this property. However if SVG files are composed to build a composite SVG image, or to build a single HTML file, this uniqueness property will not be met. To achieve this, some post processing of the SVG may be required.
To use the Diagrams backend use the following import:
import Graphics.Rendering.Chart.Backend.Diagrams
A configuration environment can be created using defaultEnv
function. Afterwards you can call runBackend
to create a Cairo Diagram b R2
instance from your ChartBackend
.
defaultEnv :: AlignmentFns -> Double -> Double -> IO (DEnv b)
runBackend :: (...) => DEnv (N b) -> ChartBackend a -> (D.QDiagram b V2 (N b) Any, a)
The width and height of the final output has to be supplied to defaultEnv
. Creating an environment is a IO
operation since this caches the available fonts for later (pure) use inside the produces diagram.
As a convenience the module also offers utilities to get started quickly:
runBackendR :: (...) => DEnv (N b) -> Renderable a -> (D.QDiagram b V2 (N b) Any, PickFn a)
data FileFormat = EPS| SVG | SVG_EMBEDDED
data FileOptions = FileOptions {
_fo_size :: (Double,Double),
_fo_format :: FileFormat,
_fo_fonts :: IO (FontSelector Double)
}
renderableToFile :: FileOptions -> FilePath -> Renderable a -> IO (PickFn a)
Most of the time charts are produced in form of Renderable
s. This is why the utilities take a Renderable
instead of a ChartBackend
. FileOptions
has a Default
instance, such that renderableToFile def path r
will write the given Renderable to a 800x600 svg file, with sans serif fonts.
Here is a complete example of how to use this backend:
import Graphics.Rendering.Chart
import Graphics.Rendering.Chart.Backend.Diagrams
import Data.Default.Class
import Control.Lens
import System.Environment(getArgs)
chart = toRenderable layout
where
values = [ ("Mexico City",19.2,e), ("Mumbai",12.9,e)
, ("Sydney",4.3,e), ("London",8.3,e), ("New York",8.2,e1) ]
e = 0
e1 = 25
pitem (s,v,o) = pitem_value .~ v
$ pitem_label .~ s
$ pitem_offset .~ o
$ def
layout = pie_title .~ "Relative Population"
$ pie_plot . pie_data .~ map pitem values
$ def
main1 ["svg"] = renderableToFile def "example5.svg" chart
main1 ["eps"] = renderableToFile def{_fo_format=EPS} "example5.eps" chart
main = getArgs >>= main1