Closed GoogleCodeExporter closed 8 years ago
I'll work on this one.
Drew
Original comment by drewmcco...@mac.com
on 24 Jun 2009 at 7:27
An related issue that's come up recently is the desire to have more than one
plot area within the graph. This
would enable multiple plots to have their own axes but ease the task of
aligning them with each other. The
simplest way to implement this would be to have the graph hold an array of plot
areas instead of a single one.
Original comment by eskr...@mac.com
on 15 Aug 2009 at 5:20
Why is the plot space a layer? It seems like this should be a model object, not
a view. Also, could we change the
plot space model so it applies to only one axis? You would need one for each
axis of the plot, e.g., one for X and
another for Y.
It would then be easy to set up multiple plots (see comment 2 above) such that
they shared the plot space for
one or more axes. This arrangement would benefit the automatic axis labeling
(issue #38) as well.
Original comment by eskr...@mac.com
on 15 Aug 2009 at 5:39
I actually don't see the need for supporting multiple plot areas. Can't you
just create multiple graphs, and lay
those out? I don't see what the advantage of having multiple areas in a single
graph would be. Can you come
up with a concrete example which would demonstrate a case that couldn't be
handled by multiple graphs?
At the moment you can already have multiple axes in a single graph. You can
have two y axes, for example,
and two x axes, each associated with different plot spaces. So you can have
multiple plots associated with
different axes in that sense.
Re: why is the plot space a layer? At this point it is true it does nothing
important. We could indeed make it a
model object, and just have plot layers directly under the CPPlotArea. One
issue would be that some layers (eg
plots) should be cropped to the plot area, and others, eg CPAxisSet, should
not.
Original comment by drewmcco...@mac.com
on 15 Aug 2009 at 5:56
It's pretty common to see two or more graphs arranged in a column or row, each
with their own axis set. There are several reasons I think CPGraph should be
able to contain more than one plot area.
1. It gives a common container with it's own border and background. The plot
areas can have their own as well.
2. We would have a place to show titles and/or legends that apply to all of the
plots. Each plot area could have its own as well.
3. Aesthetically, the group of graphs will look better if the axes are aligned,
not the borders of the plot areas. This can be difficult if the labels on the
different graphs are different sizes (e.g.,
because of different number formats or data ranges). Picture a column of X-Y
graphs where the Y-axis labels are different. The layout problem gets even
harder once we implement automatic axis
labeling.
4. Sometimes, the plots in the group will need to have a common axis scale,
e.g., the X-axes in our column of graphs. If you're setting the scale manually,
that's no problem. If you're using
automatic scales, the separate graphs would have to communicate somehow in
order to figure out an axis scale that accommodates the data for each plot.
It's easier to set that up if the plots are all
part of the same graph. Having the plot space be an abstract model instead of
part of the layer hierarchy will help solve this problem, too.
5. The layout problem can be non-trivial. Encapsulating the layout inside
CPGraph puts the burden on Core Plot to get it right and not make users
reinvent the wheel every time they need to do this.
Eric
Original comment by eskr...@mac.com
on 15 Aug 2009 at 7:33
Groups of related plots are common in stock charting applications. A plot of
the stock price above a volume
chart with a separate axis set is very common.
See http://stockcharts.com/h-sc/ui?s=aapl for an example with three plots
stacked in a column with common
x-axis scale.
Original comment by eskr...@mac.com
on 16 Aug 2009 at 12:50
OK, it seems like there are some good arguments for it, so we can do this.
We need to consider how we are going to layout the plot areas inside the graph.
Will it always be a column? Will
we use some sort of grid system? Or will the user just set the layer frames
directly? It will take quite a bit of
thought. The padding property won't be enough anymore, I doubt.
Drew
Original comment by drewmcco...@mac.com
on 16 Aug 2009 at 7:25
I think a grid system with the ability to span rows and/or columns like an HTML
table is a good layout model.
That should be flexible and easy to understand from a user perspective and not
too hard to implement.
Original comment by eskr...@mac.com
on 16 Aug 2009 at 12:10
Maybe we should provide a layout manager type mechanism. We could supply a
basic grid layout manager, but
provide the flexibility to create a custom layout manager by subclassing a
CPLayoutManager abstract class.
Drew
Original comment by drewmcco...@mac.com
on 16 Aug 2009 at 5:31
Agreed. CALayer on the Mac already supports custom layout managers. The trick
will be to provide the same
features on the iPhone without completely reinventing the wheel.
Original comment by eskr...@mac.com
on 16 Aug 2009 at 7:38
I've attached a diagram of how I think the layer hierarchy ought to be
organized. I didn't include minor things
like titles and labels that have an obvious parent.
I want to add the ability to draw a border around the plots and add a
background fill. For an X-Y plot, an axis
would replace a side of the bordered box. I'm not sure yet if this should be
the responsibility of the axis set, the
plot group, or a separate layer altogether.
Original comment by eskr...@mac.com
on 23 Aug 2009 at 2:57
Attachments:
The design looks good. Actually, it is pretty similar to what we already have.
The major difference I see is that
CPPlotSpace is not a layer, and has been replaced in the layer hierarchy by
something called CPPlotGroup.
CPPlotSpace currently serves the purpose of doing coordinate transforms, and
acting as the base layer for
plots. With the new design, it seems CPPlotGroup would act as the base layer
for plots, and CPPlotSpace
would be moved outside the layer tree.
One thing to consider is how CPPlotSpace is going to work. There really needs
to be a one-to-one relationship
between CPPlotSpace and CPPlotArea, because the transform is dictated by the
bounds of the plot area. I don't
think it would be wise to try to make that relationship a to-many relationship.
Another thing to consider is whether these changes, in particular multiple plot
areas, will complicate the APIs
unduly. For example, someone could already put multiple graphs in a single
view, lay them out using standard
core animation techniques. If axes must be kept in sync, they could easily do
that if appropriate delegate
methods were available to tell them when a change has occurred.
So my question is: Is the complexity of the multiple plot area design worth the
complexity it will introduce for
the user of the framework? Most users will just want a simple single plot area
graph. By allowing multiple plot
areas we are helping those users that have advanced needs, but at the expense
of simplicity. Is that a price
worth paying, given advanced users could still achieve their goals -- with a
bit more effort -- as the
framework currently is?
I'm not against the changes, but we need to be careful. Perhaps it would be a
good idea just to go through
some of the header files, and consider what sort of changes to the APIs will be
needed, and whether it can be
done in a way that will not overly confuse a new user.
Original comment by drewmcco...@mac.com
on 23 Aug 2009 at 7:44
I included the CPPlotGroup for a couple of reasons. It gives all of the plots a
common superlayer. This makes
it easy to animate the plots as a group. It also gives them a common base
coordinate system.
The current CPGraph automatically creates a single plot area during
initialization. There's no reason it couldn't
continue to do that. We just need to add a mechanism to add others and give the
user control of the layout.
The way Core Plot handles the plot space transforms has always struck me as a
little unusual. I've used several
other plotting libraries and none of them require the user to manipulate the
plot space directly. Instead of
assigning a plot to a particular plot space, you just specify whether to use
the primary or secondary axis (for
both X and Y independently). The plot space transforms are implicit and
internal to the library.
There are several ways of implementing the relationships between the axes,
plots, and plot space(s). My
feeling is that this should be an implementation detail that is not exposed to
the user of the Core Plot
framework. When we implement features like auto-scale axes and secondary axis
scales, having the user
manage the different plot spaces could become very confusing, especially for a
new user, and could allow the
user to create plot spaces that are incompatible with each other. For instance,
if you have two X-Y plots that
share the X-axis scale, but have different Y-axis scales (e.g., one primary and
one secondary), you have to
manage two different X-Y plot spaces that are somehow linked together so the
X-axes stay synchronized, or
you need separate plot spaces for each axis scale (one X and two Y).
I think add the data range and scaling features that are now part of
CPPlotSpace should be added to the axis
classes to eliminate the need for a user to interact with the plot space model
directly. This is conceptually
cleaner and consistent with other plotting libraries the user may already be
familiar with.
Original comment by eskr...@mac.com
on 23 Aug 2009 at 7:40
The CPPlotGroup is basically the same as CPPlotSpace now: it is a common
superlayer for all plots, making
animations easy, and gives a common base coordinate system. The only difference
is that the plot space also
does transforms to the plot space coordinates.
I am not that concerned if Core Plot is a bit different to other plotting
frameworks, because it is intended to
be a Cocoa solution to plotting. The Cocoa frameworks are also quite different
to other UI frameworks. They
have a unique set of design features (eg delegation, notifications, are quite
minimal, etc), which I think would
be good to guide Core Plot.
It needn't be difficult to keep plot spaces in sync. If we simply provide
notifications and delegate methods for
any changes in scale -- there is actually already a notification used
internally -- it only takes about one line of
code to synchronize two plot spaces. In many ways, this approach is more
powerful: imagine that you wanted
to have one range twice as big as another range. With delegation, this is 3
lines of code for the developer. With
automatic synchronization of axes, you can't do it without modifying the
framework. (In fact, whether you
have plot spaces or not, you will have to provide these delegate methods, so
that people can update non-
Core Plot parts of the UI (eg table views) when ranges change.)
Having said all that, I'm happy to remove the CPPlotSpace class, and have the
other changes made too. I think
we need a way to hide axes, and we should be able to have as many axes as we
want, not just primary and
secondary. Other than that, your plan seems fine.
Since you have the best grasp of the design concepts involved, I suggest you
undertake the changes. They will
involve widespread changes, so probably best make a separate branch.
Original comment by drewmcco...@mac.com
on 24 Aug 2009 at 7:51
I agree about supporting multiple (more than 2) axes. It's rare, but I have
seen examples of this in the past.
HIding an axis should be no problem.
I'll start working on this and agree that it definitely belongs in a separate
branch.
Original comment by eskr...@mac.com
on 24 Aug 2009 at 11:11
Original comment by drewmcco...@mac.com
on 20 Dec 2009 at 3:37
Hello, I was wondering if anyone had implemented "multiple graphs in a column
with the same x-axis" with the
new layer structure? If so, would you mind posting some code on how to
construct the different
plotAreas/plotSpaces for the different plots? Thanks!
Original comment by HMUnderw...@gmail.com
on 10 May 2010 at 5:40
Multiple plot areas will not be implemented before 1.0 of the framework. You
can use multiple plot spaces
though, with careful selection of plot ranges, or multiple host views, each
with a graph, to achieve pretty much
the same thing. Just use the plot space or axis delegate methods to keep things
in sync.
Original comment by drewmcco...@mac.com
on 12 May 2010 at 8:23
Original issue reported on code.google.com by
drewmcco...@mac.com
on 17 Jun 2009 at 3:49