Search Results for

    Show / Hide Table of Contents

    Custom Modifiers - the ChartModifierBase API

    The ChartModifierBase API is by far the most powerful API in the SciChart library. The ChartModifierBase provides an abstract base class for all of the 2D ChartModifiers within SciChart, all of our built-in 2D modifiers inherit from it. Using this API, you can create behaviours which you can attach to a chart to perform custom Zooming, Panning, Annotation & Markers, Legend output and much much more. Any time you want to do something to alter the behaviour of a SciChartSurface you should be thinking about creating a custom modifier to do it.

    Custom Chart Rotation Modifier

    A simple example below shows how you can use ChartModifierBase API to create a chart rotation modifier. Add it onto your chart like any other modifier to see how it works.

    Let's get to the code:

    Note

    It's highly recommended to inherit from ChartModifierBase since it gives you some of the base implementation for free.

    • Java
    • Java with Builders API
    • Kotlin
    class CustomRotateChartModifier extends ChartModifierBase {
        public void rotateChart() {
            if (isAttached()) {
                final ISciChartSurface parentSurface = getParentSurface();
    
                IUpdateSuspender updateSuspender = parentSurface.suspendUpdates();
                try {
                    rotateAxes(parentSurface.getXAxes());
                    rotateAxes(parentSurface.getYAxes());
                } finally {
                    updateSuspender.dispose();
                }
            }
        }
    
        private void rotateAxes(AxisCollection axes) {
            for (int i = 0, size = axes.size(); i < size; i++) {
                final IAxis axis = axes.get(i);
                final AxisAlignment axisAlignment = axis.getAxisAlignment();
    
                switch (axisAlignment) {
                    case Right:
                        axis.setAxisAlignment(AxisAlignment.Bottom);
                        break;
                    case Left:
                        axis.setAxisAlignment(AxisAlignment.Top);
                        break;
                    case Top:
                        axis.setAxisAlignment(AxisAlignment.Right);
                        break;
                    case Bottom:
                        axis.setAxisAlignment(AxisAlignment.Left);
                        break;
                    case Auto:
                        if(axis.isXAxis()) {
                            // Bottom
                            axis.setAxisAlignment(AxisAlignment.Left);
                        } else {
                            // Right
                            axis.setAxisAlignment(AxisAlignment.Bottom);
                        }
                }
            }
        }
    }
    
    class CustomRotateChartModifier extends ChartModifierBase {
        public void rotateChart() {
            if (isAttached()) {
                final ISciChartSurface parentSurface = getParentSurface();
    
                IUpdateSuspender updateSuspender = parentSurface.suspendUpdates();
                try {
                    rotateAxes(parentSurface.getXAxes());
                    rotateAxes(parentSurface.getYAxes());
                } finally {
                    updateSuspender.dispose();
                }
            }
        }
    
        private void rotateAxes(AxisCollection axes) {
            for (int i = 0, size = axes.size(); i < size; i++) {
                final IAxis axis = axes.get(i);
                final AxisAlignment axisAlignment = axis.getAxisAlignment();
    
                switch (axisAlignment) {
                    case Right:
                        axis.setAxisAlignment(AxisAlignment.Bottom);
                        break;
                    case Left:
                        axis.setAxisAlignment(AxisAlignment.Top);
                        break;
                    case Top:
                        axis.setAxisAlignment(AxisAlignment.Right);
                        break;
                    case Bottom:
                        axis.setAxisAlignment(AxisAlignment.Left);
                        break;
                    case Auto:
                        if(axis.isXAxis()) {
                            // Bottom
                            axis.setAxisAlignment(AxisAlignment.Left);
                        } else {
                            // Right
                            axis.setAxisAlignment(AxisAlignment.Bottom);
                        }
                }
            }
        }
    }
    
    class CustomRotateChartModifier : ChartModifierBase() {
        fun rotateChart() {
            if (isAttached) {
                val parentSurface = parentSurface
                val updateSuspender = parentSurface.suspendUpdates()
                try {
                    rotateAxes(parentSurface.xAxes)
                    rotateAxes(parentSurface.yAxes)
                } finally {
                    updateSuspender.dispose()
                }
            }
        }
    
        private fun rotateAxes(axes: AxisCollection) {
            var i = 0
            val size = axes.size
            while (i < size) {
                val axis = axes[i]
                val axisAlignment = axis.axisAlignment
                when (axisAlignment) {
                    AxisAlignment.Right -> axis.axisAlignment = AxisAlignment.Bottom
                    AxisAlignment.Left -> axis.axisAlignment = AxisAlignment.Top
                    AxisAlignment.Top -> axis.axisAlignment = AxisAlignment.Right
                    AxisAlignment.Bottom -> axis.axisAlignment = AxisAlignment.Left
                    AxisAlignment.Auto -> if (axis.isXAxis) {
                        // Bottom
                        axis.axisAlignment = AxisAlignment.Left
                    } else {
                        // Right
                        axis.axisAlignment = AxisAlignment.Bottom
                    }
                }
                i++
            }
        }
    }
    

    The modifier above allows to rotate a chart when added to its ChartModifierCollection.

    The common methods that are currently implemented and are not likely to be replaced can be found in the Chart Modifier APIs article. For more information - please read the IChartModifier API documentation.

    Note

    If you want to handle gestures in your custom ChartModifier, you could derive it from the GestureModifierBase class, which provides base infrastructure for GestureDetector usage.

    The ModifierTouchEventArgs Type

    If your custom ChartModifier requires to handle touch events or gestures, you might need to override either the onTouch(ModifierTouchEventArgs args) or onGenericMotion(ModifierTouchEventArgs args) method. Both receive the only parameter of the ModifierTouchEventArgs type. This type exposes the following information about an event that occurred:

    Field Description
    source Provides the source of the event, of the IReceiveMotionEvents type.
    isEventWithinBounds(IHitTestable hitTestable) Reports whether the event occurred within the Source.
    isHandled Reports whether the event has been already passed to any other modifier and handled by it.
    e Returns the original MotionEvent instance
    Note

    To receive handled events, use setReceiveHandledEvents(boolean receiveHandledEvents) on a modifier and set it to true.

    Back to top © 2011-2025 SciChart. All rights reserved. | sitemap.xml