I have a bar graph displaying a number of different series (stacked on each other) and I'm trying to find a way to dynamically change the y-axis interval if the values go above a set value.
If the bars only go up to a maximum of 50, I'd like the interval to be 25 so the bars still 'look' rather small. But if a large spike comes through, the interval needs to be set to 0 so the large spike is more noticeable.
Oh, and this is in C# .NET 3.5
I hope that makes sense :)
Thanks in advance
This is pretty much feasible by tweaking both the size of the axis and the relative intervals dynamically by updating the right properties. Default control behavior is rescaling the axis to adapt to the dataset so this should be no problem (works well for me)
Take a look at the Axis Class MSDN Reference, especially the Interval and IntervalAutoMode Properties. (the MSDN in pretty exhaustive on chart control if you dig enough you'll find everything you might need).
besides I HEAVILY advice you to download the very complete sample application
and play around with it locally. It is pretty exhaustive and you'll have the complete source at hand.
Set IntervalAutoMode="Variable Count" and dint mention any axis interval in the Axis Y element of the chart Area of that chart,it will adjust according to the maximum value.
Related
I want to create a plot that dynamically displays active elements as rectangles. I have achieved a first version that is actually ok using OxyPlot.Annotations.RectangleAnnotation which I add to myPlotModel.Annotations, you can see it in the image hereafter:
Example of wanted display
The thing is that after a while, the amount of drawn rectangles make the update not smooth as I update the shown timewindow (which is set to 15 seconds). I have already set a maximum of drawn elements that suffice to cover the displayed window (i.e. the rectangles get removed as they are too far in the past), but the rendering is still jerky. I draw the rectangles by allocating them to an equal fraction of the Y-axis, that is the third one from the top gets:
rowNumber= 3.0
minimumY = maximalY - maximalY / totalElements * rowNumber
maximumY = maximalY - maximalY / totalElements * (rowNumber + 1.0)
And the Y-axis is hidden.
My question:
Is there a smarter way of creating such a display that would be less computationally heavy, and therefore allow a smoother update? I do not have to stick to OxyPlot, it is simply the easiest way that I found to obtain what I wanted.
Thanks for your answers!
Technically, the answer to your question is "Yes".
There are a number of ways to do this.
You could have a vertical itemscontrol that had an itemscontrol in it's template. That could have a canvas as it's itemspresenter and you could bind canvas.top and canvas.left to properties in it's content. Template each into a rectangle and bind height and width.
And of course do something about the scale on the bottom and the column of activity labels or whatever you want to call them there.
Unless you're using an absolutely ancient machine, that'd just fly.
It's quite a lot of work but it would probably be quicker to write that than to search through a load of alternative packages and decide which was optimal.
I am using oxyplot to create line series charts in my c# application.
The data is loaded in real time as a test progresses.
I am currently using LinearAxis.MinimumRange to prevent auto scaling to zoom right into the data to prevent the screen being filled with noise at the start of the test before values start changing.
However, by design this property limits how far the user is able to zoom in, is there a simple way beyond hooking into the scale changed events to achieve the functionality I want which is, to put it more simply, a default plot size that when exceeded autoscaling kicks in.
My solution to this ended up being wrap adding points into my own function (I am directly manipulating LineSeries.Points).
Now I just set min and max when setting up my axes and then when adding a point, check if it is outside these limits, if they are set the limits to NaN so autoscale resumes.
I am using C#, and would like to plot a line chart to visualize my data, the data could be stored as a double array, the number could be very large, over 100000 maybe, and I also would like to update the data source all the time, but when I use the Microsoft Win Chart, the refresh rate will be very slow if the number is too large (20000 would give a very bad user experience), I use the FastLine/FastPoint chartType, but it did not give me too much improvement, and I also tried to directly bind the data to the Points.DataBindY method, still, does not feel very well.
Is there anyone has experience on how to deal with this?
Many thanks.
You're going to find that trying to chart that number of points (100k) is going to overwhelm even the most powerful of charting controls. And I would question why it's even necessary to do that. How can you possibly differentiate 100k points on a chart? It seems unnecessary. Most charting controls (I'm most familiar with WPF controls) allow you to 'sample' the data (via a sampling threshold). This permits you to still retain the general shape of the data, but do so with far fewer data points, and much better performance.
Also, be very careful when binding data. With many charting controls, when you bind data, each data point bound to the chart causes a refresh of the chart. You can imagine what 100k refreshes would do :(. If you can, find a way to refresh the chart after all the data has been bound to the chart.
A solution might be to reduce the scale to 1:10000, greatly reducing drawn points while keeping the same draw.
You could do this by working on the data array before giving it to the chart.
try this:
chart1.Series[0].ChartType = SeriesChartType.FastLine;
or
chart1.Series[0].ChartType = SeriesChartType.FastPoint;
In cases when you need to draw more than 100,000 data points you may also consider using FastLine and FastPoint chart types. They do not support all the features of the regular Line and Point chart but will SIGNIFICANTLY improve chart performance.
https://blogs.msdn.microsoft.com/alexgor/2008/12/02/microsoft-chart-control-how-to-improve-chart-performance/
for other type of charts . idk either.
Tried to leave as a comment but can't due to rep, to update the chart manually every 'x' many points:
https://stackoverflow.com/a/10621610/1360625
Has a massive effect on speed and efficiency.
Is it possible to force the display of grid lines on the chart with the dates for the extreme data points?
I've tried almost every configuration of following Chart DateTimeAxis properties: IntervalType, Interval, Minimum and Maximum but I wasn't satisfied with the result.
Setting properties Minimum and Maximum didn't solve the problem.
For instance (IntervalType="Days" , Interval="4" , Minimum="1/1/2010" , Maximum="1/31/2010"):
If I'm lucky I will generate some random data where only one extreme point will have the date with grid line.
Does somebody have an idea how to solve the problem mentioned above?
Edited to add
I added a bounty to this question since I really need a fast solution for this issue.
I am binding a series of specific pairs to my chart and I'd like to display excactly those given DateTime values on the x-axis.
Since these are usually dates like 6/30/11, 6/30/12 and so on, I can't use the Interval/IntervalType properties because adding 1 year or 365 days to 6/30/11 doesn't necessarily result in 6/30/12.
So what I need to do is either disable the "automatic axis label generation" of the DateTime axis or use another axis type.
LinearAxis doesn't work because it expects double values and CategoryAxis is not an option because it displays the axis labels between two tickmarks instead of underneath them.
I am very grateful for any help!
To be perfectly clear, here is what axis labels I need (taken from another chart component):
This is what I get so far with the Silverlight 4 Toolkit:
€: I also opened a thread in the official Silverlight Toolkit Support Forums.
The vertical lines are set where you specify an interval.
There is no vertical line for the data for 1/31/2010 as it does not fall on an interval.
I've used ZedGraph to plot data from several sources with a single click. I need the Y-axes to always have the same max and min-values for each plot. I need this to be able to see changes between datasets as I flip through them. In my case, it would not make sense to plot data from several sources in one graph.
I've tried to set axis properties like this:
myPane.Y2Axis.Scale.Max = 40;
myPane.Y2Axis.Scale.MaxAuto = false;
myPane.Y2Axis.Scale.Min = -40;
myPane.Y2Axis.Scale.MinAuto = false;
I still see the axes beeing auto scaled. Please give me a hint if this is possible or not. I probably only miss a small thing...
(by the way: I hope someone picks this project up, it's great!)
Well, solved like this:
zGC.AxisChange();
zGC.RestoreScale(myPane);
zGC.ZoomOut(myPane);
Added a ZoomOut(), since I realized that RestoreScale() actually always autozooms...
-rb
Is your intention to synchronize the scales of all panes that you use?
If so, have you seen this tutorial?
The second thing is that the Y2Axis is not visible by default. ZG uses by default first Y axis (YAxis). Have you enabled Y2Axis manually?