[Chart] Fwd: [diagrams] Re: [GSoC 2013] Progress - Porting Charts to Diagrams

Brent Yorgey byorgey at seas.upenn.edu
Tue Jul 2 14:04:33 BST 2013


Whoops, looks like my email got munged a bit.  The parenthetical in
the middle was supposed to say

  ("default" means how the flag is set if the user does not explicitly
  specify; "manual" means that the cabal solver should not
  automatically try toggling the flag when creating a build plan,
  i.e. the flag should be changed only by the user.)

-Brent

On Tue, Jul 02, 2013 at 07:56:53AM -0400, Brent Yorgey wrote:
> On Tue, Jul 02, 2013 at 11:17:57AM +0200, Jan Bracker wrote:
> > 
> > It seems like cabal does not support the separate compilation of
> > executable. So we have to split the test package to manage dependencies. 
> 
> That's not true.  (Assuming I understand what you are saying.) 		   You
> can use some (standard) tricks with cabal flags	  to make		   this work.
> For example, see the diagrams-builder package, which has several
> executables (each with different dependencies) but you control which
> are installed via flags, and you only incur the	   dependencies of	the
> ones you request to be installed.  The idea is to make a flag like
> 
> flag cairo
>   description: install cairo-specific builder tool
>   default:     False
>   manual:      True
> 
> ("default" means how the flag is set if	the user does not explicitly
> specify; "manual" means that the cabal s
> 
> and then in the
> executable section you make both 'buildable' and the dependencies
> conditional on the flag, like this:
> 
> executable diagrams-builder-cairo
>   main-is:             diagrams-builder-cairo.hs
>   hs-source-dirs:      src/tools
>   default-language:    Haskell2010
>   other-extensions:    DeriveDataTypeable
>                        RecordWildCards
> 
>   if !flag(cairo)
>     buildable: False
> 
>   if flag(cairo)
>     build-depends:     base >= 4 && < 5,
>                        filepath,
>                        directory,
>                        diagrams-builder,
>                        diagrams-lib >= 0.6 && < 0.7,
>                        diagrams-cairo >= 0.6 && < 0.7,
>                        cmdargs >= 0.6 && < 0.11
> 
> When building, if you want to turn on a specific flag you do something like
> 
>   cabal install -fcairo diagrams-builder
> 
> -Brent
> 
> > 
> > The most current stable version of the port can be found here [0] in
> > commit 2e2277b4a65dc426d2da2a92b4c27eaa6bc11ecd .
> > 
> > Greets
> > Jan
> > 
> > [0]:
> > https://github.com/jbracker/haskell-chart/tree/2e2277b4a65dc426d2da2a92b4c27eaa6bc11ecd
> > 
> > 
> > 2013/6/25 Jan Bracker <jan.bracker at googlemail.com>
> > 
> > > Hello everybody,
> > >
> > > the last week brought some major changes. The current stable version is
> > > here [0]. All changes are in the master branch of my fork. What has been
> > > done / changed:
> > >
> > > - Implemented a new type for 'Path' that supports to be closed. Like this
> > > 'fillPath' and 'strokePath' do not need a boolean flag anymore. This should
> > > also make future changes easier, since the 'Path' type is abstract.
> > > - Cleaned up the code and added documentation for the 'Backend',
> > > 'Geometry' and 'Drawing' functions.
> > > - 'withClipRegion' now works in a hierarchical manner. You can only make
> > > the clipping region smaller and you can only clip on areas in your current
> > > clip. The clip region is represented by a 'Limit Rect'. This properly
> > > reflects the possibilities that the clip region can be empty 'LMin' or an
> > > infinite plane 'LMax'.
> > > - Removed the associated 'ChartOutput' type from the 'ChartBackend' class.
> > > Instead backend modules now deliver functions specific to their backend.
> > > - Removed all function with legacy names and switched the complete library
> > > to use the new API and functions.
> > > - Marked all 'default...' values as deprecated to push the transition to
> > > Data.Default.
> > > - Removed the 'Types' module again and distributed all contents into
> > > 'Backend', 'Geometry' and 'Drawing'.
> > > - Moved the cairo backend and the tests to their own packages (
> > > chart-cairo and chart-tests ).
> > > - Updated/Fixed the 'chart-gtk' package to work together with all changes.
> > > Its tests are now also in the chart-tests package.
> > >
> > > Some questions that I have:
> > >
> > > - When implementing the new version of 'withClipRegion' I stumbled upon
> > > the question how the empty clip region looks in cairo. Right now I use the
> > > empty 'Rect' at location (0,0) to represent this. This seems to work fine.
> > > - Right now the 'Renderable' class is commented out. Should I try to
> > > reintroduce it? Is this really a good Idea or should we leave it away all
> > > together? None of Charts uses it anymore.
> > >
> > > My plan for the next week would be:
> > >
> > > - Implement a test that only uses the backend API so we have something
> > > more basic to check if the backends work as expected. This will also show
> > > if the current documentation is specific enough.
> > > - Try to bring 'Renderable' back into scope (If that is a good idea)
> > >
> > > The next big step after this would be to merge all the changes back into
> > > the main Charts repository and start developing the Diagrams backend.
> > >
> > > Greets
> > > Jan
> > >
> > > [0]:
> > > https://github.com/jbracker/haskell-chart/tree/dcd35c767c69db40e1494608029736ae60148378
> > >
> > >
> > > 2013/6/17 Jan Bracker <jan.bracker at googlemail.com>
> > >
> > >> Hello everybody,
> > >>
> > >> I made good progress over the last week. I implemented the minimal chart
> > >> drawing API (  http://hpaste.org/89758 ) that Tim suggested. It worked
> > >> with minor problems. I tried to stay pixel equal to the PNGs that the
> > >> current release produces when running the test suite. I did not manage to
> > >> stay 100% pixel equal, but all differences are not visible with the naked
> > >> eye.
> > >>
> > >> Here the changes I had to apply to the API:
> > >>
> > >> - TextSize also contains the Y-bearing since it is used in some of the
> > >> text adjustment calculations.
> > >> - withSourceColor does not exists any more. The line style provides the
> > >> color for stroking, fill style the color for filling and font style the
> > >> color for fonts. There are several utilities to aid implementors of
> > >> backends with keeping the local environment up to date.
> > >> - The strokePath and fillPath functions are now backendStrokePath and
> > >> backendFillPath. They take an extra parameter that tells them if the given
> > >> path shall be close before rendering. This was necessary to produce equal
> > >> output. Convenience functions that default to not closed paths are provided.
> > >> - The matrix implementation is basically a copy of the matrix
> > >> implementation from cairo.
> > >> - The withClipRegion function now takes a Maybe Rect. I thought this
> > >> might be useful, because otherwise there would be no possibility to remove
> > >> the clip region. Though this is not needed anywhere in charts yet.
> > >> - I had to add the fillClip function, because otherwise there would have
> > >> been no possibility to fill the clip region if it is not set (infinite
> > >> plane clip).
> > >> - showText is now drawText and also takes a Point so it know where to
> > >> draw the text. The point refers to the left end of the text baseline.
> > >> - The drawing module now contains all kinds of higher level drawing
> > >> functions and helpers. There are still a lot of legacy functions with
> > >> temporary names. I will remove these soon.
> > >>
> > >> This commit is "stable" [0]: bdb628591132964e94f5b317026605790250359a
> > >>
> > >> Plans I would like to hear thoughts to:
> > >>
> > >> - Should I prefix the backend functions and provide wrapper functions
> > >> with the nice name? I already did this for backendFillPath since I noticed
> > >> that it also needed to know if the path has to be closed, but in 95% of all
> > >> cases the version that does not close by default is more practical. Like
> > >> this we would also be able to change the backend interface without having
> > >> to change several other modules.
> > >> - Should I keep the Maybe in withClipRegion? As said nothing in charts
> > >> actually ever removes the clip region.
> > >>
> > >> The next steps would be:
> > >>
> > >> - Remove legacy functions.
> > >> - Document all the drawing functions.
> > >> - Create a separate package for the Cairo backend. I don't know if we
> > >> should merge with the main repo before this or afterwards.
> > >> - There are still some direct connections to the Cairo backend in
> > >> Simple.Internal we have to think about how these can be removed.
> > >> - I would also suggest to create a separate package for the tests since
> > >> that would make dependency management easier.
> > >>
> > >> Greets
> > >> Jan
> > >>
> > >> [0]:
> > >> https://github.com/jbracker/haskell-chart/tree/bdb628591132964e94f5b317026605790250359a
> > >>
> > >>
> > >> 2013/6/13 Jan Bracker <jan.bracker at googlemail.com>
> > >>
> > >>> I will proceed with 3 then.
> > >>>
> > >>>
> > >>> 2013/6/12 Tim Docker <tim at dockerz.net>
> > >>>
> > >>>>  Hi,
> > >>>>
> > >>>> I think your analysis is good. In the context of the backend, it makes
> > >>>> sense to separate out the color from the various styles.
> > >>>>
> > >>>> On the other hand, in the context of the chart use API, it makes sense
> > >>>> to have all of the properties of a line in a single data type - it's
> > >>>> simpler for the caller to say style this plot line using properties as per
> > >>>> this value.
> > >>>>
> > >>>> Possible solutions are:
> > >>>>
> > >>>>     1) Leave it and put up with the inconsistency...
> > >>>>     2) Have separate types in the backend API / user API for LineStyle,
> > >>>> FillStyle and FontStyle
> > >>>>     3) Remove withSourceColor from the backend API, and require
> > >>>> backends to give the logical behaviour (ie setting the FillStyle doesn't
> > >>>> affect the color of lines). This would mean the cairo backend would have to
> > >>>> do a bit more work to be correct.
> > >>>>
> > >>>> Either 2 or 3 is ok with me.
> > >>>>
> > >>>> Tim
> > >>>>
> > >>>>
> > >>>>
> > >>>> On 13/06/13 00:45, Jan Bracker wrote:
> > >>>>
> > >>>> Hi everybody,
> > >>>>
> > >>>>  a small follow up: While thinking about and implementing the smaller
> > >>>> API I noticed that due to the internals of Cairo the source color is used
> > >>>> to render everything. When setting a style (font, fill, line) the source
> > >>>> color is changed according to that style. This means each of the
> > >>>> "with...Style" or "withSourceColor" functions constantly overrides the
> > >>>> source color. Is this really desired behaviour? Shouldn't the fill color
> > >>>> apply to fills, the line color to strokes and the font color to text
> > >>>> rendering? If so the source color ("withSourceColor") is a useless concept.
> > >>>> Of course keeping these color seperate will expand the cairo rendering
> > >>>> backend, but I think it is useful to avoid confusion to which color is used
> > >>>> where.
> > >>>>
> > >>>>  Example:
> > >>>>
> > >>>>  1: withLineStyle ls $ withFillStyle fs $ fillPath p >> strokePath p
> > >>>>
> > >>>>  should be the same as (according to my thoughts):
> > >>>>
> > >>>> 2: withFillStyle fs $ withLineStyle ls $ fillPath p >> strokePath p
> > >>>>
> > >>>>  but with the current implementation 1 would render both with the fill
> > >>>> color and 2 would render them with the line color.
> > >>>>
> > >>>>  Jan
> > >>>>
> > >>>>
> > >>>>
> > >>>> 2013/6/12 Jan Bracker <jan.bracker at googlemail.com>
> > >>>>
> > >>>>> Hi everybody,
> > >>>>>
> > >>>>>  Brent: Thanks you for the offer and thanks for your great help on
> > >>>>> those nasty type errors yesterday.
> > >>>>>
> > >>>>>  On IO in Diagrams: We looked into the SVGFont rendering stuff and
> > >>>>> noticed that it has a call to unsafePerformIO (which let us scream in pain
> > >>>>> and agony :-P ). We though it would be nice to remove this hidden call and
> > >>>>> actually offer a function that makes it explicit. I am not sure why it is
> > >>>>> there and assume its purpose is to keep everything pure. Your suggestion to
> > >>>>> produce a IO Diagram is what we thought of too. We are not sure which
> > >>>>> changes would be required up to now, but we will come back to you when we
> > >>>>> do know.
> > >>>>>
> > >>>>>  On general note: I have worked on abstracting the backend the last
> > >>>>> two days. Here what I accomplished by now:
> > >>>>>
> > >>>>>  - I have fully converted my branch to use the abstract rendering
> > >>>>> backend ChartBackend [0] instead of the CRender monad directly.
> > >>>>>
> > >>>>>  - There is a implementation of the backend with Cairo in the
> > >>>>> Backend.Cairo module [1].
> > >>>>>
> > >>>>>  - The current HEAD of the backend-experiment branch [2] is stable
> > >>>>> (commit ad715c4d216e8fcb494f9919d4fb5459ce7d85c2).
> > >>>>>
> > >>>>>  - I added reference images [3] of all tests to compare with the
> > >>>>> results that the original code delivered.
> > >>>>>
> > >>>>>  - All tests are running using the new backend code and pixel-diffs
> > >>>>> [4] of the produced PNGs show that they render exactly the same.
> > >>>>>
> > >>>>>  - I ran into the issue that the ToRenderable class was complicated
> > >>>>> to abstract. My abstraction involved a associated type with two parameters
> > >>>>> that are in relation to each other [5,6]. After talking with Tim I removed
> > >>>>> the ToRenderable code completely and instead just exported specific
> > >>>>> functions for all types directly. This also made the examples easier to
> > >>>>> adjust, since the new ToRenderable class made type annotations necessary
> > >>>>> everywhere, which, in my point of view, defeats the purpose of the
> > >>>>> toRenderable function. It was easier just calling the specific function
> > >>>>> directly. I think the change of API is acceptable, since the generalised
> > >>>>> backend lets type parameters popup everywhere anyway.
> > >>>>>
> > >>>>>  The next steps:
> > >>>>>
> > >>>>>  - Tim suggested this simplified API instead of the rather extensive
> > >>>>> [0] version used right now: http://hpaste.org/89758 . I will work on
> > >>>>> trimming down the current API and providing all complex functions in terms
> > >>>>> of the new API.
> > >>>>> - The only downside I see is the Matrix type which (I assume) comes
> > >>>>> from Cairo.Matrix [7]. I would just give a naive implementation that
> > >>>>> contains 6 double values for the affine transformations and provide a
> > >>>>> similar custom API.
> > >>>>> - I will also try to provide a small EDSL for writing paths to make
> > >>>>> that easier (I guess some short combinators and a monoid instance will do
> > >>>>> fine).
> > >>>>>
> > >>>>>  Jan
> > >>>>>
> > >>>>>  [0]:
> > >>>>> https://github.com/jbracker/haskell-chart/blob/backend-experiment/chart/Graphics/Rendering/Chart/Types.hs#L85
> > >>>>> [1]:
> > >>>>> https://github.com/jbracker/haskell-chart/blob/backend-experiment/chart/Graphics/Rendering/Chart/Backend/Cairo.hs#L80
> > >>>>> [2]:
> > >>>>> https://github.com/jbracker/haskell-chart/tree/ad715c4d216e8fcb494f9919d4fb5459ce7d85c2
> > >>>>> [3]:
> > >>>>> https://github.com/jbracker/haskell-chart/tree/backend-experiment/chart/tests-reference
> > >>>>>  [4]:
> > >>>>> https://github.com/jbracker/haskell-chart/blob/backend-experiment/chart/gen-diffs-png.sh
> > >>>>>  [5]:
> > >>>>> https://github.com/jbracker/haskell-chart/blob/backend-experiment/chart/Graphics/Rendering/Chart/Renderable.hs#L77
> > >>>>> [6]:
> > >>>>> https://github.com/jbracker/haskell-chart/blob/backend-experiment/chart/Graphics/Rendering/Chart/Layout.hs#L163
> > >>>>> [7]:
> > >>>>> http://hackage.haskell.org/packages/archive/cairo/0.12.4/doc/html/Graphics-Rendering-Cairo-Matrix.html
> > >>>>>
> > >>>>>
> > >>>>> 2013/6/11 Brent Yorgey <byorgey at seas.upenn.edu>
> > >>>>>
> > >>>>>> Hi Jan and all,
> > >>>>>>
> > >>>>>> Looks like some great progress!  I'm excited. =) Just a couple
> > >>>>>> thoughts: one, let me know if you want help staring at the funny type
> > >>>>>> errors with Legend and whatnot.  I'm not familiar with the Chart code
> > >>>>>> but perhaps I can help figure out a good solution for the abstraction.
> > >>>>>>
> > >>>>>> My other general comment is that I know you and Tim have talked a bit
> > >>>>>> about the problems with having font stuff in IO whereas diagrams is
> > >>>>>> pure.  However, from my point of view it wouldn't be that big of a
> > >>>>>> deal if Chart produced an IO Diagram rather than just a Diagram.
> > >>>>>> Maybe I haven't thought about it sufficiently but it seems like this
> > >>>>>> would be an easy solution to the problem of needing IO.  I'm happy to
> > >>>>>> talk about it in more detail if you want, and if there are ways that
> > >>>>>> the diagrams API could change to make any of this easier I'm happy to
> > >>>>>> discuss that as well. I'm in the middle of some big refactoring anyway
> > >>>>>> (though don't worry, I don't think it will affect your work on porting
> > >>>>>> Chart very much).
> > >>>>>>
> > >>>>>> -Brent
> > >>>>>>
> > >>>>>> On Mon, Jun 10, 2013 at 05:24:34PM +0200, Jan Bracker wrote:
> > >>>>>> > Hi,
> > >>>>>> >
> > >>>>>> > Andy: The goal is to abstract Charts from Cairo so we can plug in
> > >>>>>> another
> > >>>>>> > backend (target is Diagrams). And by that we would also be able to
> > >>>>>> use
> > >>>>>> > Sunroof through diagrams. Of course in the end it should also be
> > >>>>>> possible
> > >>>>>> > to implement a Sunroof backend on its own.
> > >>>>>> >
> > >>>>>> > Tim:
> > >>>>>> >
> > >>>>>> >  > Rather than have the CRender monad take an extra parameter, I
> > >>>>>> guess one
> > >>>>>> > > could just have a separate data type for each backend (ie
> > >>>>>> CRenderCairo and
> > >>>>>> > > CRenderDiagrams) and have the drawing code abstracted over a
> > >>>>>> typeclass
> > >>>>>> > > implemented by both. Not sure if this would be better...
> > >>>>>> > >
> > >>>>>> >
> > >>>>>> >  I tried your approach in a new branch:
> > >>>>>> > https://github.com/jbracker/haskell-chart/tree/backend-experiment
> > >>>>>> >
> > >>>>>> > It seems to be working quite well. So I started generalizing
> > >>>>>> everything
> > >>>>>> > outside of the cairo module to use a general ChartBackend m instead
> > >>>>>> of a
> > >>>>>> > CRender to draw everything. There are a few spots that are giving
> > >>>>>> me a hard
> > >>>>>> > time:
> > >>>>>> >
> > >>>>>> > Renderable was implemented in terms of CRender. So I added another
> > >>>>>> type
> > >>>>>> > parameter and that worked fine until I hit Legend. There I also
> > >>>>>> added a
> > >>>>>> > type parameter. But that blew up the ToRenderable instance. So I
> > >>>>>> had to
> > >>>>>> > insert a associated type to relate types to each other. After doing
> > >>>>>> so I
> > >>>>>> > was not able to fix whatever went wrong in Plot.Pie. The
> > >>>>>> 'ToRenderable
> > >>>>>> > PieLayout' instance gives me this error:
> > >>>>>> >
> > >>>>>> > Graphics/Rendering/Chart/Plot/Pie.hs:121:62:
> > >>>>>> >     Could not deduce (RenderableT m a0 ~ PieChart)
> > >>>>>> >     from the context (ChartBackend m)
> > >>>>>> >       bound by the type signature for
> > >>>>>> >                  toRenderable :: ChartBackend m =>
> > >>>>>> >                                  RenderableT m PieLayout ->
> > >>>>>> Renderable m ()
> > >>>>>> >       at Graphics/Rendering/Chart/Plot/Pie.hs:(117,5)-(125,29)
> > >>>>>> >     The type variable `a0' is ambiguous
> > >>>>>> >     Possible fix: add a type signature that fixes these type
> > >>>>>> variable(s)
> > >>>>>> >     In the return type of a call of `pie_plot_'
> > >>>>>> >     In the second argument of `($)', namely `pie_plot_ p'
> > >>>>>> >     In the second argument of `addMargins', namely
> > >>>>>> >       `(toRenderable $ pie_plot_ p)'
> > >>>>>> >
> > >>>>>> > I think I know what is going wrong, but I have no idea how to
> > >>>>>> specify the
> > >>>>>> > instance it should use there. Maybe I am just to tired to see the
> > >>>>>> solution.
> > >>>>>> >
> > >>>>>> > Right now I am trying to make things work without extra type
> > >>>>>> parameters,
> > >>>>>> > though the definitions that are based on CRender are giving me a
> > >>>>>> hard time,
> > >>>>>> > because then I end up with rank N types.
> > >>>>>> >
> > >>>>>>   > --
> > >>>>>> > You received this message because you are subscribed to the Google
> > >>>>>> Groups "diagrams-discuss" group.
> > >>>>>> > To unsubscribe from this group and stop receiving emails from it,
> > >>>>>> send an email to diagrams-discuss+unsubscribe at googlegroups.com.
> > >>>>>> > For more options, visit https://groups.google.com/groups/opt_out.
> > >>>>>> >
> > >>>>>> >
> > >>>>>>
> > >>>>>
> > >>>>>
> > >>>>
> > >>>>
> > >>>
> > >>
> > >
> 
> -- 
> You received this message because you are subscribed to the Google Groups "diagrams-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to diagrams-discuss+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
> 
> 



More information about the Chart mailing list