Nevron .NET Vision
Chart for .NET / User's Guide / Axes / Scale / Manually Programming the Scale / Scale Calculation and Decoration

In This Topic
    Scale Calculation and Decoration
    In This Topic
     Scale Calculation

    The process of scale calculation includes the calculation of the transformation of logical to scale units. Part of this calculation includes taking into account scale logical range inflation – this for example happens when you want to have axes that are rounded to the nearest min or max tick.

    Logical range inflation is performed by NRangeInflator derived objects. There are two types of range inflators:

    1. Custom Range Inflator - As the name implies this range inflator allows you to manually specify how the range is inflated in order to accumulate a value.
    2. Sampled Range inflator - A sampled range inflator will get the output of a range sampler and round the begin and end values of the range so that they fall on an exact step of the range sampler. For example given the range [21, 41] a sampled range inflator with numeric range sampler with step 5 and origin 0 will inflate the range to [20, 45]. The NSampledRange inflator class represents this type of range inflation.
     Scale Decoration

    To better understand the scale decoration lets first take a look at a simple axis:



    figure 1.

    Each scale visual representation consists of two groups of decorations:

    Scale decorations - These decorations are displayed along the scale and the most commonly used ones are the scale tick and scale label decorations.

    Wall decorations - Wall decorations are also embedded in the scale definition but are displayed on one or more walls as defined by their ShowAtWalls property.

    Furthermore scale decorations are grouped in levels. Each scale can have an unlimited number of levels containing an unlimited number of decorations. The important point here is that scale levels much like the axis dock zone levels cannot overlap. You can think of scale level decorations as characters in a single line of text – some characters may be taller than others or below the base line of text, but each line of text does not overlap the rest. This concept is illustrated by the following picture:



    figure 2.

    You add a scale level by creating an instance of the NScaleLevel class and adding it to the scale levels collection:

    C#
    Copy Code
    NScaleLevel scaleLevel = new NScaleLevel();
    scale.Levels.Add(scaleLevel);
    
    Visual Basic
    Copy Code
    Dim scaleLevel as NScaleLevel = New NScaleLevel()
    Scale.Levels.Add(scaleLevel)
    
    Scale decoration is performed by decorators. Each scale level can have an unlimited number of decorators that outputs scale decorations in it given the scale logical range. Similarly to range inflators there two types of scale decorators - Custom Scale Decorators and Sampled Scale Decorators
     Custom Scale Decorators

    Custom scale decorators allow you to define a set of scale decorations that will decorate the scale if they fall in the scale range. The following code will create a custom scale decorator and a new level on the scale that contains a label:

    C#
    Copy Code
    NScaleLevel scaleLevel = new NScaleLevel();
    NCustomScaleDecorator customScaleDecorator = new NCustomScaleDecorator();
    NValueScaleLabel label = new NValueScaleLabel();
    label.Text = "Danger Zone";
    label.Anchor = new NRulerValueDecorationAnchor(HorzAlign.Right, new NLength(0));
    label.Style.TextStyle.FillStyle = new NColorFillStyle(Color.Red);
    label.Style.Offset = new NLength(6, NGraphicsUnit.Point);
    label.Style.ContentAlignment = ContentAlignment.TopLeft;
    label.Style.Angle = new NScaleLabelAngle(ScaleLabelAngleMode.View, 90);
    
    customScaleDecorator.Decorations.Add(label);
    scaleLevel.Decorators.Add(customScaleDecorator);
    
    Visual Basic
    Copy Code
    Dim scaleLevel As NScaleLevel = New NScaleLevel
    Dim customScaleDecorator As NCustomScaleDecorator = New NCustomScaleDecorator
    Dim label As NValueScaleLabel = New NValueScaleLabel
    label.Text = "Danger Zone"
    label.Anchor = New NRulerValueDecorationAnchor(HorzAlign.Right, New NLength(0))
    label.Style.TextStyle.FillStyle = New NColorFillStyle(New NArgbColor(Color.Red))
    label.Style.Offset = New NLength(6, NGraphicsUnit.Point)
    label.Style.ContentAlignment = ContentAlignment.TopLeft
    label.Style.Angle = New NScaleLabelAngle(ScaleLabelAngleMode.View, 90)
    customScaleDecorator.Decorations.Add(label)
    scaleLevel.Decorators.Add(customScaleDecorator)
    
     Sampled Range Decoration

    Sampled range decoration will use the output of a range sampler for a given scale range in order to create decorations for each sampled range.

    Sampled range decoration is represented by the NSampledScaleDecorator, which groups together a range sampler and scale decoration factory. In this way when the range sampler produces a range the decorator tells the factory to create a new decoration given that range. This is a powerful concept, because it allows you to decouple the range sampling from the actual scale decorations that are generated in the scale level.

    The following code will create ticks in the range [70, 100] with step 5:

    C#
    Copy Code
    NNumericStepRangeSampler rangeSampler = new NNumericStepRangeSampler(new NCustomNumericStepProvider(5));
    NClampedRangeSampler clampedRangeSampler = new NClampedRangeSampler(rangeSampler, new NRange1DD(70, 100));
    
    NScaleTickFactory tickFactory = new NScaleTickFactory(ScaleTickShape.Line,
    new NLength(0),
    new NSizeL(0, 5),
    new NConstValueProvider(new NColorFillStyle(Color.Red)),
    new NConstValueProvider(new NStrokeStyle(1, Color.Red)),
    HorzAlign.Left);
    NSampledScaleDecorator sampledDecorator = new NSampledScaleDecorator(clampedRangeSampler, tickFactory);
    scaleLevel.Decorators.Add(sampledDecorator);
    
    Visual Basic
    Copy Code
    Dim rangeSampler As New NNumericStepRangeSampler(New NCustomNumericStepProvider(5))
    Dim clampedRangeSampler As New NClampedRangeSampler(rangeSampler, New NRange1DD(70, 100))
    Dim tickFactory As New NScaleTickFactory(ScaleTickShape.Line, _
    New NLength(0), _
    New NSizeL(0, 5), _
    New NConstValueProvider(New NColorFillStyle(Color.Red)), _
    New NConstValueProvider(New NStrokeStyle(1, Color.Red)), _
    HorzAlign.Left)
    
    Dim sampledDecorator As New NSampledScaleDecorator(clampedRangeSampler, tickFactory)
    scaleLevel.Decorators.Add(sampledDecorator)
    
     Wall Decoration

    Wall decoration uses the same approach as scale decoration except that the wall decorators are placed in the wall decorators collection of the scale. The following code snippet will add custom grid lines to the primary Y axis of the chart and override any previous decorators:

    C#
    Copy Code
    NNumericStepRangeSampler rangeSampler = new NNumericStepRangeSampler(new NCustomNumericStepProvider(5));
    NClampedRangeSampler clampedRangeSampler = new NClampedRangeSampler(rangeSampler, new NRange1DD(70, 100));
    
    NGridLineFactory gridLineFactory = new NGridLineFactory(
                                    new NConstValueProvider(new NStrokeStyle(Color.Red)),
                                    HorzAlign.Left,
                                    new ChartWallType[] { ChartWallType.Back });
    
    NSampledWallDecorator sampledDecorator = new NSampledWallDecorator(clampedRangeSampler, gridLineFactory);
    
    NAxis primaryY = chart.Axis(StandardAxis.PrimaryY);
    primaryY.Scale.WallDecorators.Clear();
    primaryY.Scale.WallDecorators.Add(sampledDecorator);
    
    Visual Basic
    Copy Code
    Dim rangeSampler As New NNumericStepRangeSampler(New NCustomNumericStepProvider(5))
    Dim clampedRangeSampler As New NClampedRangeSampler(rangeSampler, New NRange1DD(70, 100))
    
    Dim chartWallTypes(1) As ChartWallType
    chartWallTypes(0) = ChartWallType.Back
    
    Dim gridLineFactory As New NGridLineFactory( _
                                    New NConstValueProvider(New NStrokeStyle(Color.Red)), _
                                    HorzAlign.Left, _
                                    chartWallTypes)
    
    Dim sampledDecorator As New NSampledWallDecorator(clampedRangeSampler, gridLineFactory)
    
    Dim primaryY As NAxis = chart.Axis(StandardAxis.PrimaryY)
    primaryY.Scale.WallDecorators.Clear()
    primaryY.Scale.WallDecorators.Add(sampledDecorator)
    
    Finally you should know that the drawing order of the generated wall decorations is dependent on the order of the wall decorators and the type of decorations. Grid lines will always be drawn on top of strip lines. Decorations of the same type will have the same order as the decorator that produced them – for example grid lines produced by the first decorator will be drawn first, grid lines produced by the second decorator will be drawn second and so on.
     Related Examples
    Windows Forms: Axes \ Scaling \ Custom Scale Decorations
    See Also