Dynamic-Data-Display multiple axes scaling - c#

I have a MVVM wpf application with a chartplotter. I have 2 vertical axis and 2 graphs (for example current and voltage over time on one chart).
<d3:ChartPlotter>
<d3:ChartPlotter.Children>
<d3:VerticalIntegerAxis/>
<d3:LineGraph DataSource="{Binding GraphOneDataSource}" Stroke="Blue"/>
<d3:LineGraph DataSource="{Binding GraphTwoDataSource}" Stroke="Red"/>
</d3:ChartPlotter.Children>
</d3:ChartPlotter>
The 2 graphs are scaled differently. I have made one graph scalable with the other by adjusting his mapping like so
GraphTwoDataSource.SetXYMapping(p=>new Point(p.X+1,((p.Y)*(GraphOneMax-GraphOneMin)/(GraphTwoMax-GraphTwoMin))));
The graphs scale with each other. The first graph values are from 1000 to 5000 and the second one's values are 10-50.
I need to adjust the second vertical axis of the chartplotter accordingly. How can you change the behaviour of the axis tick generation so that it scales with the first axis the same way as the graphs scale with each other?

as described here and here you can use InjectedPlotter . here i found an example.

Solved this problem with the DependentPlotter control introduced in the "Future of D3" library

Related

Creating a stacked bar graph with a DateTimeAxis Oxyplot

Using OxyPlot.Wpf 2.1, I am creating a bar graph where the horizontal axis (x) is a DateTimeAxis and the vertical axis (y) is a LinearAxis. I need 4 series that stack on each other so when one series is disabled there are no vertical gaps. A BarSeries seemed to be the best option at first since it contains the IsStacked property so hiding a series properly displays the bar graph with no vertical gaps. However, it requires a CategoryAxis along the x axis which does not seem to work well with the DateTimeAxis.
I have used a RectangleSeries and a RectangleBarSeries but they do not support stacking which means I have to recalculate all items to avoid vertical gaps when a series is hidden.
I have also used a LinearBarSeries but the larger series overlaps and hides the smaller series and does not support stacking either.
Is there some bar series in OxyPlot that supports a DateTimeAxis and stacking? I am able to use a CategoryAxis and display the time as the Category label but zooming out does not support readjusting tick size and labels which is what is ideal and functional with a DateTimeAxis. Also I am dealing with continuous data where the user can look at past or future times which does not seem possible with a CategoryAxis since the bounds are determined by how many categories you have.
This github issue claims that LinearBarSeries does support stacking but I do not see how it is possible from the code.
https://github.com/oxyplot/oxyplot/issues/1172

Dynamic-Data-Display WPF Changing the ChartPlotter's default behaviour to moving instead of scaling

I have some data that comes via messages to my chart. It's a electric current over time (seconds) chart. How can I change the behaviour of the FitToView mode (or write a different one) so that the plotter doesn't zoom out and scale to fit the whole line graph, but move left instead, showing for example only the 100 last seconds?
I thought of calculating minimums and maximums every message and changing the plotters restraints explicitly but it doesn't seem very optimal. Also due to the fact that I would have to set the restraints in code-behind but all the data is in the ViewModel (using MVVM with caliburn).
Edit: I've found the functionality for this (adding WidthFollowConstraint to the FitToView constraints) but the linegraph gets moved more than the axis and after that it compensates back to where it should be, making the whole graph glitch out on every iteration. How can this be fixed?
Apperently I forgot to answer this.
I made the graph move instead of scale by adding a MinimalSizeConstraint and a FollowWidthConstraint to the ConstraintCollection in the constructor of the D3 Viewport2D class. The names are pretty selfexplanitory. Basically this changes the FitToView funtion of the graph to the desired behaviour

SciChart Realtime zoom with minimum axis range

