Drawing graphs iin Dolphin

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

Drawing graphs iin Dolphin

Peter Kenny-2
Could anyone help me with ideas on producing graphic output in a Dolphin
app? I need to plot the values of some numbers coming out of my program,
generally simple x-y line plots with time as the x-axis. I had thought of
using ActiveX to link my program to Excel, but that looks a lot of hassle,
and I only need a small subset of the Excel facilities. So I am working on a
Smalltalk system to generate the necessary plots. I have found that
everything I need can be done using Canvas>>lineFrom:to: and
Canvas>>text:at:, but I am not sure what sort of view to use to provide an
appropriate canvas, and what sort of presenter to use with it. I have
experimented with using a ScribbleView with a Scribble presenter, since
obviously that is a drawing app. When I issue the drawing instructions from
a workspace the graph appears exactly as I want it, but as soon as the plot
window is covered the plot is wiped out. This does not happen with Scribble,
so clearly I am doing something wrong.

I suspect I need to have a graph object, which is assigned as the model of a
graph presenter and is in turn linked to a graph view. I do not know whether
I can use any existing classes as the presenter and view in this set-up; if
not, what would be a good point to start subclassing, and which methods
would I have to override in my subclasses? I am floundering at the moment,
because I am relatively new to Smalltalk.

Two further points:
a. Am I reinventing the wheel here? There is so much stuff out there in
people's goodies packs, perhaps there is what I need already. If so I would
be glad of any pointers (or even shameless plugs from authors).
b. The primary purpose of the plots is for on-line visual display to users,
as part of an interactive analysis. However, users may wish to save some of
them for inclusion in reports. So one consideration in choosing what sort of
view to subclass is the ability to save the display as a file. The only sort
of image saving I can find mentioned in going through the Smalltalk classes
is a bitmap, but this is a pain for inclusion in a report, because you have
to use it at exactly the original size or destroy the image quality. What is
needed is a scalable drawing format like WMF. Do any of the available
classes provide the possibility of saving the display as a .wmf file?

Thanks for any help.

Peter Kenny


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Chris Uppal-3
Peter Kenny wrote:

> I suspect I need to have a graph object, which is assigned as the model
> of a graph presenter and is in turn linked to a graph view. I do not know
> whether I can use any existing classes as the presenter and view in this
> set-up; if not, what would be a good point to start subclassing, and
> which methods would I have to override in my subclasses? I am floundering
> at the moment, because I am relatively new to Smalltalk.

That is probably the right place to start.  It's the approach /I've/ taken,
anyway, so I hope it's optimal ;-)

I think the key point that you are missing is that you need to provide your own
implementation of View>>onPaintRequired: that does the actual drawing.  This is
called when Windows decides that it wants your application to refresh part of
its display.  In this case your View would use the data from the Model to paint
the graph on the Canvas.

(BTW, Ian's archive and/or Google will show lots of discussion of the finer
points of graphics work if you search for "Canvas").

Ian also has a tutorial at <http://www.iandb.org.uk/> (the "buildview"
tutorial) which has an example of drawing a histogram as part of an
application.  That tutorial is very slightly out of date in that it mentions
CompositePresenters here and there, but they have been unnecessary since D4 (or
D5?) when OA made all Presenters be able to act as composites.


> a. Am I reinventing the wheel here? There is so much stuff out there in
> people's goodies packs, perhaps there is what I need already. If so I
> would be glad of any pointers (or even shameless plugs from authors).

Oddly, I don't know of anything that anyone has published.  That may be because
its difficult to write a self-contained graphing package without it sprawling
out to be absolutely /huge/ (see the jFreeGraph package for a -- Java --
example of this).  I know that the reason I'm not planning to put my own graph
stuff on my website is that the only way I've been able to keep it simple
enough to be implementable is to concentrate of the features I actually need to
the point where I can't imagine it being any real use to anyone else.


> What is needed is a scalable drawing
> format like WMF. Do any of the available classes provide the possibility
> of saving the display as a .wmf file?

