Drawing a chart in WPF C # design questions

I had a project a month ago where I was drawing a stock chart in an application using Windows Forms. I did this by creating a bitmap that would stretch to fit the window. This will allow my chart to resize the window.

Now I am expanding the project using WPF. I tried to work on my design for the project, but it seems I don’t know how best to make the same schedule. I looked at canvases, grids, and several other controls. I thought I was on the right track with the canvas, but when I resized the window, my drawing will remain in the same place. I guess the point of my message today is to get some ideas that will help me brainstorm the project for my project.

All tips and questions are welcome.

Thank you Joseph

+4
source share
4 answers

(By implementing these addresses, at best, a subset of this rather old question, since this is only one type of diagram ...)

Just fwiw, creating a histogram in the Grid , as Ed suggests , is pretty simple. Here is a quick and dirty version:

Add a Grid to your Window XAML. Just for testing, here, which completely fills Window .

 <Grid> <Grid Name="myGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="auto" Height="auto" Margin="10,10,10,10" /> </Grid> 

Now insert these two utility functions somewhere in your project. They provide simple, single-color columns and uneven but centered label text for the x axis.

I think the only nasty kludge is maxHeight in calling _placeSingleColorColumn .

Worth mentioning: I have no shortcuts for the y axis in this quick and dirty version.

 private void _placeSingleColorColumn(Grid grid, Color color, int height, int colNum, int maxHeight) { Brush brush = new SolidColorBrush(color); Rectangle rect = new Rectangle(); rect.Fill = brush; Grid.SetColumn(rect, colNum); Grid.SetRow(rect, maxHeight - height); Grid.SetRowSpan(rect, height); grid.Children.Add(rect); } private void _createLabels(Grid grid, string[] labels) { RowDefinition rowDefnLabels = new RowDefinition(); grid.RowDefinitions.Add(rowDefnLabels); for (int i = 0; i < labels.Length; i++) { TextBlock block = new TextBlock(); block.Text = labels[i]; block.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; Grid.SetColumn(block, i); Grid.SetRow(block, grid.RowDefinitions.Count); grid.Children.Add(block); } } 

It really is. Here's some insanely fast and dirty code example for creating a 10 by 10 grid with some data examples.

 public void createGrid10x10() { Random random = new Random(); for (int i=0; i<10; i++) { ColumnDefinition colDef = new ColumnDefinition(); myGrid.ColumnDefinitions.Add(colDef); RowDefinition rowDef = new RowDefinition(); myGrid.RowDefinitions.Add(rowDef); Color color = i % 2 == 0 ? Colors.Red : Colors.Blue; _placeSingleColorColumn(this.myGrid, color, random.Next(1,11), i, 10); } string[] aLabels = "Dogs,Cats,Birds,Snakes,Rabbits,Hamsters,Horses,Rats,Bats,Unicorns".Split(','); _createLabels(this.myGrid, aLabels); } 

Add one line to your MainWindow constructor, and you're done, afaict.

 public MainWindow() { InitializeComponent(); this.createGrid10x10(); } 

Now you have a histogram that will resize and remain proportional as the window resizes, etc.

bar graphbar graph resized wider

Adding more labels (bar values ​​above, Y axis labels, etc.) should be pretty simple, if you understand above. Just enter another column and / or row, create TextBlock s and put them in the right places.

+1
source

Try using the DockPanel and set LastChildFill to true. Then make your control the last child of the DockPanel .

0
source

I assume that you want to draw your own chart, and not use WPF graphics.

Canvas is generally not recommended for use in WPF, as it captures objects at a specific location and size, just like you saw (although I suppose you could use Canvas with ScaleTransform). The grid will take the size of its container, so setting the Grid to the window will make the grid change using the window (unless you specify a fixed width and height for the grid). The StackPanel will stack things and try to take the minimum size of its content, so it’s probably not what you want to use here.

Creating a chart diagram inside a panel, such as a grid, is not entirely simple. If you are making a histogram, you can create a column in the grid for each bar, assign a percentage width such as a star; and the columns will grow as your grid expands with the window. You can use a similar trick by creating each grid panel, setting two columns in the grid and setting the third grid level inside the lowest column, and then using percentages for the column heights (e.g. 90star and 10star for 90%, 10% height). Then the bars will grow taller as the window grows. You can reserve a Grid row under the columns for labels and center them under the bars.

Line charts are more complicated. You might want to create GeometryDrawing line segments, and then use the ScaleTransform snapping to fit the window to reduce and enlarge it.

There are a lot of possibilities in WPF, but first you need to lean over and learn. A book such as Adam Nathan's “Windows Presentation Foundation Unleashed” will quickly give you a lot of knowledge about WPF layout and how to proceed.

Edit: You can also use a blank panel and use DrawingContext to draw lines, rectangles, text, ellipses, etc. at the points that you calculated from the current window size.

0
source

Funny: I'm just doing the same thing!

I have already developed a chart control, many functions. Now I need to update and expand it with some other function. Nevertheless, my transaction manages even 100 thousand points on one chart, but it maintains good performance on a regular PC. When you resize the window, the chart will scale, but the text will not be placed on it. Also note that I need to render in real time the data received for at least 0.5 seconds.

Everything that was allowed using the old-style bitmap creation, then placed it as a normal image in any wpf control. There are several limitations because there are no “live” objects like in wpf that you have, but the rendering performance is really huge compared to wpf primitives.

So, if you do not have charts with a maximum of 100 points to manage, I highly recommend a hybrid approach. In any case, this is a very difficult task!

Greetings

0
source

All Articles