From: nospam on
Hi Mike

Sorry for the long delay in response. I spent the weekend installing
Windows 7 on my main (developer) machine and it's been a slow process
from XP Professional.

Anyway... (responses between text below)

On Fri, 27 Nov 2009 05:30:04 -0000, "Mike Williams"
<Mike(a)WhiskyAndCoke.com> wrote:

>"Webbiz" <nospam(a)forme.thanks.com> wrote in message
>news:2rhtg5t0qaq95h56u3f4t1p1ke331g7163(a)4ax.com...
>
>> When you discussed the thinkness of the line being more
>> than 1 pixel, I suppose you are referring to when my app
>> sets the DrawWidth > 1, right?
>
>Yes. DrawWidth sets the thickness of the line in pixels, regardless of the
>VB ScaleMode you might be using.
>
>> Let's take one of these line draws as an example.
>> 'Draw the main vertical bar
>> frmChart.pctChart.Line ((i - (gFirstBarRecNum)) * gHSpace,
>> dblLowPoint)-((i - (gFirstBarRecNum)) * gHSpace, dblHighPoint),
>> lngColor
>> Break it down to...
>> X1 = (i - (gFirstBarRecNum)) * gHSpace
>> Y1 = dblLowPoint
>> X2 = ((i - (gFirstBarRecNum)) * gHSpace) - Int(gHSpace / 2)
>> Y2 = dblHighPoint
>> frmChart.pctChartLine (X1, Y1) - (X2, Y2)
>
>It looks as though you have broken that down wrongly (which is probably just
>a typo) because the former appears to draw a vertical line (your main bar)
>whereas the latter appears to draw a small horizontal line (either your
>opening or closing price marker), so they are not equivalent, but I think I
>can see what you mean . . .

Would not doubt it. I broke it down for the post only. In the code
itself, it's not broken down. Just wanted to try and make it read
easier here.

>
>> . . . frmChart.pctChartLine (X1, Y1) - (X2, Y2)
>> If I were to replace the above line with the FillRect
>> API code, what would be the approach? This ...
>> Dim r as RECT, retval as Long, brush as Long
>> ' Set the coordinates of the bar/rectangle
>> retval = SetRect(r, X1, Y1, X2, Y2)
>> brush = CreateSolidBrush(lngColor)
>> retval = FillRect(frmChart.pctChart.hDC, r, brush)
>
>Not quite, because the Line coordinates represent the two ends of a line
>whereas the FillRect coordinates represent the coordinates of the top left
>corner and the bottom right corner of a rectangle.

That's right. I better keep that point in mind. ;-)

>As far as the FillRect
>coordinates are concerned (as they relate to the coordinates you would use
>for the Line method) it depends on the thickness of the line and on its
>orientation (vertical or horizontal). It also depends on the
>pctChart.ScaleMode you are using, because the VB Line method uses ScaleMode
>units for the X1, Y1, etc coordinates whereas the FillRect function (as with
>all other GDI drawing functions) defaults to using Pixels. So, if you're not
>using pixels as your ScaleMode then you would need to perform the
>appropriate conversion (or alternatively you can force the GDI functions to
>use something other than pixels, but that's another story and is best
>avoided for now). On the assumption that your pctChart.ScaleMode is vbPixels
>(if not then there will be a little more math) then, using your own VB Line
>method example, here are the equivalent FillRect methods ("wide" is a Long
>variable containing the desired line thickness in pixels) . . .
>
>frmChart.pctChartLine.DrawWidth = wide
>frmChart.pctChartLine (X1, Y1) - (X2, Y2)
>
>. . . the equivalent for a vertical line would be
>
>SetRect r, X1 - wide \ 2, Y1, X2 + wide - wide \ 2, Y2 + 1
>FillRect frmChart.pctChart.hdc, r, brush1
>
>. . . and for a horizontal line it would be:
>
>SetRect r, X1, Y1 - wide \ 2, X2 + 1, Y2 + wide - wide \ 2
>FillRect frmChart.pctChart.hdc, r, brush1
>
>You also need to remember that the VB Line method draws rounded ends on
>lines thicker than one pixel (or at least it attempts to do so, with the
>degree of success depending on the thickness of the line). These rounded
>ends are generally added to each end of what would otherwise be a flat edged
>line, thereby making it slightly longer than your coordinates when you are
>drawing fairly thick lines. The FillRect function will of course not do
>that, and will produce a perfectly squared off line of exactly the size and
>thickness you require. Personally I think that for your own purposes you are
>better off without those rounded ends anyway, but that's a personal choice
>of course.

This is did not know as well. Rounded ends? How odd. Yes, my chart app
would be better served with square edges.

