|

Introduction
This project was developed for the impatient developer (that's me sometimes, and probably you!) who's sitting late at night downloading charting libraries only to figure out that it's too complex to set up, isn't dynamic, and doesn't provide the necessary customizations.
Well, GraphComponents hopes to provide an answer to these common problems. In short, GraphComponents is a .NET user control that provides you the following features:
- Easy to use in the Visual Studio designer IDE
- Easy to configure during runtime
- High speed updating
- Rich features like custom color settings, custom background settings, smart numbering, reference values and lines, grids, transparent bars, etc.
GraphComponents currently supports Bar Graphs, Stacked Bar Graphs (Multi-bar Graphs), and a N-Channel Plotter Oscilloscope (Plotter CRO). Future versions should see other kinds of graphs too.
Usage
GraphComponents is accessible as a control from the control toolbox in Visual Studio .NET. To access GraphComponents, first launch Visual Studio .NET, and create a new Windows Application project. Open the Form Design so that it appears in the current window. View the toolbox using the View/Toolbox menu command. Right-click inside the "General" or "Components" sub-pane of the tool box, and select the "Add/Remove Items..." option. In the "Customize Toolbox" dialog that appears, select ".NET Framework Components". Click "Browse...", and navigate to the GraphComponents.dll file. Once this file is added, you should see a BarGraph, StackedBarGraph, and a Plotter option in the toolbox.
Using the Stacked Bar Graph
Using the Plotter Oscilloscope
The plotter oscilloscope is useful when you want to capture various input signals and observe them. The Performance tab of the Windows Task Manager has two simple plotters for monitoring CPU usage history and page file usage history. On Windows 2000 or XP, you can view the Windows Task Manager by pressing Ctrl + Shift and then pressing Esc.
Another thing about plotters and CROs in general is that they receive inputs through their 'channels'. If you observe the Plotter in the GraphUsageDemo application, you can see that the Advanced Body Measurement System measures four parameters (voltage, current, body pulses, and metabolism) through its four channels. While a simple low-end CRO has two channels, a hi-fi CRO (called as a spectrum analyser) can have many input channels. OK, enough with electronics theory! Let's get back to .NET.
- To use a plotter, create a new Windows Application project as described above.
- Drag and drop the
Plotter onto the form.
- In the form's constructor, add the following line after the
InitializeComponent(); line:
plotter1.Start ();
plotter1.PlotRate = 200;
- Go back to the Form Design view and drag and drop a
Button (Button1) onto the form.
- Double click
Button1. This will place a Button1_Click() function in your C# file.
- Add the following code in the
Button1_Click() function:
Random r = new Random ( (int) DateTime.Now.Ticks);
plotter1.Channels[0].CurrentValue = r.Next (0, 100);
plotter1.Channels[1].CurrentValue = r.Next (0, 5);
plotter1.UpdateDisplay ();
- Build and run the application. Keep clicking
Button1, and the plotter starts plotting two separate lines for its two channels. You now have a very basic framework ready for using the Plotter. On the top left hand corner of the plotter, you can see the < and > icons. These are used for navigating to the next and previous channels. On surfing channels, the currently active channel appears brighter. The + and - icons below are used for offset adjustment. You can experiment by clicking these buttons and repeatedly clicking Button1.
- By default, channels 1 and 2 are enabled, while channels 3 and 4 are disabled. The X axis time range is set to 9 seconds. Once the plotter has reached the right side, it automatically scrolls to the left. Also, by default, the upper and lower limits for channel 1 are set to 100 and 0. The upper and lower limits for channel 2 are set to 5 and 0.
- Examine the sources of the PlotterWalkThrough project and the
Plotter part of GraphUsageDemo.
- Now, getting back to the Form Design view, adjust some of the properties of the plotter in the Properties pane. For example, adjust the
PlotRate, GraphMarginLeft, and GraphMarginTop.
- To perform high speed updating for measuring various things like voltages, currents, etc., you just have to set up a timer. Also note that the
PlotRate must tally with the timer's Interval to get an accurate measurement. Examine the source of the GraphUsageDemo application for configuring high speed displays.
While using this in your code, it is useful to know the following things:
Start() starts the plotter.
Stop() stops the plotter. If the plotter has scrolled, then a scroll bar appears allowing you to see the earlier plots.
Start() and Stop() also act like Resume and Pause. So you can pause, examine the graphs, and resume by using the same two functions.
Reset() erases the plotter and makes it fresh for using again.
- The
CompressedMode property allows you to view the entire plot in the graph area without any scrolling.
NextChannel() and PreviousChannel() allow you to surf channels.
- A channel can be enabled or disabled. You cannot see the output of a disabled channel.
- If you are not satisfied with four channels, you can add more channels by easily changing the source code. The upper limit is based on how satisfied you are with the performance. So, you could possibly set up 8 channels and observe the data bus of an 8-bit microprocessor.
Acknowledgements
I would like to thank my wife Shubha, for providing me with some cool ideas with respect to usability, and for lots of other small things. Also, thanks to some of my friends in my current and previous companies, with whom I discuss a lot about software.
Conclusion
Hope you find this library useful and that you enjoy using it. Please send your criticisms, bugs, ideas for new features, and suggestions to anupshubha@yahoo.com. I would be especially happy with any ideas adhering to the "Keep It Simple" principle.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 44 (Total in Forum: 44) (Refresh) | FirstPrevNext |
|
 |
|
|
When looking at your demo project, I noticed it goes into infinite loop when you set the height of the graph container to 0.
Regards Rémi
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I was just wondering if setting the maximum value on the Y axis for the plotter was possible. I am using it like a line graph. If there is an easier way please let me know .
Very Cool dll btw!
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Hi, First of all this library is great,one of the best i found on the internet.Can I access the points that cursor is showing in stop mode,by that I mean to get values that cursor shows on graph?
Best regards and keep up the good work......
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi
Thanks for lovely little graph library, it's exactly what I've been looking for. I am capturing data from a model aircraft in real-time, and display the data using my own graphic controls, and this plotter adds a nice way to display the history of the values. Although I do save the data to a file, but it's a pain to import it to Excel everytime.
I noticed that if I disable some of the channels, it still cycles through the channels using the arrow controls. I would like it to skip the disabled channels. It would also be nice to assign a certain number of channels to the plotter, that way if I only have two traces, then I don't need to disable the others.
Something else I would like, is to have a second scale on the right, if I display two different ranges of values at one time. It would also be nice to have some kind of legend, or label for each channel trace.
|
| Sign In·View Thread·PermaLink | 3.00/5 (2 votes) |
|
|
|
 |
|
|
I want to make my graphs excel compatible. I am making my excel sheets dynamic in nature and want to import values to my GUI application. Can someone guide me how can I do that using this graphs?
Mandip Shah Mandip.shah@asu.edu
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
This system looks really cool... What I was actually looking for is some sort of FREE plotting-system that can be kicked off from my own program, but then runs stand alone. That is, I want to avoid building my own GUI in which I integrate the chart controls. Ideally, I would like to just click a button that calls some sort of PlotLib::OpenPlotWindow command and then simply feed the data to the window.
I found a suitable open-source real-time plotter like that for Java (LiveGraph: http://www.live-graph.org), but so far nothing for .NET.
Any ideas?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
The first thing I want to mention is that it is a very nice control!
I use your plotter control to monitor some variables of an embedded system. Due to the fact that Microsoft Windows is not a real-time O.S. and the communication bus between the Windows System and the embedded system is not deterministic, I calculate and update the plotrate every send-receive cycles. When I stop the plotter I noticed that the coordinates displayed when hovering over the graph are not calculated correctly. I checked your code and I think it has to do with the fact that your code (method: DrawXYText in Plotter.cs) assumes a fixed plotrate 
The peace of code is a little bit hard to get. When I have more time I will try to fix it. Have you planned any updates?
Thanks!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Well I already found some time to take a look at the problem and I have a solution:
Update the following code in the function: DrawXYText
........... ...........
int modulo = actualX % plotRate; actualX -= modulo; int pointsOffset = actualX / plotRate;
float y = float.NaN; string coordinate = "";
if (activeCh.Points.ContainsKey (pointsOffset)) { PointF selectedPoint = (PointF) activeCh.Points[pointsOffset]; y = selectedPoint.Y; }
int last_diff = -1; int last_x = 0; float last_y = 0; int current_diff = 0; // Find the closest match for the x value! foreach (PointF value in activeCh.Points.Values) { current_diff = Math.Abs(actualX - (int)value.X); if ((last_diff == -1) || (current_diff == Math.Min(current_diff, last_diff))) { last_diff = current_diff; last_x = (int)value.X; last_y = value.Y; } else { actualX = last_x; y = last_y; break; } } ........... ...........
Maybe it can be more efficient, but it works. The only little thing about this code is that if you point the cursor to a position outside the plotted range, it will show you the last point of the plotted range and not the y = '-' value.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thank you for such a nice control.
I have a question about the bar chart. Is it possible to have "stacked bars"? For this I mean a single bar (imagine a vertical bar) that has had different values appended to it, and perhaps each appended value shows as a different color.
I've see this called "stacked bars" on other graph components.
Thanks again.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
A very nice job .
I ran into a problem with the auto scrolling when plotting several simultaniously updatng Channels. - Channel[0] would plot to the right of the graph, triggering the autoScroll operation. The rest of the channels would plot one plotRate interval to the left.
I fixed this by replacing the comparison from the plotter's TotalElapsedTime to the Channel's TotalElapsedTime (inside the Plotter.Draw method) that is: if (! scrollAdjusted) {
// if (TotalTimeElapsed > rightDisplayLimit) if (channel.TotalTimeElapsed > rightDisplayLimit) {
I must admit, I didn't follow the logic for changing plotRate's etc., so this might not be the correct fix for everyone.
The second problem is somewhat related to the first. You calculate the horizontal tick interval as an integer instead of a float, leading to an accumulating error in drawing the X axis grid lines. This also happens with the Y axis grid lines. The fix is to change GraphDecorators\Gridline.cs as so:
if ((parentGraph.Gridlines & GridStyles.Horizontal) == GridStyles.Horizontal) { graphics.SetClip (parentGraph.GraphArea);
// int gridSize = parentGraph.GraphArea.Height / parentGraph.GraduationsY; float gridSize = (float)parentGraph.GraphArea.Height / (float)parentGraph.GraduationsY;
// for (int i = 0; i < parentGraph.GraphArea.Height; i += gridSize) for (float i = 0; i <= parentGraph.GraphArea.Height; i += gridSize) { graphics.DrawLine (graphAreaPen, parentGraph.GraphArea.Left, parentGraph.GraphArea.Top + i, parentGraph.GraphArea.Right, parentGraph.GraphArea.Top + i); } }
if ((parentGraph.Gridlines & GridStyles.Vertical) == GridStyles.Vertical) {
// int gridSize = parentGraph.GraphArea.Width / parentGraph.GraduationsX; float gridSize = (float)parentGraph.GraphArea.Width / (float)parentGraph.GraduationsX;
// for (int i = 0; i < parentGraph.GraphArea.Width; i += gridSize) for (float i = 0; i <= parentGraph.GraphArea.Width; i += gridSize) { graphics.DrawLine (graphAreaPen, parentGraph.GraphArea.Left + i, parentGraph.GraphArea.Bottom, parentGraph.GraphArea.Left + i, parentGraph.GraphArea.Top); } } The only downside I see is that the right hand edge grid line is now outside the clipping area, so it looks messy. To fix this, we need to do some more work...
I blame Bush...
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
hi anup i´m using your plotter and it works really fine. but one question. I am starting and stopping the plotter after every measurement that i do. how can i avoid the plotter to scroll to the left after evrey cycle? i want to see the last two measurement without scrolling manual.
thanks for your offerts
hubert81
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Hi Anup,
I'm using your GraphComponents to plot the output from my micro-controller which outputs data in hex format.. using hyperterminal i get 0000 to 0fff as my output from the microcontroller.
I cast the output from the COM port as float and send it to the channel for display but it doesnt seem to work... I have implemented code to append output from the COM port to a logger.txt and it correctly shows its receiving output so i do not think the problem is with the serialport code.. can you pls enlighten me? thanks in advance.
gerardtay[at]yahoo[dot]com
My code is as of below:
private void plotterTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { byte[] buffer = null; int offset = 0; int count = 2; //plotter1.Channels[0].CurrentValue = (float)(5 * r.NextDouble()); plotter1.Channels[0].CurrentValue = (float) (serialPort1.Read(buffer,offset,count)); if ( plotter1.Channels[0].Enabled) { plotter1.UpdateDisplay(); } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
hi, the dll is called GraphComponents.dll. It is contained as a project (GraphComponents) in the solution GraphComponents.sln. The other projects in this solution are all applications.
Regards Anup
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, I'm using Visual Studio 2005 and i keep getting an error msg when i try to convert the solution.. any idea why? I wish to import tis library into a VB project.. is it possible?
Conversion Report - GraphComponents Time of Conversion: Monday, January 22, 2007 22:53 PM
Solution: GraphComponents Filename Status Errors Warnings GraphComponents.sln Converted 0 0 Conversion Issues - GraphComponents.sln: Solution converted successfully 1 file Converted: 1 Not converted 0 0 0
Project: BarGraphWalkThrough Filename Status Errors Warnings BarGraphWalkThrough\BarGraphWalkThrough.csproj Not Converted 2 0 Conversion Issues - BarGraphWalkThrough\BarGraphWalkThrough.csproj: Project file is not writable: C:\Documents and Settings\u0307692\Desktop\GraphComponents_src\GraphComponents_src\BarGraphWalkThrough\BarGraphWalkThrough.csproj Unable to save converted project file. 1 file Converted: 0 Not converted 1 2 0
Project: GraphComponents Filename Status Errors Warnings GraphComponents.csproj Not Converted 2 0 Conversion Issues - GraphComponents.csproj: Project file is not writable: C:\Documents and Settings\u0307692\Desktop\GraphComponents_src\GraphComponents_src\GraphComponents.csproj Unable to save converted project file. 1 file Converted: 0 Not converted 1 2 0
Project: GraphUsageDemo Filename Status Errors Warnings GraphUsageDemo\GraphUsageDemo.csproj Not Converted 2 0 Conversion Issues - GraphUsageDemo\GraphUsageDemo.csproj: Project file is not writable: C:\Documents and Settings\u0307692\Desktop\GraphComponents_src\GraphComponents_src\GraphUsageDemo\GraphUsageDemo.csproj Unable to save converted project file. 1 file Converted: 0 Not converted 1 2 0
Project: PlotterWalkThrough Filename Status Errors Warnings PlotterWalkThrough\PlotterWalkThrough.csproj Not Converted 2 0 Conversion Issues - PlotterWalkThrough\PlotterWalkThrough.csproj: Project file is not writable: C:\Documents and Settings\u0307692\Desktop\GraphComponents_src\GraphComponents_src\PlotterWalkThrough\PlotterWalkThrough.csproj Unable to save converted project file. 1 file Converted: 0 Not converted 1 2 0
Project: StackedBarGraphWalkThrough Filename Status Errors Warnings StackedBarGraphWalkThrough\StackedBarGraphWalkThrough.csproj Not Converted 2 0 Conversion Issues - StackedBarGraphWalkThrough\StackedBarGraphWalkThrough.csproj: Project file is not writable: C:\Documents and Settings\u0307692\Desktop\GraphComponents_src\GraphComponents_src\StackedBarGraphWalkThrough\StackedBarGraphWalkThrough.csproj Unable to save converted project file. 1 file Converted: 0 Not converted 1 2 0
Conversion Settings Solution File: C:\Documents and Settings\u0307692\Desktop\GraphComponents_src\GraphComponents_src\GraphComponents.sln
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I had the same issue. First, all the files were Read Only for some reason...so I fixed that and ran the conversion again. Things were better but I had many errors when I tried to compile.
As was stated before; "You need to rebuild the whole project and remove the old reference and add the new rebuilt one from this directory "GraphComponents_src\GraphComponents_src\bin\Debug" "
After you perform the conversion, ignore any errors, look in the Solution Explorer at GraphUsageDemo and then at its References. The GraphComponents reference is broken. Remove that reference and replace it with a current reference to the dll in the bin\Debug folder.
Recompile....it's all good!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
is the code for the graphic components DLL in the demo folder is available?
I am interested in the real time ploter to apply to application.
I want to include the ploter and isert other symbols and format to the ploter.
the real time ability of this implementation is great in GDI+!!
Did you consider WPF/Vista graphics engine for a real time graphic components?
elwolv
elwolv
|
| Sign In·View Thread·PermaLink | 2.00/5 (3 votes) |
|
|
|
 |
|
|
Hi!!! I found great your plotter control! I'm traying to use it to display a signal acquisition. But if I have signals that changes in less than 40 ms, all application doesn't respond to inputs. I use the plotter in a new thread and in this thread I use a timer to generate ticks.
Do you have any suggestion?
Thank you in advance and sorry for my bad english 
Alessio
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, Thanks for the compliments  For the time being this could help (maybe) What you can do to draw a line graph is for every timer elapsed, set the CurrentValue and not call the UpdateDisplay () function. After setting all the values, you can call update display once.
eg.
int update; // a member variable private void plotterTimer_Elapsed (.......) { // keep assigning values each time the timer elapses // The plotter stores all this internally plotter.Channels[0].CurrentValue = x;
update ++;
// refresh the screen once every 50 times. if (update == 50) { plotter.UpdateDisplay (); update = 0; } }
With this you can get low times plotted (like 1 ms or less, but the actual refresh happens every 50 ms or so). This should be okay because if the control were to draw and scroll for every 1 ms, then we could not see anything but a blur on the screen.
Hope this helps you. If not, i am currently working on a fast oscilloscope. I will try to finish that once i get some free time.
Regards Anup
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks a lot for your help.
I was thinking about implementing the plotter using asynchronous threading pattern, for example with background process. By this way maybe it's possible to have faster refresh without blocking main application form.
What do you think about this?
Thank again!

Alessio
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Hi,
This is a very neat control! Thanks a lot.
One question, is it possible to create a line graph?
Kindest regards Raymond Verbruggen Netherlands
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, Thanks for the compliments  For the time being this could help (maybe) What you can do to draw a line graph is for every timer elapsed, set the CurrentValue and not call the UpdateDisplay () function. After setting all the values, you can call update display once.
eg.
int update; // a member variable private void plotterTimer_Elapsed (.......) { // keep assigning values each time the timer elapses // The plotter stores all this internally plotter.Channels[0].CurrentValue = x;
update ++;
// refresh the screen once every 50 times. if (update == 50) { plotter.UpdateDisplay (); update = 0; } }
Hope this helps you. If not, i am currently working on a fast oscilloscope. I will try to finish that once i get some free time.
Regards Anup
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|