I imagine that there is some way to create a Canvas representing a .wmf file,
but I've never needed to find out how to do it.  For displaying .WMF files, you
can use an ImagePresenter and an OLEPicture, e.g:

    file := 'whatever.wmf'.
    picture := OLEPicture fromFile: file.
    ImagePresenter show: 'Basic image' on: picture.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Andy Bower-3
Peter,

If you find that your graphing requirements are anything more than just
trivial then I would recommend using an ActiveX charting control from
within Dolphin. There are a number of these available and the interface
methods are easily generated using the ActiveX Wizard. If you don't
mind spending some money then we would recommend Steema's TChart
control.

www.steema.com

Best regards,

Andy Bower
Dolphin Support
www.object-arts.com


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Andy Bower-3
Peter,

Further to my previous message, there's a small example (although not
very complex) of the use of TChart from within Dolphin at:

http://www.object-arts.com/downloads/misc/genelab.png

--
Andy Bower
Dolphin Support
www.object-arts.com


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Chris Uppal-3
Andy Bower wrote:

> http://www.object-arts.com/downloads/misc/genelab.png

Interesting application...

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Bill Schwab-2
In reply to this post by Chris Uppal-3
Chris, Peter,

> That is probably the right place to start.  It's the approach /I've/
taken,
> anyway, so I hope it's optimal ;-)

Same here, on both counts.


> I think the key point that you are missing is that you need to provide
your own
> implementation of View>>onPaintRequired: that does the actual drawing.
This is
> called when Windows decides that it wants your application to refresh part
of
> its display.  In this case your View would use the data from the Model to
paint
> the graph on the Canvas.

I think it is better to add yet another object that provides this service to
said view, and can be rescaled for printers, etc.


> Oddly, I don't know of anything that anyone has published.  That may be
because
> its difficult to write a self-contained graphing package without it
sprawling
> out to be absolutely /huge/ (see the jFreeGraph package for a -- Java --
> example of this).  I know that the reason I'm not planning to put my own
graph
> stuff on my website is that the only way I've been able to keep it simple
> enough to be implementable is to concentrate of the features I actually
need to
> the point where I can't imagine it being any real use to anyone else.

Same here.  However, I probably should clean it up and post it.


> > What is needed is a scalable drawing
> > format like WMF. Do any of the available classes provide the possibility
> > of saving the display as a .wmf file?
>
> I imagine that there is some way to create a Canvas representing a .wmf
file,
> but I've never needed to find out how to do it.  For displaying .WMF
files, you
> can use an ImagePresenter and an OLEPicture, e.g:

IMHO, the better approach is to draw in inches (or mm if you are so
calibrated), and scale through the resolution of the output device.

Peter, if you create something that renders obects on a canvas, then you can
create a bitmap, obtain its #canvas, have your evolving code draw on it, and
then use an ImagePresenter to display the results.  That approach will save
you some hassles with zombie presenters - the voice of experience talking :)
Once everything works, you can more easily/safely create a model/presenter
pair to make it easier to use.

In addition to scaling to printers, another reason to roll your own graphics
is that you will not have to worry about installing/licensing an ActiveX
control on other machines.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Peter Kenny-2
Thanks to all for the comments. I still haven't cracked it, but at least the
problems are clearer (or at least I think I know where they lie).