>
>> I would assume that the 'brush' is set once if all the bars will
>> have the same color. Then for every .Line code, replace it
>> with two lines, the SetRect and FillRect lines.
>
>Yes. You need create only one brush and you can use it to draw as many
>"lines" (FillRects) as you wish. When you have finally finished with the
>brush (and certainly before your program ends) you must delete it (using the
>DeleteObject function), otherwise you will have a memory and resource leak.
>Since you will be using the brush over and over again for as long as your
>program is running I would suggest that you declare it as Private in your
>frmChart declarations section (Private BrushBlack as Long, for example) and
>create it (CreateSolidBrush) in your frmChart Load event and delete it
>(DeleteObject) in your frmChart Unload event. In that way you will be able
>to use it in all blocks of code in that Form. You can of course create as
>many different colour brushes as you wish, in exactly the same way, so for
>example you could have BrushBlack, BrushRed, BrushGreen, BrushBlue etc, all
>declared as Private in the declarations section of frmChart and all created
>in the Load event and deleted in the Unload event.

So in other words, I could create all the color brushes I will need
(and there are a few I would need... Red, Blue, Green, Black).

This brings up something else.

Currently, in order to show the user which bar on the chart the mouse
is currently associated with, I have been using a line control
(lnPriceBar) that is moved over the vertical bar on the chart, causing
it to change color (currently to Fuchsia - I didn't pick it ;).

'======= HIGHLITE PRICE BAR


If lRecNum <= gLastBarRecNum Then
'change current selected into Fuchsia
With lnPricebar
.BorderWidth = pctChart.DrawWidth + 2
.x1 = gCurrentBar * gHSpace
.y1 = dblHighPoint
.x2 = .x1
.y2 = dblLowPoint
.Visible = True
End With
End If

I'm assuming I'll need to do this differently if I'm going to use
FillRect.

The whole idea here is that the vertical bar needs to change colors
when the mouse is moved to the same X coordinate as the bar, letting
the user which bar is currently selected as the mouse is moved left to
right. The data of the bar is currently displayed in the panel below
the chart for the highlighted bar.

When the mouse is moved off that vertical bar, it must return to the
original color.

Any thoughts on that?

>
>There were a number of points raised in your post and I'm not sure whether I
>have covered them all here, and of course I may have forgotten to mention
>some things that I had intended to mention, but I think that about covers
>it.

That's me. Always with a number of posts raised. Of all the aspects of
VB, the graphics part always seem to be the stickler for me. Pixels,
Twips, blah blah.

Oh, as to your question on whether my picbox is set to Twips or
Pixels, BOTH.

When the chart is drawn with the vertical bars, it is set to Twips.

Public Sub DrawChart(Optional ByVal x As Long)

frmChart.pctChart.ScaleMode = 1 'twips


However, various routines in this project will change this scalemode
to Pixels, such as the routine to 'clip' part of the picturebox for
insertion into posts, emails, etc.

Why can't life be simple and one size fits all? LOL

Thanks.

Webbiz



>
>Mike
>
>
From: nospam on
On Thu, 26 Nov 2009 17:55:24 -0600, "Larry Serflaten"
<serflaten(a)usinternet.com> wrote:

>
>"Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote
>> > 1. Since I am using an AutoRedraw picturebox (frmChart.pctChart)
>> > there is no need for me to do the 'double-buffer' technique because
>> > the picturebox will already be doing this when AutoRedraw = True.
>>
>> Yep. That's about it.
>
>I would raise an objection there. The difference between drawing the chart
>once (to an off screen buffer) and painting in place compared to drawing
>the chart in every Resize event is going to increase as the drawing work
>load increases. For simple (say less than 50 lines) images, the difference
>may be neglegible, but for several hundred lines, the difference will be
>signifcantly more noticable.
>
>If you're only talking about drawing the visible portion of the chart on
>each Resize (or Scroll) event, then I would agree, there is no gain in using
>a second buffer if VB already does it for you. But I would suggest that
>drawing the chart once and painting to the form as needed will be more
>responsive to user input....
>
>LFS
>

On average, a complete chart based on all the data loaded would be
about 20-30 years worth. At about 200+ bars per year, that would be a
complete chart of about 5000 vertical bars.

Usually, the user will only view about 100 - 200 at a time in a single
view. Most times, the user may scroll back another 100 - 200 bars, but
not the whole 5000. Yet, sometimes they might.

Assuming a display setting of 200 bars, the app will start out
displaying the last 200 bars of the chart. So the DrawChart routine
simply gets the data index for the first bar of that last 200 and
starts drawing the chart from there.

FirstBarRecNum to LastBarRecNum

FirstBarRecNum contains the data array index for X = 0 on the
picturebox. LastBarRecNum would be the 200th data array index for X =
gHSpace * 200

(gHSpace is the horizontal increment from left to right of the
picturebox to draw the vertical bars)

If the user SCROLLS this chart, the picturebox is cleared, and the
chart is redrawn with a new FirstBarRecNum and LastBarRecNum.

For example, with a single bar scroll, the FirstBarRecNum is
incremented or decremented by 1. LastBarRecNum is then the result of
FirstBarRecNum + 200, if there is data for it. LastBarRecNum never
exceeds the UBound of the data array.

===============

So are you suggesting that the app should paint all 5000 bars on the
non-visible picturebox and then display only a portion of it at any
given time? What about the lines and other drawings the user may add
to the chart and will likely save with the chart for later
reload/display?

Thanks.

Webbiz


From: nospam on
On Fri, 27 Nov 2009 07:00:34 -0000, "Mike Williams"
<Mike(a)WhiskyAndCoke.com> wrote:


>In this specific case there is also the problem of the requirement to
>respond to the user's request to magnify portions of the chart, which as I
>vaguely recall (although I could be wrong on that point) from some very much
>earlier postings by Webbiz (in different threads quite some time ago)
>required not just a simple magnification of an existing ready drawn portion
>of the chart but needed to draw various elements so that they gained in
>visible data resolution when they were magnified, a bit like a metafile
>drawing would . . .
>
>. . . now there's a thought :-)
>
>Mike

Ah, good memory there Mike.

Yes, the app has a routine that ZOOMS a portion of the chart with a
sort of MagnifyingGlass. As the mouse moves, that part of the chart is
magnified. Works really nice. :-)