I have a FIFO Real Time chart (pretty much taken from their published Example) of a SciChart graph. As it renders, it starts out completely zoomed in very close and as the line is drawn, it zooms out to accommodate the full size of the line.
<s:SciChartSurface.XAxis>
<s:NumericAxis x:Name="axisX" MinHeight="50" AutoRange="Always" AxisTitle="{Binding Path=XAxisTitle}" DrawMinorGridLines="False" DrawMinorTicks="False" TextFormatting="0.##">
<s:NumericAxis.GrowBy>
<s:DoubleRange Max="0.1" Min="0.1" />
</s:NumericAxis.GrowBy>
</s:NumericAxis>
</s:SciChartSurface.XAxis>
However, what I would like is for it to begin zoomed out by a certain amount already - e.g. the X axis would already be displaying from (for example) 0 - 10 and as the line is drawn it proceeds across the screen, only zooming if the line happens to get bigger than the space provided.
I've tried setting the VisibleRangeLimit, but while this does allow me to define the range of the chart area, the zoom doesn't kick in when the curve gets too big (so it literally goes "off the chart")
How can this be accomplished?
The reason for this is the Fifo Example in sciChart WPF uses XAxis AutoRange set to Always to scale the axis to fit the data. When the example starts, even if the Fifo buffer has a capacity of 10,000 points, it has no data in it, hence the axis is scaled small to accommodate the data.
There are two ways around this:
Is to pre-fill your FIFO DataSeries with X=xValue, Y=double.NaN. Given enough values the chart will think it has to draw all these points so the XAxis will scale accordingly
Is to take control of XAxis.VisibleRange yourself (do not use AutoRange). In this case, you need to set XAxis.VisibleRange to a window size to accommodate N points, and as you update data, update the window.
The FAQ 'How to create a StripChart in SciChart' demonstrates technique (2), how to update the visible-range of the XAxis to achieve scrolling behaviour.
Disclosure, I am the tech lead of the SciChart WPF Team

Center axis on barchart using visifire

I am currently working with visifire on a c# charting project.
I want to create a bar chart to show percental increase as green bars and decreases as red bars. The Axis / 0 point line should always remain at the same position.
The problem is, that the axis currently moves all around the screen depending on the values that are shown. (see the image below)
I already tried to center it with axismaximum and axisminimum set to fix values, but that doesn't work.
The way i want it to be is like this.
or this
Are there any remaining visifire cracks out there, that can understand the problem and help?
One workaround for this is finding the maximum value (absolute value, using Math.Abs) from the series, then adding its counter value to the beginning of series.
For example, if the maximum absolute value is -80%, then add a +80%. In this way, the axis can be centred.
You can use a special colour (Transparent?) for the first bar, or use other control to cover it so user will only see the real data.
Using data bindings, this should do the trick.
MinValue = -MaxValue
<vc:Chart.AxesY >
<vc:Axis AxisMaximum="{Binding MinValue}" AxisMinimum="{Binding MaxValue}" Enabled="False" AxisType="Primary" >
</vc:Axis>
</vc:Chart.AxesY>
Otherwise this is the same without databinding
<vc:Chart.AxesY >
<vc:Axis AxisMaximum="70" AxisMinimum="-70" Enabled="False" AxisType="Primary" >
</vc:Axis>
</vc:Chart.AxesY>

How to draw something in DrawingVisual with millimeter unit instead of pixels?

I'm trying to draw something in a System.Windows.Media.DrawingVisual but I need to draw thins in millimeter unit. How can I do that?
In WPF, you can't even draw something in pixel units without at least some extra effort. WPF uses "device independent units" where each unit is 1/96th of an inch. Even that is only a theoretical relationship, as it depends on the display device correctly reporting its resolution, which in turn is dependent on the display, its configuration, and what the user has set e.g. in the "large fonts" setting (i.e. in the screen resolution settings, clicking the link that reads "Make text and other items larger or smaller").
All of these affect WPF's interpretation of the available display resolution information, which in turn affect how WPF chooses to render its "device independent" 1/96th of a inch units.
The bottom line is that the link commenter Sheridan offered really is the closest you can come to displaying in millimeters, barring a lot of extra work and help from the user. By scaling your input units, intended as millimeters, by the factor value provided (i.e. 96/ 25.4…in the expression, you can see the 25.4 to convert from millimeters to inches, then the 96 that converts inches to 1/96ths of an inch), you can convert your millimeters into the 96 dpi units that WPF uses natively.
Assuming the display is configured correctly (an optimistic assumption, but it does happen :) ), this will result in reasonably accurate presentation on the screen according to your desired millimeter-based dimensions.
Note that you can accomplish this scaling through the use of a transform on your rendered UI elements. The easiest thing to do would be to set the LayoutTransform property of the outer-most container object where you want the millimeter-based rendering. Then you can just lay out your objects in that container using the millimeters values for their location and size, and WPF will use the transform to present the container and the rendered objects within at the scale you want.

Categories

Resources