a. Chris - I see the crucial point is that I must have a method for
#onPaintRequired:, which in turn sends #drawOn: to the model (in this case
my graph object). I have ensured that the graph object is the model for the
view I am using, which is still a ScribbleView, and the object has a
#drawOn: method, which I have single-stepped through with the debugger.
Everything seems to happen OK, the drawing instructions are issued, but
nothing appears. (I know the #drawOn: method is called at the right point,
because I put a 'self halt' in it; when I want to close the walkback, the
window has to be repainted, which generates another walkback, and so ad
infinitum - isn't debugging fun!)

b. I have obviously got to learn more about views and canvases than I really
want to know if I am going to crack this. One thing bugs me at the moment.
Almost all the #onPaintRequired; methods I have found begin:
    onPaintRequired: aPaintEvent
    |canvas|
    canvas := aPaintEvent canvas
and this provides the canvas for the #drawOn: method. But inside the method
the canvas has extent = 1280@1024 (i.e. the whole screen) and windowExtent =
viewportExtent = 1@1. Nothing bears any  relationship to the actual extent
of the graph window I am trying to draw on.

c. Andy - I have thought of the ActiveX route, but if I do that I would use
Excel, because almost all the target users are expected to have it already.
The problems with that are, first, it looks as though there are different
type libraries for the current Excel and for earlier versions, so my program
would have to discover which version the user had loaded; second, I want to
produce compound graphs consisting of several graphs stacked side by side
with the same y-axis, which I have tried to do in free-standing Excel and
found very messy if not impossible. I actually have a charting control
called ChartFX, which I acquired years ago with Delphi and which I think is
licensed for redistribution; I may try it later if the do-it-yourself
approach fails.

d. Bill - I was thinking in terms of saving the view from the screen as a
file. I see now that the save instruction could instead prompt the system to
redraw the graph on another canvas, more suitable for saving, and then save
that. I thought of a scalable format like .wmf because the users are likely
to save the graph as a record of the analysis and put it in a report, which
is probably a MSWord document; they may want it as a whole page or embedded
in a page, and it would be a pity if they had to come back to my program and
rerun in order to resave it at the size needed. I suppose I could provide
options to save a bitmap at whole-page, half-page or quarter-page sizes, if
.wmf is not possible.

e. There is still a question in my mind as to whether Windows provides
options for handling .wmf pictures, which maybe OA have chosen not to wrap
in Dolphin. IPicture class>>fromBitmap: and fromIcon: refer to constants
PICTYPE_BITMAP = 1 and PICTYPE_ICON = 3. Could there be other picture types
available?

f. I am still puzzling a bit over MVP strategy. I have a group containing a
graph model, a graph presenter and a graph view, which is obviously an MVP
triad as a component. But where does this fit in the MVP framework of the
whole application. Drawing a graph is part of the user interface, not part
of the underlying calculation, so it is not part of the overall model. So
where does my graph object class belong in the object hierarchy? - all the
classes in the main model are under Model. Is this all just a question of
labelling, or does it have any implication for the functioning of the
system?

Sorry that this is longer than most contributions to this group. I grew up
in an era when we learned to write essays, not text messages, and anyway
writing out like this helps to get it clear in my mind.

Thanks again

Peter Kenny


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

geringerNOSPAMMM
Peter,

I am also looking for a graphic/charting solution for my application.

A few years back I spent a week or two trying to use the GDIlibrary
stuff.  Ended up with a primitive looking solution.  (Scaling and
inserting labels were problems).

Here are some thoughts on your MVP questions:

In my case:

Model =  TPGraphingObject subclass of Model
Presenter =  TPBarGraphPresenter subclass of Presenter  (this has
stuff that would need to be refactored if the solution was more complete)
View = TPGarGraph Subclass of View

Edit the default view of the TPBarGraphPresenter and insert a TPBarGraph
view object.  (Also, heep in mind the TPBarGraph view is an instance in
the TPBarGraphPresenter's view.  under some conditions you need to
destroy and re-insert it).

Then use the TPBarGraphPresenter on the view of your window shell.

... I recently brushed the dust off this code and could not get it
to display...then I found the following "magic incantation" in the
archives of this newsgroup and it displayed:

TPBarGraphPresenter addView: TPBarGraph asResource: 'DefaultView'

I never bothered to figure out why this worked or if could be done
differently...it just worked and I saw my default model displayed in the
view composer and I was happy with that...

(As a side note...I could not actually load the package where this code
was stored due to some object filer walkback on some view in the
package...so I had to open the .pac file with wordpad and cut and paste
the source code that I needed...this may be why it didn't all come back
together at first)

Regarding your conceptual question about the model...
yes, TPGraphingObject is not strictly speaking a business model object.
It is a runtime only object which is destroyed and recreated for each
user action.  Each time the user selects a different view of their data,
it gets a new TPGraphingObject and sets the model in the presenter to
this new object.


Hope that helps,
Steve Geringer

http://www.TradePerformance.com


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Peter Kenny-2
<[hidden email]> wrote in message
news:1RxGc.129373$[hidden email]...
>
>
>
> Model =  TPGraphingObject subclass of Model
> Presenter =  TPBarGraphPresenter subclass of Presenter  (this has
> stuff that would need to be refactored if the solution was more complete)
> View = TPGarGraph Subclass of View

Steve

Thanks for the hints - I am trying to follow what you suggest. At the moment
I can't generate my view class as a direct subclass of View - or rather I
don't know how to generate the view resource to go with it. I have tried
using various existing view resources as the starting point (e.g.
ImageView.Basic image, TextPresenter.Multiline text and my old favourite
Scribble), but they all finish up carrying all the methods of their original
view classes, even though I have put them at a different point in the
hierarchy. Obviously I am completely confused by MVP. Maybe I should take
your hint (that the results are not good enough to be worth the effort) and
try the ActiveX route.

Thanks

Peter Kenny


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

geringerNOSPAMMM
Peter,

I would rather have a smalltalk solution than an activeX or third party
solution because a few years ago I evaluated Smalltalk Systems
WidgetKit/Business graphics for visualAge.
http://www.instantiations.com/sts/wkbg.htm
I had a terrible time with it.  after about two weeks I still could not
figure how to get their default labels off of my charts.  Plus, after
the evaluation expired, I could not even load my own code due to some
dependency issues.

In any case, last night I spent some time looking at ActiveX charting
packages and found a number of them with in the $300-$400 price range.
Unfortunately these seem to be licenses per developer machine.  (i keep
my code on a flash drive and work on diffrent machines depending on my
mood).

However, I did discover something pretty slick.  There were two products
which were based on Shockwave flash.  They sell you a .swf file and you
actually sent it xml to build the chart.  This is designed for use with
web applications.

see...

http://www.infosoftglobal.com/FusionCharts/Gallery.asp
http://www.infosoftglobal.com/fxgraph/


One plus is that it is animated...you see the chart grow which is kind
of flashy (I assume this is optional).  Another plus is you don't have
to own the Flash MX development tool @ $499.   (or whatever tool you
would need.  they seem to have alot of different tools)


The Big question...

Does anyone know if/how to imbed a Shockwave activeX component into a
Dolphin Application?   (I have no experience with imbeding anything
activeX into Dolphin smalltalk.)

Finally two other things to investigate.  Microsoft MSChrt20.ocx seems
to come with visual studio which many people own...no need to buy
another.  Also, there is also a dolphin GDI++ library wrapper...which
someone here is working on...not sure if it alleviates any of these
problems...


Steve

http://www.TradePerformance.com


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Schwab,Wilhelm K
In reply to this post by Peter Kenny-2
Peter,

> d. Bill - I was thinking in terms of saving the view from the screen as a
> file. I see now that the save instruction could instead prompt the system to
> redraw the graph on another canvas, more suitable for saving, and then save
> that. I thought of a scalable format like .wmf because the users are likely
> to save the graph as a record of the analysis and put it in a report, which
> is probably a MSWord document; they may want it as a whole page or embedded
> in a page, and it would be a pity if they had to come back to my program and
> rerun in order to resave it at the size needed. I suppose I could provide
> options to save a bitmap at whole-page, half-page or quarter-page sizes, if
> .wmf is not possible.

When you speak of users embedding the result in other documents, then a
meta file makes sense.  When you know the output device, I recommend
rendering at its resolution, but meta files have their uses too.



> f. I am still puzzling a bit over MVP strategy.

That will continue for some time, not because MVP has problems, but
because it is quite flexible.


 > I have a group containing a
> graph model, a graph presenter and a graph view, which is obviously an MVP
> triad as a component. But where does this fit in the MVP framework of the
> whole application. Drawing a graph is part of the user interface, not part
> of the underlying calculation, so it is not part of the overall model.

There is a space/speed tradeoff to consider.  Suppose that you have a
bunch of nerds that go into concert halls, stand on stage, fire a pistol
(loaded with blanks of course) and record the resulting sound at various
locations.  Sound nutty?  It happens.  When I was involved with this
kind of work, the data sets were a little on the big side for computers
of the time.  Rendering the various graphs we wanted to see was
expensive, and it made a lot of sense to draw to a bitmap that could be
painted on the screen rapidly (even rescaled as appropriate), rather
than going back to the raw data.

I strongly urge you to build something that allows you to render to an
arbitrary canvas, and therefore to a display-compatible bitmap.  That
will simplify your debugging (no partially open presenters to cause
trouble).  Of course, it can also draw on a view's canvas too, so there
is nothing to stop you from directly rendering small data sets.


 > So
> where does my graph object class belong in the object hierarchy? - all the
> classes in the main model are under Model. Is this all just a question of
> labelling, or does it have any implication for the functioning of the
> system?

My solution to the problem was to make two graph presenters, one w/o
labels, and one that adds labels, using the basic graph presenter to the
  graphics, and text presenters (static text views) to display the labels.

Of course, you can also simply render the text as part of the graphics,
and I end up doing that on printers and for "presentation graphics".


Have a good one,

Bill


--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Chris Uppal-3
In reply to this post by Bill Schwab-2
Bill,

> I think it is better to add yet another object that provides this service
> to said view, and can be rescaled for printers, etc.

Agreed entirely.  I use a "painter" object that is logically separate from the
View too -- in fact it's an "editable aspect" of the View so I can still create
and configure them in the VC, but am not tied to using them to paint on
Windows.


> Peter, if you create something that renders obects on a canvas, then you
> can create a bitmap, obtain its #canvas, have your evolving code draw on
> it, and then use an ImagePresenter to display the results.  That approach
> will save you some hassles with zombie presenters - the voice of
> experience talking :) Once everything works, you can more easily/safely
> create a model/presenter pair to make it easier to use.

