* Make the dependency on the gtk package optional.
(since users can now install cairo without gtk if they wish.)
* Building on the AreaSpots idea, add a new AreaSpots4D, using
colour palettes to represent the fourth dimension.
* Tweak some of the Axis choices for time values, to avoid nasty
cases.
* Make some progress towards using PickFn for interaction with plots.
The major change here is that pixel coordinates now always
translate
back to value-space co-ordinates. (The caller could then use
these e.g.
to display the (x,y) value under the mouse, or to redraw the plot
after
zooming in or a dragged area, etc. But I have not yet added any
of the
latter facilities to the Gtk interactive windows.)
Regards,
Malcolm
Thanks for the patches. I'm sure they are good. I've been travelling
for the last couple of weeks and will take a look at them shortly.
Tim
On 02/07/2010, at 2:21 AM, Malcolm Wallace <malcolm...@cs.york.ac.uk
> wrote:
> --
> You received this message because you are subscribed to the Google
> Groups "Haskell Charts" group.
> To post to this group, send email to haskell...@googlegroups.com.
> To unsubscribe from this group, send email to haskell-chart...@googlegroups.com
> .
> For more options, visit this group at http://groups.google.com/group/haskell-charts?hl=en
> .
>
> <Chart.patches>
Regards,
Malcolm
>> <Chart.patches>
Tim
| Fri May 7 08:15:29 CDT 2010 Malcolm...@cs.york.ac.uk
| * If title is empty, don't create space for it in the top margin.
|
| M ./Graphics/Rendering/Chart/Layout.hs +1
pushed.
| Fri May 21 08:11:39 CDT 2010 Malcolm...@cs.york.ac.uk
| * New: AreaSpots4D; shows (x,y,z,t) using coords, spot area, and
colour.
| In addition to 2D position, and spot area for the z value, the
colour to
| represent the fourth dimension is chosen from a supplied palette. A
| palette is just a list of available colours - values are mapped to
the
| palette linearly, with truncation. (There is no blending of
intermediate
| colours.)
|
| M ./Graphics/Rendering/Chart/AreaSpots.hs +95
|
| Fri May 21 08:16:37 CDT 2010 Malcolm...@cs.york.ac.uk
| * Test for AreaSpots4D.
|
| A ./tests/Test14a.hs
nice! pushed.
| Wed Jun 30 09:46:42 CDT 2010 Malcolm...@cs.york.ac.uk
| * Fix Prelude.undefined bug.
|
| M ./Graphics/Rendering/Chart/Renderable.hs -1 +3
pushed.
| Tue Jun 29 08:01:13 CDT 2010 Malcolm...@cs.york.ac.uk
| * Inverse mapping from output image coordinates to values.
| This is useful for interactive manipulation of the output, e.g. for
| zooming or selecting.
|
| M ./Graphics/Rendering/Chart/Axis.hs -5 +42
pushed
| Wed Jun 30 09:41:35 CDT 2010 Malcolm...@cs.york.ac.uk
| * A Percent type for use on axes.
|
| M ./Graphics/Rendering/Chart/Axis.hs +11
pushed
| Wed Jul 7 07:46:57 CDT 2010 Malcolm...@cs.york.ac.uk
| * Fix calibration of pickFn when inside a grid.
|
| M ./Graphics/Rendering/Chart/Grid.hs -1 +4
pushed
| Tue Jun 29 08:04:08 CDT 2010 Malcolm...@cs.york.ac.uk
| * Tweak the auto axis selection for time, to use months for up to 2
years.
|
| M ./Graphics/Rendering/Chart/Axis.hs -1 +1
|
| Wed Jun 30 09:42:46 CDT 2010 Malcolm...@cs.york.ac.uk
| * Smooth out some of the time series used on axes.
| Previously it was possible for no axis labels to be visible at all,
| depending on the number of time units in the displayed interval, and
the
| number of displayed subdivisions thereof. It was also possible to
have
| only one or two major labels visible with large numbers of minor
ticks.
| Now, there should always be a minimum of 4-5 labels visible at once.
|
| M ./Graphics/Rendering/Chart/Axis.hs -9 +11
Can you please run the all_tests.hs script with these changes in place
(eg test2a) ? Some of the dated plots now look a bit of a mess with
overlapping labels etc. If you stretch the plots wide enough, the
overlaps go away, but I think that appropriate defaults should have us
showing about 5 labels by default.
FWIW, As a substitute for automated testing, I always take a quick
glance at the output of all_tests.hs just to make sure that I haven't
broken anything.
| Thu Jul 1 10:57:27 CDT 2010 Malcolm...@cs.york.ac.uk
| * ToRenderable now returns a PickFn (for interaction).
| But the only object that creates a usable PickFn is an AxisT.
|
| M ./Graphics/Rendering/Chart/Axis.hs -6 +6
| M ./Graphics/Rendering/Chart/Grid.hs -1 +2
| M ./Graphics/Rendering/Chart/Layout.hs -23 +33
| M ./Graphics/Rendering/Chart/Legend.hs -3 +3
| M ./Graphics/Rendering/Chart/Pie.hs -3 +4
| M ./Graphics/Rendering/Chart/Renderable.hs -5 +8
I'm not quite sure where this is going. Your change seems to be
assuming that all want from picking on a layout is an (x,y) pair?
I had envisaged that the picking on a layout would result in a
value of type:
data Layout1Pick x y = L1P_Legend String
| L1P_PlotArea x y y
| L1P_BottomAxis x
| L1P_TopAxis x
| L1P_LeftAxis y
| L1P_RightAxis y
| Thu Jul 1 10:39:00 CDT 2010 Malcolm...@cs.york.ac.uk
| * Add a gtk flag to .cabal file. Building with Gtk is now optional.
| The cairo package is still necessary, but cairo and gtk are no
longer
| packaged together upstream.
|
| M ./Chart.cabal -2 +10
| M ./Graphics/Rendering/Chart/Simple.hs -1 +9
A couple of questions on this - I'm not sure how a optional dependency
works in the cabal+hackage world. Given you've made the flag false by
default, does this mean that a normal build no longer has the gtk code
built in? If so, and I'm a user of the chart library, how do I specify
that in my cabal file that need the chart library with the gtk related
code?
An alternative would be to split the package into "chart" and
"chart-gtk". Do you think this better/worse than having the build
flag?
Yes, I realised after sending the patch, that sometimes the labels
overlap and look ugly. I was trying to fix the opposite problem, that
sometimes there are no labels visible at all, and sometimes only one
or two. I took some guesses as to when to switch between the various
different time granularities, but they do not always work out well.
Ideally, for time series I think I might like to see two sets of
labels, one for the major ticks (max two or three labels), and another
for some of the minor ticks (max ~20?). e.g. if the display shows 30
hours, it would be nice to have the two separate days labelled (12-
Jul-2010, 13-Jul-2010) but also every alternate hour tick (00:00,
02:00, 04:00, ...). If you are trying to read off values, this would
be a lot easier than having to find where the major tick boundary
lies, then counting small ticks manually. What do you think?
> I'm not quite sure where this is going. Your change seems to be
> assuming that all want from picking on a layout is an (x,y) pair?
Well, yes, that is all that I require for my application. But your
suggested return type is perfectly reasonable too:
> data Layout1Pick x y = L1P_Legend String
> | L1P_PlotArea x y y
> | L1P_BottomAxis x
> | L1P_TopAxis x
> | L1P_LeftAxis y
> | L1P_RightAxis y
The main changes in my patches do not preclude moving to that type
eventually. What they do is to augment the Renderable class to make
it possible to return anything sensible at all, and perform the
reverse calculation from pixel coordinates to value-space
coordinates. Previously, the PickFn could only return (). Now, a
PickFn returns (x,y), which is in effect a partial construction of the
L1P_PlotArea value above. In principle, I don't see a problem
extending my initial patches to build a full Layout1Pick instead of
just (x,y). Would you like me to do that?
> | * Add a gtk flag to .cabal file. Building with Gtk is now
> optional.
>
> A couple of questions on this - I'm not sure how a optional dependency
> works in the cabal+hackage world. Given you've made the flag false by
> default, does this mean that a normal build no longer has the gtk code
> built in? If so, and I'm a user of the chart library, how do I specify
> that in my cabal file that need the chart library with the gtk related
> code?
Hmm, the default for the flag means that cabal will attempt to resolve
dependencies with that setting first, and only if it fails, to try
other flag settings. So I guess on reflection it would be better to
make the flag True by default. All users will then get the maximum
possible API available on their system. It is possible for the
individual cabal user to switch the flag on/off on the commandline with
cabal install [-/+]gtk Chart
or some other such invocation, if they need to deviate from the
standard config for whatever reason.
> An alternative would be to split the package into "chart" and
> "chart-gtk". Do you think this better/worse than having the build
> flag?
I think separate packages would be a far worse solution. There is
very little gtk usage in Chart, and it is very obviously located in a
separate module. A build-time flag seems like the ideal solution to me.
Regards,
Malcolm
> Ideally, for time series I think I might like to see two sets of
> labels, one for the major ticks (max two or three labels), and another
> for some of the minor ticks (max ~20?). e.g. if the display shows 30
> hours, it would be nice to have the two separate days labelled (12-
> Jul-2010, 13-Jul-2010) but also every alternate hour tick (00:00,
> 02:00, 04:00, ...). If you are trying to read off values, this would
> be a lot easier than having to find where the major tick boundary
> lies, then counting small ticks manually. What do you think?
Yep - I agree that would be easier to read.
> > I'm not quite sure where this is going. Your change seems to be
> > assuming that all want from picking on a layout is an (x,y) pair?
>
> Well, yes, that is all that I require for my application. But your
> suggested return type is perfectly reasonable too:
>
> > data Layout1Pick x y = L1P_Legend String
> > | L1P_PlotArea x y y
> > | L1P_BottomAxis x
> > | L1P_TopAxis x
> > | L1P_LeftAxis y
> > | L1P_RightAxis y
>
> The main changes in my patches do not preclude moving to that type
> eventually. What they do is to augment the Renderable class to make
> it possible to return anything sensible at all, and perform the
> reverse calculation from pixel coordinates to value-space
> coordinates. Previously, the PickFn could only return (). Now, a
> PickFn returns (x,y), which is in effect a partial construction of the
> L1P_PlotArea value above. In principle, I don't see a problem
> extending my initial patches to build a full Layout1Pick instead of
> just (x,y). Would you like me to do that?
In the long run, this would be nice. But it's not essential right now.
There's two parts to your changes:
- filling in the missing parts of picking support
- making ToRenderable a MPTC
The first is much appreciated. I'm a little hesitant on the second,
because it requires turning on these language extensions:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
FlexibleInstances, UndecidableInstances #-}
Do you think that the convenience of being able to call say,
toRenderable a
rather than
axisToRenderable a
warrants turning on those extensions? (I'm unsure of the details of
each of them)
> So I guess on reflection it would be better to
> make the flag True by default. All users will then get the maximum
> possible API available on their system. It is possible for the
> individual cabal user to switch the flag on/off on the commandline with
> cabal install [-/+]gtk Chart
> or some other such invocation, if they need to deviate from the
> standard config for whatever reason.
> I think separate packages would be a far worse solution. There is
> very little gtk usage in Chart, and it is very obviously located in a
> separate module. A build-time flag seems like the ideal solution to me.
The think that makes me unsure about having these build flags is that
there's no way to specify them in the package dependencies. This
potentially turns cabal configuration problems into compile failures.
To be honest, the Gtk support currently is only a convenience. Over time
it might become a more general plotting widget I guess.
Given the limited GTK functionality right now. I'm ok with the flag,
assuming it defaults to true.
Tim
MultiParamTypeClasses and FunctionalDependencies are needed because,
given any Renderable value of type'a', we want to know what type 'b'
will be returned by the PickFn. FlexibleInstances and
UndecidableInstances are turned on simply because ghc told me to, when
it otherwise refused to compile! If you were happy to fix all PickFns
to return the same type (namely Layout1Pick), we could perhaps
eliminate all of these extensions. I'll have a go, and see how it
looks.
> Do you think that the convenience of being able to call say,
> toRenderable a
> rather than
> axisToRenderable a
> warrants turning on those extensions?
Well, I see that toRenderable is not used heavily, and in most places
could be replaced by a more type-specific call. To eliminate the
ToRenderable class altogether would perhaps be a useful simplification?
Regards,
Malcolm
> If you were happy to fix all PickFns
> to return the same type (namely Layout1Pick), we could perhaps
> eliminate all of these extensions. I'll have a go, and see how it
> looks.
My (admittedly slightly vague) plan was that pick functions would
return different types, depending on the value eg
for an axis it would be just the axes value,
for a layout1, it would be a Layout1Pick
for multiple a pair of layouts in a grid, it would be
Either (Layout1Pick ..., Layout1Pick ....)
etc
I'm tinkering with this now, and should have something to show
shortly.
>
> > Do you think that the convenience of being able to call say,
> > toRenderable a
> > rather than
> > axisToRenderable a
> > warrants turning on those extensions?
>
> Well, I see that toRenderable is not used heavily, and in most places
> could be replaced by a more type-specific call. To eliminate the
> ToRenderable class altogether would perhaps be a useful simplification?
That's what I was wondering. If it lets us have arbitrary pick values
without requiring type system extensions, perhaps it's the go? I'll
have a quick try and see how it turns out.
Tim
Cheers,
Tim
Tue Jul 13 22:42:26 CDT 2010 t...@dockerz.net
* Initial support for picking
This builds upon the patches from Malcolm Wallace,
and supports picking inside the plot region and
along the axes.
A sample script is provided that prints the pick
results which the chart is clicked upon.
Aha. I had just made a very similar patch myself today, before seeing
yours. Looks good to me. (I have another that deletes the
ToRenderable class and all of its instances from all modules, but may
need to re-record that, because it overlaps slightly with your patch.)
Regards,
Malcolm
Consequent on your patch, here are a couple of small tweaks: to allow
titles to be pickable; and to return the PickFn when writing a PNG
file. The latter I particularly need in my application, which is not
Gtk+ driven, but rather uses interactive HTML and Javascript to
display the charts.
I have also amended my gtk-flag patch, to make the default setting
True (i.e. to build gtk unless unusual circumstances prevail).
Regards,
Malcolm
Thanks - I've pushed all of these, along with a small picking patch of
my own. With my limited testing through the example script, picking now
works for the plot area, the axes, the legend, and title(s).
Out of curiosity, can you give some more information about your app? I
curious as to how you are writing a png file, but keeping the process
presumably alive so that you can use the pick function.
Tim
You are probably wondering how the JavaScript can call back into
Haskell. I'm not entirely clear on the details myself, but in
general, we have a rather complicated interop system written in C++,
that has bindings for Java, C#, and other languages. It can load a
Haskell DLL and start it with its own separate heap, and make certain
of the Haskell API calls available to any of the clients. The Haskell
heap just sits around containing values (including closures) whilst
the application might be doing other things in other languages.
The app uses the Chart library to write a PNG file, and keeps a
reference to the PickFn returned. The PNG is rendered in a custom
mini-HTML browser along with some JavaScript. The purpose of the
PickFn could be (e.g) to display the values of a lineplot, whilst
hovering over the PNG. The JavaScript can gather pixel co-ordinates
for the mouse position, and generate a callback into the PickFn to
determine the corresponding value-space co-ordinates for the popup
display. Another thing we can do is, if say the user clicks and drags
the mouse, the JavaScript can:
* draw a rectangle encompassing the dragged x-axis range,
* use the PickFn to determine the min and max x-values
corresponding to it,
* filter the original datasets that were used to generate the plot,
* render a fresh plot with the reduced dataset.
The effect for the user is an interactive zoom into the picture.
Regards,
Malcolm