Webbiz

From: nospam on
On Fri, 27 Nov 2009 10:52:54 -0600, "Larry Serflaten"
<serflaten(a)usinternet.com> wrote:

>
>"Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote
>
>> . . . But Webbiz has said that he has an extremely large chart, apparently
>> about the height of the screen but as wide as at least 25 screens and
>> possibly many more,
>
>While I saw that 120 / 3000 post, it simply did not register as being so massive.
>
>I don't know about you, but I think I'd get dizzy looking at 25 screens worth
>of vertical lines scrolling by....
>
>Might there may be a user interface issue there? Perhaps they should be
>categorized, or a favorites list, or something to bring that down to a more
>manageable size. Similar to what is somethimes done when a list has thousands
>of items, etc...
>
>We'll see....
>LFS
>
>

Users may wish to view price data going back years. They may wish to
increase the vertical bar density with the "+" key in order to see
more years at once, or the "-" key to spread the vertical bars apart
to see a certain time frame closer up. Sort of a ZOOM IN and ZOOM OUT
scenario.

Some users have data going back to the early 1900's. I personally use
data files going back to 1980. I may have to see it all at once, or
bounce around to different years to do comparisons, etc.

As a matter of a cut-off, however, data cannot be loaded prior to
1901.

:-)
Webbiz

From: nospam on
On Mon, 30 Nov 2009 14:23:01 -0600, nospam(a)noway.com wrote:

>On Thu, 26 Nov 2009 17:55:24 -0600, "Larry Serflaten"
><serflaten(a)usinternet.com> wrote:
>
>>
>>"Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote
>>> > 1. Since I am using an AutoRedraw picturebox (frmChart.pctChart)
>>> > there is no need for me to do the 'double-buffer' technique because
>>> > the picturebox will already be doing this when AutoRedraw = True.
>>>
>>> Yep. That's about it.
>>
>>I would raise an objection there. The difference between drawing the chart
>>once (to an off screen buffer) and painting in place compared to drawing
>>the chart in every Resize event is going to increase as the drawing work
>>load increases. For simple (say less than 50 lines) images, the difference
>>may be neglegible, but for several hundred lines, the difference will be
>>signifcantly more noticable.
>>
>>If you're only talking about drawing the visible portion of the chart on
>>each Resize (or Scroll) event, then I would agree, there is no gain in using
>>a second buffer if VB already does it for you. But I would suggest that
>>drawing the chart once and painting to the form as needed will be more
>>responsive to user input....
>>
>>LFS
>>
>
>On average, a complete chart based on all the data loaded would be
>about 20-30 years worth. At about 200+ bars per year, that would be a
>complete chart of about 5000 vertical bars.
>
>Usually, the user will only view about 100 - 200 at a time in a single
>view. Most times, the user may scroll back another 100 - 200 bars, but
>not the whole 5000. Yet, sometimes they might.
>
>Assuming a display setting of 200 bars, the app will start out
>displaying the last 200 bars of the chart. So the DrawChart routine
>simply gets the data index for the first bar of that last 200 and
>starts drawing the chart from there.
>
>FirstBarRecNum to LastBarRecNum
>
>FirstBarRecNum contains the data array index for X = 0 on the
>picturebox. LastBarRecNum would be the 200th data array index for X =
>gHSpace * 200
>
>(gHSpace is the horizontal increment from left to right of the
>picturebox to draw the vertical bars)
>
>If the user SCROLLS this chart, the picturebox is cleared, and the
>chart is redrawn with a new FirstBarRecNum and LastBarRecNum.
>
>For example, with a single bar scroll, the FirstBarRecNum is
>incremented or decremented by 1. LastBarRecNum is then the result of
>FirstBarRecNum + 200, if there is data for it. LastBarRecNum never
>exceeds the UBound of the data array.
>
>===============
>
>So are you suggesting that the app should paint all 5000 bars on the
>non-visible picturebox and then display only a portion of it at any
>given time? What about the lines and other drawings the user may add
>to the chart and will likely save with the chart for later
>reload/display?
>
>Thanks.
>
>Webbiz
>

Seems my alias got a bit mucked when I reinstalled the reader into
Windows 7. Here's to hoping it's back to Webbiz. :-b

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9
Prev: Snapshot of screen
Next: HTTPS File Uploads