adding a hscrollbar to a forms.panel

J

jleslie48

So I have a panel, that I draw a graph in. with mousedown mousemove
and mouseup I've programmed a zoom feature for the data. As a result I
might only see 10% of the graph with the other 90% being outside the
boundarys of the panel rectangle. I'd like to add a horizontal scroll
bar so I can view a different section of the plot. Any ideas?


I'm not sure if I explained that very well. here's an example,

let's say my panel goes from (0,0) to (1000,y) so my pixel range for
the panel is 1000.

lets say my data for the plot goes from 1910 to 1950. I set my
original plot so that the X pixel of 0 equates to the 1910, and the
1000 pixel to the 1950.

If I zoom so show only 1930-1940, I rescale my mapping so the 1930
goes to x pixel 0, and the 1000 x pixel goes to 1940. I still try
and graph my point 1910 but since it equates to x pixel value of like
-800, its doesn't show. Same goes for the other side, the 1950 point
equates to pixel 1200, and it too is off the visible area.

What I want to do is effectively attach a horizontal scrollbar to the
panel so the visible area ( 0,0 --> 1000,y) can be dragged ie, -800,0
--> 200,y) I hope that explains it better.
 
J

jleslie48

Without a proper concise-but-complete code example that shows exactly
what you're doing, it's hard to say.

But, assuming when you write "panel" you really mean
"System.Windows.Forms.Panel", then having a scroll bar is as simple as
enabling it in the Designer.

One of the simplest ways is actually to use two controls.  A Panel as a
container, and then any other control as a child of the Panel and which
resizes according to the scale factor.  Then, set the Panel's AutoScroll
property to "true", and it will automatically enable scroll bars when
the child control is larger than the Panel itself, and handle all of the
necessary rendering translations needed.

If you want to stick with your current drawing implementation, you can
just make that child your current Panel object.  Personally, I would
prefer a custom Control sub-class that resizes according to your
scaling, but there's obviously some value in sticking with code that
already works, once you've gotten it to work.  :)

If that doesn't help, then you'll need to provide a specific,
concise-but-complete code example to show exactly what you're doing and
how you want to change it.

Pete

Ok, here's what I have so far.

1) I can graph:

http://jleslie48.com/images/csharp_graph_Image1.jpg

2) I can capture a zoom region:

http://jleslie48.com/images/csharp_graph_Image2.jpg

3) I can rescale the graph and display just the zoomed in area:

http://jleslie48.com/images/csharp_graph_Image3.jpg

The controls for the System.Windows.Forms.Panel do not have scroll
bars (but for some reason they do have autoscroll???):

http://jleslie48.com/images/csharp_panel_Image1.jpg


here's the code I have so far:

1) I take my raw data, (x=freq, y =amp) and convert it to a percent of
the entire range:

private void make_percent_points(decimal local_high_x,
decimal local_low_x,
decimal local_high_y,
decimal local_low_y ) {

decimal curr_magnitude_y ;
decimal curr_magnitude_x ;

decimal range_y, range_x;

range_y = local_high_y - local_low_y;
range_x = local_high_x - local_low_x;

/* lets convert the actual values into percents for
future graphing*/
points_list_pc.Clear();

faPair temp_one_pc;
foreach ( faPair curritem in plotpt_pairs) {
curr_magnitude_y = curritem.amp -
local_low_y;
curr_magnitude_x = curritem.freq -
local_low_x;

temp_one_pc = curritem.makeduplicate();
temp_one_pc.amp = curr_magnitude_y/
range_y;
temp_one_pc.freq = curr_magnitude_x/
range_x;

points_list_pc.Add( temp_one_pc );
} //foreach

2) in the onPaint section of the panel I normalize the x,y points to
the size of the panel and make
points out of them:

//graph of the data
foreach ( faPair curritem in
myform1ptr.points_list_pc) {
temp_one.amp = ((1 - curritem.amp) *
(this.Size.Height-50)) +20 ;
// flipped over, and
borders.
temp_one.freq = curritem.freq *
(this.Size.Width-50) +40;
points_list_plot.Add( new
Point((int)temp_one.freq,(int)temp_one.amp) );
} //foreach
points =points_list_plot.ToArray();
pe.Graphics.DrawLines(a_sharpie, points );

int curr_index;
curr_index = 0;
foreach (Point curr_point in points_list_plot) {
pe.Graphics.FillEllipse(Brushes.Red,
points_list_plot[curr_index].X-3,
points_list_plot[curr_index].Y-3,
6,6);
curr_index++;
}//foreach




3) now for the zoom, the mouse controls give me the x,y coordinates of
the green box, so I reverse the calcuation to get the freq,amp pairs
of the the range:

private void panel1_MouseUp(object sender,MouseEventArgs e) {

double amp_pc, freq_pc;
double amp_mag, freq_mag;
double amp_val, freq_val;

double md_amp_pc, md_freq_pc;
double md_amp_mag, md_freq_mag;
double md_amp_val, md_freq_val;

WindowsFormsApplication01.PlotPanel pp_ptr =
(WindowsFormsApplication01.PlotPanel)sender;


decimal range_y, range_x;

range_y = high_y - low_y;
range_x= high_x - low_x;


md_amp_pc = 1.0 - (md_e.Y-20.0)/(pp_ptr.Height-50.0);
md_amp_mag = md_amp_pc* (double)range_y;
md_amp_val = md_amp_mag + (double)low_y;

md_freq_pc = (md_e.X-40.0)/(pp_ptr.Width-50.0);
md_freq_mag = md_freq_pc* (double)range_x;
md_freq_val = md_freq_mag + (double)low_x;

amp_pc = 1.0 - (e.Y-20.0)/(pp_ptr.Height-50.0);
amp_mag = amp_pc* (double)range_y;
amp_val = amp_mag + (double)low_y;

freq_pc = (e.X-40.0)/(pp_ptr.Width-50.0);
freq_mag = freq_pc* (double)range_x;
freq_val = freq_mag + (double)low_x;

4) and then redo my percentages with the new highs and lows. This time
points that are outside the "zoom" will have a percent that is either
below 0% (negative) or above 100%. These datapoints in the onPaint
simply fall away from the repaint, but still exist:


high_x = Math.Max((decimal)freq_val,
(decimal)md_freq_val);
low_x = Math.Min((decimal)freq_val,
(decimal)md_freq_val);
high_y = Math.Max((decimal)md_amp_val,
(decimal)amp_val);
low_y = Math.Min((decimal)md_amp_val,
(decimal)amp_val);

make_percent_points(high_x, low_x, high_y,
low_y);

}//make_percent_points


***********************************************************
5) so I have all the data I need, I know that my zoom is a certain
percent of the whole range so I can "size" my hscrollbar. I also
know that the leftmost edge of the scrollbars marker represents the
0th pixel, and the rightmost edge the highest pixel, so as the user
drags the scrollbar he declares where is want the new range of values
to be (again by converting the pixels to their relative location)

I don't know how to program up the hscrollbar events to return the x
and y etc, or if I'm doing way too much work and there is something
already there I should be using.

TIA,

- jleslie48
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top