That's a good idea.  I tend to do it the other way around, though, and develop
with the painter object drawing directly into an open View -- that does have
the advantage in immediacy, but I do have to put a

    on: Error
    do: [err | err notify]

around the painting code in #onPaintRequired: to avoid the risk of a cascade of
walkbacks.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Chris Uppal-3
In reply to this post by Peter Kenny-2
Peter,

> a. Chris - I see the crucial point is that I must have a method for
> #onPaintRequired:, which in turn sends #drawOn: to the model (in this case
> my graph object). I have ensured that the graph object is the model for
> the view I am using, which is still a ScribbleView, and the object has a
> #drawOn: method, which I have single-stepped through with the debugger.
> Everything seems to happen OK, the drawing instructions are issued, but
> nothing appears.

Is it possible that your paintng code is buggy ?  Or that you are drawing in
white on a white background ?


> b. I have obviously got to learn more about views and canvases than I
> really want to know if I am going to crack this. One thing bugs me at the
> moment. Almost all the #onPaintRequired; methods I have found begin:
>     onPaintRequired: aPaintEvent
>     |canvas|
>     canvas := aPaintEvent canvas
> and this provides the canvas for the #drawOn: method. But inside the
> method the canvas has extent = 1280@1024 (i.e. the whole screen) and
> windowExtent = viewportExtent = 1@1. Nothing bears any  relationship to
> the actual extent of the graph window I am trying to draw on.

