From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF Custom Axes labels

Solved!
Go to solution

Hi,

I would like to have the HorizontalScale of an IntensityGraph labeled in units of π (Pi). I found much about the LabelFormat (which i reckon is only available in WinForms), where I could just set the custom numeric format string to something like ("#.## π") and scale my horizontal values to 2 (from 2*Pi), but I could not find this in WPF. It would also be nice to have it like 1/2π or π/2 and not 0.5π.

Can anybody help me?
Thanks

0 Kudos
Message 1 of 5
(3,330 Views)

In WPF, the format of division labels is controlled by the LabelPresenter property on the MajorDivisions for the axis. With a little custom code, we can adapt the primitive AngularValueFormatter used by the PolarGraph to get radian labels on an intensity graph:

 

Code:

public class RadiansFormatter : AngularValueFormatter {
    public static RangeDivisionsMode MajorRadians = RangeDivisionsMode.CreateIntervalMode( 0.0, Math.PI / 2.0 );
public static RangeDivisionsMode MinorRadians = RangeDivisionsMode.CreateIntervalMode( 0.0, Math.PI / 8.0 ); private readonly PolarAngularAxis _radiansAxis = new PolarAngularAxis { ScaleKind = AngularScaleKind.Radians };
protected override string FormatCore<TData>( TData value, ValuePresenterArgs args ) { return base.FormatCore<TData>( value, args.ChangeContext( _radiansAxis ) ); } }

XAML:

<ni:IntensityGraph.HorizontalAxis>
    <ni:AxisDouble Orientation="Horizontal">
        <ni:AxisDouble.MajorDivisions>
            <ni:RangeLabeledDivisions Mode="{x:​Static local:RadiansFormatter.MajorRadians}">
                <ni:RangeLabeledDivisions.LabelPresenter>
                    <local:RadiansFormatter Format="0.##" />
                </ni:RangeLabeledDivisions.LabelPresenter>
            </ni:RangeLabeledDivisions>
        </ni:AxisDouble.MajorDivisions>
        <ni:AxisDouble.MinorDivisions>
            <ni:RangeDivisions Mode="{x:​Static local:RadiansFormatter.MinorRadians}" />
        </ni:AxisDouble.MinorDivisions>
    </ni:AxisDouble>
</ni:IntensityGraph.HorizontalAxis>

 

This will display labels using the "0.##" decimal format with the "π" symbol. (To get vulgar fractions instead of decimal values, you can customize the logic in the FormatCore method.)

~ Paul H
0 Kudos
Message 2 of 5
(3,310 Views)

Thank you so far Paul, I got some weird compiler errors at first, which disappeared after rewriting your code and letting IntelliSense lookup the classes and linking.

The next thing I would like to do (and this might be the last for the time being ;-)), is plotting a sine wave in front of my IntensityGraph, just one oscillation (thats also why I need the 2*Pi scale). I tried this by putting the according data in another Point3D-Array and assign it to IntensityGraph.Data[1]. This does not work, I assume the IntensityGraph takes only one set of data for plotting? The other thing I don't like about this method is, that I have to work around a bit with the Colorscale to have the sinewave plotted in black and my IntensityGraph scaling from green to red...

Would you have another idea for that? The sinewave is supposed to be displayed the whole time, so it won't change at runtime  etc.

Thanks for all your replies Paul, it's amazing how fast and sophisticated you are answering ;-)!

0 Kudos
Message 3 of 5
(3,285 Views)
Solution
Accepted by topic author mrpip

I just have a lot of practice at answering questions 😉

 

I would suggest looking at the “NonUniformIntensity” project in the WPF examples included with Measurement Studio. That examples shows three intensity plots in a single Graph, but the general approach would be the same for any multi-plot example. For your case, instead of three plots using IntensityPlotRenderer, you would have one intensity plot (for your 3D data), and one other plot using a LinePlotRenderer to draw the sine wave (which would take 2D data).

~ Paul H
Message 4 of 5
(3,280 Views)

Just wanted to let you know that the AngularValueFormatter.ScaleKind property was added in Measurement Studio 2019, so now it can be used directly to format axis labels:

<ni:AxisDouble>
    <ni:AxisDouble.MajorDivisions>
        <ni:RangeLabeledDivisions>
            <niPrimitives:AngularValueFormatter ScaleKind="Radians" />
        </ni:RangeLabeledDivisions>
    </ni:AxisDouble.MajorDivisions>
</ni:AxisDouble>

 

~ Paul H
0 Kudos
Message 5 of 5
(2,123 Views)