alesnick42 / core-plot

Automatically exported from code.google.com/p/core-plot
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Refactor layers #35

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
The layer hierarchy is not optimal. For example, axes appear drawn on top of 
plots, rather than 
behind them. 

The following changes should be made:

- CPAxisSet should be moved from being a sublayer of CPGraph to being a 
sublayer of CPPlotArea. 
CPPlotArea should not mask its sublayers.
- The CPAxisSet overlay layer should be moved to the CPPlotArea.

Original issue reported on code.google.com by drewmcco...@mac.com on 17 Jun 2009 at 3:49

GoogleCodeExporter commented 8 years ago
I'll work on this one.

Drew

Original comment by drewmcco...@mac.com on 24 Jun 2009 at 7:27

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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:

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago

Original comment by drewmcco...@mac.com on 20 Dec 2009 at 3:37

GoogleCodeExporter commented 8 years ago
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

GoogleCodeExporter commented 8 years ago
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