Yes, that seems to be a problem with Windows, and has been discussed here
before quite recently.  See the thread from May entitled "Very big bitmap
doesn't work".  What I do is to use the View's #clientRectangle or
#clientExtent to determine what to draw on.  Like Bill, I use a painting object
that is logically separate from the View itself, so my #onPaintRequired: is
roughly like:

    onPaintRequired: aPaintEvent
        self painter
            paintOnCanvas: aPaintEvent canvas
            in: self clientRectangle.


> e. There is still a question in my mind as to whether Windows provides
> options for handling .wmf pictures, which maybe OA have chosen not to wrap
> in Dolphin. IPicture class>>fromBitmap: and fromIcon: refer to constants
> PICTYPE_BITMAP = 1 and PICTYPE_ICON = 3. Could there be other picture
> types available?

I've taken a glance through the archives, and it appears that nobody has yet
produced a wrapper for metafiles (unless there's something in the GDIPlus
wrapper ?).  It looks as though it would probably be quite easy for someone who
knows that level of Dolphin/Windows integration to produce, but then, if it
were that easy, surely somebody would have done it by now ;-)


> f. I am still puzzling a bit over MVP strategy. I have a group containing
> a graph model, a graph presenter and a graph view, which is obviously an
> MVP triad as a component. But where does this fit in the MVP framework of
> the whole application. Drawing a graph is part of the user interface, not
> part of the underlying calculation, so it is not part of the overall
> model. So where does my graph object class belong in the object
> hierarchy? - all the classes in the main model are under Model. Is this
> all just a question of labelling, or does it have any implication for the
> functioning of the system?

It's really just a labelling issue.  The only real difference between a Model
and any other Object is that a Model as an optimised implementation of the
Observer pattern (#trigger, #when:send:to:, etc).

You may want to consider moving your painting logic out of the Model and into a
separate Painter object that is owned by the View.  That would make sense if
the rendering has aspects (color, fonts to use, graph style, etc) that are not
logically part of the Model itself.


And, from another post:

> At the
> moment I can't generate my view class as a direct subclass of View - or
> rather I don't know how to generate the view resource to go with it.

When you create a custom View, you create a view resource and associate it with
a Presenter class by evaluating an expression like:

     MyPresenter
        addView: MyView
        asResource: 'Default view'.

You only have to do that once.  As far as I can see there is no strong reason
why you should not be able to do the equivalent from the View Composer, but the
fact is that you can't (without some rather desparate hacking, anyway).

View resources are instances of the View class that have been converted into
ByteArrays using the "STB" mechanism, and then saved in the current
ResourceManager.  The reason you need to be aware of that is that if you change
the definition of the View class (change the instance variables) then stored
view resources will likely not load properly.   You can add code to your View
class to convert old resources to the new format on-the-fly if you want (its
straightforward to do), but I assume you don't want to get into that now.  If
not then you'll have to ensure that you re-execute the above expression to
replace the stored resouces if/when you change the layout of your View class.
(I'd also recommend using "reference views" wherever possible to embed your
custom Views in other composite Views -- hold down the ALT key when you drag a
View from the resource list in the View Composer.)

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Peter Kenny-2
"Chris Uppal" <[hidden email]> wrote in message
news:[hidden email]...
> Peter,
 What I do is to use the View's #clientRectangle or
> #clientExtent to determine what to draw on.  Like Bill, I use a painting
object
> that is logically separate from the View itself, so my #onPaintRequired:
is
> roughly like:
>
>     onPaintRequired: aPaintEvent
>         self painter
>             paintOnCanvas: aPaintEvent canvas
>             in: self clientRectangle.
>
Chris - Yes! It works! This turned out to be the crucial step. I followed
all the rest of the instructions (as in Ian's tutorial on 'Buildview') and
got nothing, but as soon as I put in the clientRectangle bit the graph
appeared. At the moment it is just the curves on the graph, with no grid,
scales or headings, but they are just implementation details (famous last
words!).

Thanks to you, and to all the other people who commented. I shall bear their
words of wisdom in mind. At the moment I am just happy to have something
that works (sort of), but I may well restructure it to use a separate
drawing object - at the moment my #onPaintRequired: calls a
#drawOn:withRect: method which sits in the graph object. Some of what I did
still seems like a 'magic incantation', as Steve Geringer calls it, but I
think I have a glimmer of understanding, thanks to your description.

Peter Kenny


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Schwab,Wilhelm K
In reply to this post by Chris Uppal-3
Chris
> It's really just a labelling issue.  The only real difference between a Model
> and any other Object is that a Model as an optimised implementation of the
> Observer pattern (#trigger, #when:send:to:, etc).

At the risk of confusing Peter (but he seems like he's ready for
this<g>), objects can be "models" without being derived from Model.  You
are, of course, very correct about the optimizations for events, but
that is not essential to serve as a view's #model.

Peter, it is probably most important that you concentrate on building
something (one might say anything) that works without being too
concerned with details.  Following some of the suggestions in this
thread will spare you some of the false starts that a few of us
obviously have in common.  Once you have something the produces graphic
output, you can begin to enhance it.  Feel free to ask for advice on
where to put your more presentation-oriented features, etc.

In general, a good approach to Smalltalk (by no means original to me)
is: (1) make it run; (2) make it work; (3) make it fast.

Smalltalk's flexibility allows you to make fairly sweeping changes with
little backlash (most of the time).  Probably the first snag that you
should work to avoid is having errors in #onPaintRequired:.  Chris traps
them (as do I in views); I generally draw to a bitmap first so errors
are not a problem, and simply lead to a walkback and then a debugger.
In fact, I generally don't bother with a presenter as I start a new
graphic; I write code to open an image presenter on the output only when
I _don't_ see a walkback :)

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Chris Uppal-3
In reply to this post by geringerNOSPAMMM
Steve,

> However, I did discover something pretty slick.  There were two products
> which were based on Shockwave flash.  They sell you a .swf file and you
> actually sent it xml to build the chart.  This is designed for use with
> web applications.

That's a nice idea.

They even have their website set up so that you can see most of the examples
without having Flash installed, which is a nice touch.  (Unlike the TChart
folk -- why do people /do/ that... ?)

I remember sitting around a big table some years ago trying to think of a new
product to re-invent the failing company I was then working for.  We had LOTS
of kit, some decent talent, some money in the bank, but what to do with it...
I suggested tools for creating thin-client UIs in Flash, but nobody liked the
idea much.  We wouldn't have been able to do it anyway, but its nice to think
that the idea hasn't died completely.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Peter Kenny-2
In reply to this post by Schwab,Wilhelm K
"Bill Schwab" <[hidden email]> wrote in message
news:cchk52$ibq$[hidden email]...
> Chris
> > It's really just a labelling issue.  The only real difference between a
Model
> > and any other Object is that a Model as an optimised implementation of
the

> > Observer pattern (#trigger, #when:send:to:, etc).
>
> At the risk of confusing Peter (but he seems like he's ready for
> this<g>), objects can be "models" without being derived from Model.  You
> are, of course, very correct about the optimizations for events, but
> that is not essential to serve as a view's #model.
>
> Peter, it is probably most important that you concentrate on building
> something (one might say anything) that works without being too
> concerned with details.  Following some of the suggestions in this
> thread will spare you some of the false starts that a few of us
> obviously have in common.  Once you have something the produces graphic
> output, you can begin to enhance it.  Feel free to ask for advice on
> where to put your more presentation-oriented features, etc.
>
> In general, a good approach to Smalltalk (by no means original to me)
> is: (1) make it run; (2) make it work; (3) make it fast.
>
> Smalltalk's flexibility allows you to make fairly sweeping changes with
> little backlash (most of the time).  Probably the first snag that you
> should work to avoid is having errors in #onPaintRequired:.  Chris traps
> them (as do I in views); I generally draw to a bitmap first so errors
> are not a problem, and simply lead to a walkback and then a debugger.
> In fact, I generally don't bother with a presenter as I start a new
> graphic; I write code to open an image presenter on the output only when
> I _don't_ see a walkback :)
>
> Have a good one,
>
> Bill

Bill
Thanks for this advice. I seem to have hit on  some of these approaches
myself, while trying to follow the advice from people in this group. I now
have a graphing system which works a bit. The top-level presenter selects up
to three functions of time for plotting and passes them as an
OrderedCollection to a Graph class method, which generates a graph object,
and then the top presenter assigns this object as the model of the graph
pane. The #onPaintRequired: method of the pane sends #drawOn:withRect: to
the graph object, which draws itself in the specified rectangle of the
specified canvas. The resulting graph scales itself to a 'sensible' range
and grid interval and then draws a dashed background grid and the selected
functions. There are no labels of any kind as yet, not even scales on the
axes.

One advantage of the incremental approach is that you can review your design
objectives in the light of what you have done. Yesterday, having played with
the window with a graph pane working (it redraws instantly when I switch to
a different set of data), I realised that a graph for interactive use as a
diagnostic tool in an analysis is not the same thing as a presentation graph
for use in a report, and it is daft to conflate the two. So I shall not be
adding much in the way of labelling to the graph, just numbers on the axes,
because all the relevant information is available in other panes. This way I
get the maximum space (and maximum visible detail) for the plot itself. If
users want to save the plot as a presentation quality graph, that can be
added later in a separate editable window.

Thanks for the offer of future advice. I feel more confident having got this
far, but I shall probably be back!

Peter
>
> --
> Wilhelm K. Schwab, Ph.D.
> [hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Stefan Schmiedl
In reply to this post by Peter Kenny-2
On Tue, 6 Jul 2004 11:45:37 +0100,
Peter Kenny <[hidden email]> wrote:

>
> b. I have obviously got to learn more about views and canvases than I really
> want to know if I am going to crack this. One thing bugs me at the moment.
> Almost all the #onPaintRequired; methods I have found begin:
>     onPaintRequired: aPaintEvent
>     |canvas|
>     canvas := aPaintEvent canvas
> and this provides the canvas for the #drawOn: method. But inside the method
> the canvas has extent = 1280@1024 (i.e. the whole screen) and windowExtent =
> viewportExtent = 1@1. Nothing bears any  relationship to the actual extent
> of the graph window I am trying to draw on.

Don't let yourself become confused by the way Windows names concepts.

Viewport coordinates refer to "device units", commonly known as pixels.
Window coordinates refer to "logical units" used by your program.

The relationship between those two is governed by a concept called
MapMode. Your data point windowExtent = viewportExtent = 1@1 only means
that you're working with pixel based coordinates and that the y-axis
points down.

You should also find a viewportOrigin and a windowOrigin.
The viewportOrigin contains the "absolute" position of the origin in
device units and is useful if you want to put the origin into the lower
left corner of the window.
The windowOrigin determines where your "logical" origin lies in
relationship to this point.

As long as you have GDI-friendly coordinates, you can exchange the
headache caused by manual scaling and shifting for the headache
necessary to understand how MM_ANISOTROPIC et al. work.

BTW: There is almost no difference between drawing into a window and
drawing into a WMF or EMF file. You won't need ActiveX components to
display those, either, as Windows has builtin functions for handling
this kind of tasks.

I found the Win32-API help file (old version, available for download)
enormously helpful. And much more useable than that modern HTML-help
monstrosity.

s.


Reply | Threaded
Open this post in threaded view
|

Re: Drawing graphs iin Dolphin

Peter Kenny-2
Stefan,

"Stefan Schmiedl" <[hidden email]> wrote in message
news:[hidden email]...
> On Tue, 6 Jul 2004 11:45:37 +0100,
> Peter Kenny <[hidden email]> wrote:

> Don't let yourself become confused by the way Windows names concepts.
>
A bit late - I am thoroughly confused, though the fog is lifting a bit. I
have a method which works, though  I'm not quite sure how, and I shall stick
to it!

> Viewport coordinates refer to "device units", commonly known as pixels.
> Window coordinates refer to "logical units" used by your program.
>
> The relationship between those two is governed by a concept called
> MapMode. Your data point windowExtent = viewportExtent = 1@1 only means
> that you're working with pixel based coordinates and that the y-axis
> points down.
>
> You should also find a viewportOrigin and a windowOrigin.
> The viewportOrigin contains the "absolute" position of the origin in
> device units and is useful if you want to put the origin into the lower
> left corner of the window.
> The windowOrigin determines where your "logical" origin lies in
> relationship to this point.
>
I think I see this, but I seem to have found a way round it by following
Chris Uppal in working with the client rectangle. I know that my coordinates
are in pixels relative to this rectangle.

> As long as you have GDI-friendly coordinates, you can exchange the
> headache caused by manual scaling and shifting for the headache
> necessary to understand how MM_ANISOTROPIC et al. work.
>
> BTW: There is almost no difference between drawing into a window and
> drawing into a WMF or EMF file. You won't need ActiveX components to
> display those, either, as Windows has builtin functions for handling
> this kind of tasks.

This looks interesting, and I shall try to follow this up when I can. I am
using screen based graphs only at present, but when I want presentation ones
I shall know what to do.
>
> I found the Win32-API help file (old version, available for download)
> enormously helpful. And much more useable than that modern HTML-help
> monstrosity.
>
> s.
Thanks for the tip. I think I may have a copy on my old machine.

Thanks and best wishes

Peter