SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and iOS Chart & Android Chart Components

0 votes


I am currently adding a Vertical Slice Modifier with just on Vertical Line inside of it.
The idea is to create a vertical cursor to display Y values for a given X value.
As my chart is a real time chart, I don’t want my cursor position changed expect on user interaction, I set to Relative the CoordinateMode property of my Annotation.

<s:VerticalSliceModifier Name="sliceModifier" ShowTooltipOn="Always" IsEnabled="True">
                        <s:VerticalLineAnnotation IsEditable="True" X1="0.5" Stroke="#D62D15" CoordinateMode="Relative"/>

The vertical line is correctly displayed at the centre of the surface but point markers and tooltips are not displayed at the line position, it seems the relative coordinate mode is not handle on this area.

Thanks for your help

0 votes
0 answers

Dear Team,

We are evaluating Scichart Candle series chart from example suite and facing following issue [Stock market analysis product]. I am using 2 example from the demo solution of scichart after extracting. Attached are solution to reproduce. We are using version of scichart.

SciChart multipane candle chart or candle line example project throws Access Violation in Scichart.Data.Dll if number of points increased to 5000 or above. The issue happens in both solutions Multiplane chart and CandleStickAndLines.

1) SciChart_MultiPaneStockCharts.sln:

if i increase number of candle points around 5k to 10k, (i wrote an API which reads data points file this data is of real Stock Market data).

Issue 1) Firstly the chart does not render if points are more than 5000. But If we do any resize of window height or width the chart renders. If i include volume panel and other indicators like in the example the chart throws Access violation.

Issue 2) If i comment all the series retain only candle series the chart renders with 5-10k points but only after resize of window. And if i add volume panel runtime from a button click (i added Add Panel button on left hand side tray) the chart crashes with Access Violation in SciChart.Data.dll

Issue 3) The width of the chart does not work fine, even with example data set which is about 3k+ points if i shrink the width lets say to half and then make large, couple of times the chart then does not invalidate or redraw just becomes small and then nothing works (zoom , pan or any clicks)

Issue4) I also saw crash when i tried to move the axis X couple of times, again when volume and other series were present.

In this project since it creates series from code behind the CandleSeries ( but with line series commented) works fine even if 10k points added.
But as soon the Line series added dynamically by button or by lets say right click the chart crashes Access Violation. It seems there is a threshold above which FastLineRenderableSeries (column, line etc) crashes with Access Violation.

Kindly need your assistance. If this issue can be fixed or has been fixed we would be pushing management to buy the license of the product we really like its feartures.


0 votes
0 answers

I would like to display tooltip in front.

At Stacked/FastColumnRendarableSeries,
I would like to display tooltip on the x axis’s label.
Is it possible?

At PieChart,
I would like to display tooltip on the other control,
Because, pie chart’s area is narrow.
Is it possible?

Please refer to the attached file for details.


0 votes
0 answers


I need to display realtime chart with 20 series of data. My data is arriving at 500Hz. When I’m displaying this data, I find that after a while SciChart hangs with what appears to be a deadlock.

I’ve read as much as I can find about realtime graphing with SciChart and I started with tutorial 4 – Adding Realtime Updates. This article ( suggests that SciChart is thread safe so I tried using a second thread to feed data into a graph. My only change was to move from the main thread timer in the example to a GCD timer running at 500Hz. With this, I’m easily able to reproduce the deadlock in around 1.5 seconds.

Here is the main thread which is attempting to render:

Thread 1 Queue : (serial)
#0  0x0000000192bc8c20 in __psynch_rw_rdlock ()
#1  0x0000000192ae4864 in _pthread_rwlock_lock_wait ()
#2  0x0000000192ae47fc in _pthread_rwlock_lock_slow$VARIANT$mp ()
#3  0x0000000104a93828 in -[SCIRenderableSeriesLock initWithRenderableSeries:] ()
#4  0x0000000104ab742c in -[SCIRenderSurfaceRenderer p_SCI_updateCoreData:renderPassState:viewportSize:] ()
#5  0x0000000104ab6f4c in -[SCIRenderSurfaceRenderer p_SCI_renderLoop:assetManager:renderPassState:] ()
#6  0x0000000104ab6dc4 in -[SCIRenderSurfaceRenderer onDrawWithContext:andAssetManager:] ()
#7  0x00000001049c50c0 in -[SCIRenderSurfaceDrawable2D drawFrameIn:withDrawableSize:] ()
#8  0x0000000104ad4db8 in -[SCITwisterRendererBase drawFrameIn:withDrawableSize:] ()
#9  0x00000001049e56c8 in -[SCIMetalRenderer drawFrameIn:withDrawableSize:] ()
#10 0x0000000104a25b70 in -[SCIMetalRenderSurfaceBase draw] ()
#11 0x00000001999861ec in -[CALayer display] ()
#12 0x00000001999984d4 in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#13 0x00000001998e11d8 in CA::Context::commit_transaction(CA::Transaction*, double) ()
#14 0x000000019990ab78 in CA::Transaction::commit() ()
#15 0x000000019990b58c in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#17 0x0000000192d4beb0 in __CFRunLoopDoObservers ()
#18 0x0000000192d4c32c in __CFRunLoopRun ()
#19 0x0000000192d4bc38 in CFRunLoopRunSpecific ()
#20 0x000000019d39a38c in GSEventRunModal ()
#21 0x0000000196e7c444 in UIApplicationMain ()
#22 0x00000001042cc478 in main at /Users/mall/Downloads/SciChart.iOS.Examples-SciChart_v3_Release/tutorials/tutorials-2d/Tutorial 04 - Adding Realtime Updates/Tutorial 04 - Adding Realtime Updates/AppDelegate.swift:5
#23 0x0000000192bd38f0 in start ()

and here is my worker thread adding data to a series:

Thread 11 Queue : (concurrent)
#0  0x0000000192bc8c20 in __psynch_rw_rdlock ()
#1  0x0000000192ae4864 in _pthread_rwlock_lock_wait ()
#2  0x0000000192ae47fc in _pthread_rwlock_lock_slow$VARIANT$mp ()
#3  0x0000000104ac1518 in -[SCIXDataSeries p_SCI_searchDataIndexOn:xMinAsDouble:xMaxAsDouble:downSearchMode:upSearchMode:] ()
#4  0x0000000104ac1368 in -[SCIXDataSeries getIndicesXRange:xMinAsDouble:xMaxAsDouble:isCategoryAxis:] ()
#5  0x0000000104ac1b34 in -[SCIXDataSeries getWindowYRangeWithXCoordCalc:getPositiveRange:] ()
#6  0x0000000104aceddc in -[SCIRenderableSeriesBase getYRange:positive:] ()
#7  0x00000001049b25ac in -[SCIRangeCalculationHelper2DBase getWindowedYRangeWithXCalculators:] ()
#8  0x0000000104a05f84 in -[SCIAxisBase getWindowedYRangeWithXRanges:] ()
#9  0x00000001049f4184 in -[SCIChartSurface p_SCI_zoomExtentsYWithCalculators:andDuration:] ()
#10 0x00000001049f3d14 in -[SCIChartSurface p_SCI_zoomExtentsWithDuration:] ()
#11 0x00000001042c79e8 in closure #1 in ViewController.handleTimer() at /Users/mall/Downloads/SciChart.iOS.Examples-SciChart_v3_Release/tutorials/tutorials-2d/Tutorial 04 - Adding Realtime Updates/Tutorial 04 - Adding Realtime Updates/ViewController.swift:84
#12 0x00000001042c7500 in thunk for @escaping @callee_guaranteed () -> () ()
#13 0x0000000104abdae0 in +[SCIUpdateSuspender usingWithSuspendable:withBlock:] ()
#14 0x00000001042c7824 in ViewController.handleTimer() at /Users/mall/Downloads/SciChart.iOS.Examples-SciChart_v3_Release/tutorials/tutorials-2d/Tutorial 04 - Adding Realtime Updates/Tutorial 04 - Adding Realtime Updates/ViewController.swift:79
#15 0x00000001042c9250 in partial apply ()
#16 0x00000001042cb1e4 in closure #1 in closure #1 in RepeatingTimer.timer.getter at /Users/mall/Downloads/SciChart.iOS.Examples-SciChart_v3_Release/tutorials/tutorials-2d/Tutorial 04 - Adding Realtime Updates/Tutorial 04 - Adding Realtime Updates/RepeatingTimer.swift:26
#17 0x00000001042c7500 in thunk for @escaping @callee_guaranteed () -> () ()
#18 0x0000000107093730 in _dispatch_client_callout ()
#19 0x0000000107096390 in _dispatch_continuation_pop ()
#20 0x00000001070a9614 in _dispatch_source_invoke ()
#21 0x00000001070a4d74 in _dispatch_root_queue_drain ()
#22 0x00000001070a5698 in _dispatch_worker_thread2 ()
#23 0x0000000192aeab38 in _pthread_wqthread ()

Here is my version of the ViewController class from Tutorial 4 with the GCD timer (note that it uses RepeatingTimer class found here: – my changes are marked with the //MALL comment:

import UIKit
import SciChart

class ViewController: UIViewController {

    private var timer = RepeatingTimer(timeInterval: 1.0/500.0)

    private let pointsCount = 200
    private var count: Int = 0

    private let lineData = SCIDoubleValues()
    private lazy var lineDataSeries: SCIXyDataSeries = {
        let lineDataSeries = SCIXyDataSeries(xType: .int, yType: .double)
        lineDataSeries.seriesName = "Line Series"
        lineDataSeries.fifoCapacity = 300
        return lineDataSeries
    private let scatterData = SCIDoubleValues()
    private lazy var scatterDataSeries: SCIXyDataSeries = {
        let scatterDataSeries = SCIXyDataSeries(xType: .int, yType: .double)
        scatterDataSeries.seriesName = "Scatter Series"
        scatterDataSeries.fifoCapacity = 300
        return scatterDataSeries

    private var surface: SCIChartSurface {
        return view as! SCIChartSurface

    override func loadView() {
        viewRespectsSystemMinimumLayoutMargins = false
        view = SCIChartSurface()

    override func viewDidLoad() {

        let xValues = SCIIntegerValues()
        for i in 0 ..< pointsCount {
            lineData.add(sin(Double(i) * 0.1))
            scatterData.add(cos(Double(i) * 0.1))
            count += 1
        lineDataSeries.append(x: xValues, y: lineData)
        scatterDataSeries.append(x: xValues, y: scatterData)

        let lineSeries = SCIFastLineRenderableSeries()
        lineSeries.dataSeries = lineDataSeries

        let pointMarker = SCIEllipsePointMarker()
        pointMarker.fillStyle = SCISolidBrushStyle(colorCode: 0xFF32CD32)
        pointMarker.size = CGSize(width: 10, height: 10)

        let scatterSeries = SCIXyScatterRenderableSeries()
        scatterSeries.dataSeries = scatterDataSeries
        scatterSeries.pointMarker = pointMarker

        let legendModifier = SCILegendModifier()
        legendModifier.orientation = .horizontal
        legendModifier.position = [.bottom, .centerHorizontal]
        legendModifier.margins = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)

        SCIUpdateSuspender.usingWith(self.surface) {
            self.surface.xAxes.add(items: SCINumericAxis())
            self.surface.yAxes.add(items: SCINumericAxis())
            self.surface.renderableSeries.add(items: lineSeries, scatterSeries)
            self.surface.chartModifiers.add(items: SCIPinchZoomModifier(), SCIZoomExtentsModifier())
            self.surface.chartModifiers.add(items: SCIRolloverModifier(), legendModifier)

        //  MALL
        timer.eventHandler = handleTimer

    //  MALL
    private func handleTimer() {
        let x = count
        SCIUpdateSuspender.usingWith(surface) {
            self.lineDataSeries.append(x: x, y: sin(Double(x) * 0.1))
            self.scatterDataSeries.append(x: x, y: cos(Double(x) * 0.1))

            // zoom series to fit viewport size into X-Axis direction
            self.count += 1

Thanks in advance for any help you can offer.

0 votes


In the real-time line chart, I want an animation like the video(link below).
Can you be provided with animations such as a point where a point drawn in real time continues to blink?

0 votes


I set up my xAxis (DateAxis) with a minimalZoomConstrain = DateInterval.fromMinutes(3.0). And here is my PinchZoomModifier:

val pinchZoomModifier = PinchZoomModifier().apply {
        direction = Direction2D.XDirection
        receiveHandledEvents = true

The chart works great and restricts the zoom to three minutes, but I get this error to the console whenever I zoom in to reach the minimalZoomConstrain:

E/Axis: VisibleRange was restored to its last valid value. The range class (Min = Tue Jan 09 01:52:40 GMT+01:00 2020, Max = Tue Jan 09 01:55:40 GMT+01:00 2020) either is not valid or it doesn't satisfy MinimalZoomConstrain or MaximumZoomConstrain. To provide fallback value please override AxisCore#coerceVisibleRange(IRange) method

How can I get rid of this error? Is there a way to tell the PinchZoomModifier that there is a min limit?

0 votes

This issue was reported on support tickets by a customer, and we are duplicating here for the community.

Our application use SciChart, it runs normal on most of PCs, but there is one PC which runs the application threw an exception, please see below log info.

2020-07-03 08:08:21,091 [1]-[OnUnhandledException] ERROR Exception has been thrown by the target of an invocation.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.Windows.Markup.XamlParseException: Set property ‘SciChart.Charting.VisualXcceleratorEngine.IsEnabled’ threw an exception. —> System.Exception: Your GPU is blacklisted for use by the Visual Xccelerator Engine! There are several reasons why a GPU could belong to the blacklist. For example, low computation capabilities of the GPU could cause Timeout Detection and Recovery of Graphics Adapter Drivers by the OS, resulting in crashing the application. at SciChart.Charting.VisualXcceleratorEngine.ivc(DependencyObject t, DependencyPropertyChangedEventArgs u) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)

what should I do? how to resolve this issue?

0 votes

I am setting SCIDateTimeAxis as my XAxis by using the code:

let xAxis = SCIDateTimeAxis() = UIColor.darkGray
xAxis.textFormatting = “dd MMM”
xAxis.visibleRange = SCIDateRange(dateMin: 2019-07-29 11:30:00, max:2019-07-29 11:30:00)

As I have a requirement to change the application Language to THI.
How can I set the locale to the axis, so the label visible on the axis should displayed in THI language.

As right now it is always visible in english irrespective of the language like 1 sep, 20 sep, 10 oct, 30 oct, 20 nov .

Please help.

Vikas Ahuja

0 votes


I have this chart with CategoryXAxis` as X and **NumericAxis as Y. I update its IohlcDataseries with new prices for creating a live chart. I also added a HorizontalLineAnnotation on Y-Axis to point to the current price. The problem is when chart auto-scales on Y-axis it only tries to cover price data and not the Line annotation, and its label is half visible.

0 votes
0 answers
0 votes
0 answers
0 votes

i am using one LineSeries, two ScatterSeries and one ErrorBarsSeries in my Graph.

I want to disable whole Rollover Modifier or labels of Rollover Modifier for only ErrorBarsSeries , How can I do that?

  • Atiq Tahir asked 2 weeks ago
  • last active 2 weeks ago
0 votes

Hello, I have tried to see if it is possible to show the rollover without showing any labels so that is is just a vertical bar. I was searching on StackOverflow and a few answers said it was not possible to omit any of the values from the graph. I did see that we can customize the cursor, is it possible to just have it be a vertical bar instead of a cross?? Then I could just use it instead of the default rollover.

I am linking a mockup we made of what we want to make. In the image, you have the graphic showing where the use as pressed, and above the graphic, we will show and update a graphic with the relevant information for that point.

Also, I will need to programmatically dismiss it so it will need to stay visible even if the user is panning or zooming.

0 votes

See the screen shot (attached)

To dupe this start on the SciChart home page, select documentation, select iOS, then enter anything into the search box.

I get the same results with Chrome and Safari.

0 votes

iOS 13.5
Xcode 10.15.5

If I am using the API incorrectly please let me know. I am not aware of any requirement to wait after using the SciChart API.

It appears the SCILegendModifier has some kind of timing bug. If you draw a chart on a surface with a legend, then clear the chart, then add another plot to the same surface you will notice the legend has stale data. However, if you clear the surface and wait a second before you add the new plot it will work as expected.

I created a sample Xcode project to demonstrate the issue. See the attachment

I also created a video to demonstrate the issue:

I have a workaround so this is not urgent, but I would like to remove the delay for my production release.

0 votes
0 answers

I have created a composite annotation that consists of four elements: two VerticalLineAnnotations, a BoxAnnotation, and a TextAnnotation. When I first add the annotation, everything appears correctly. However, when I change between tabs in my TabControl… the BoxAnnotation disappears. The box will reappear when I move the composite annotation a few pixels.

Note: Calling ZoomExtents() or InvalidateElement() does not fix the issue.

I’ve created a simple app to reproduce the issue.


<s:CompositeAnnotation x:Class="WpfPresentation.Views.PeakAnnotation"

    <s:VerticalLineAnnotation CoordinateMode="Relative" Stroke="#FFBADAFF" StrokeThickness="2" X1="0" X2="0" Y1="0" Y2="1"/>
    <s:VerticalLineAnnotation CoordinateMode="Relative" Stroke="#FFBADAFF" StrokeThickness="2" X1="1" X2="1" Y1="0" Y2="1"/>
    <s:BoxAnnotation x:Name="box" Opacity="0.2" CornerRadius="2" Background="#FFBADAFF" BorderBrush="#1964FF" CoordinateMode="Relative" X1="0" X2="1" Y1="0" Y2="1"/>
    <s:TextAnnotation x:Name="AnnotationTextLabel" CoordinateMode="Relative" X1="0" Y1="0.95" FontSize="12" Foreground="White"/>


public partial class PeakAnnotation : CompositeAnnotation
    public PeakAnnotation()


    public PeakAnnotation(string annotationText)
        AnnotationTextLabel.Text = annotationText;

    public string StyleKey { get; set; }

    public Type ViewType => throw new NotImplementedException();


public MainViewModel()
        ChartTitle = "Testing";

        Annotations = new AnnotationCollection();

        var myAnnotation = new PeakAnnotation("My Annotation Title")
            X1 = 40,
            X2 = 50,
            Y1 = 0,
            Y2 = 100

    public string ChartTitle { get; set; }
    public AnnotationCollection Annotations { get; set; }


<Window x:Class="SciChartTesting.MainWindow"
    xmlns:local="clr-namespace:SciChartTesting" xmlns:s=""
    Title="MainWindow" Height="450" Width="800">

    <local:MainViewModel x:Key="MainViewModel"/>

<Grid DataContext="{StaticResource MainViewModel}">
        <TabItem Header="TabOne">
            <Label Content="This is TabOne"/>
        <TabItem Header="TabTwo">
            <s:SciChartSurface ChartTitle="{Binding ChartTitle}" Annotations="{Binding Annotations}">
                    <s:NumericAxis VisibleRange="0,100"/>
                    <s:NumericAxis VisibleRange="0,100"/>

0 votes


I want to implement a custom deltaX cursor in my software. It consists in two vertical lines that can be moved be the user and the idea to get the delta x (DateTime) between the two lines.
I’ve started to implement it by using two custom VerticalLineAnnotation added to a VerticalSliceManager. As my chart is a real time chart, I don’t want my cursors postions changed exepct on user interaction, that’s why I set to Relative the CoordinateMode property of my two Annotations.
The display and the interaction works fine, but when I try to retrieve the actual position of one cursor to compute the delta I have some trouble to convert the relative position to a DateTime value.
I have override the OnDragDelta() method, the relative value of X1 is correct but when I try to convert it into a DateTime by using FromRelativeCoordinate, I still have Date in 1899. I also try to interpret this as OA Date but I still have wrong date.

Do you have an idea ?

 public override void OnDragDelta()
        if (_sciChartSurface.XAxis != null)
            double dataValue = (double)this.FromRelativeCoordinate((double)this.X1, _sciChartSurface.XAxis);
            DateTime classic = new DateTime((long)dataValue);
            DateTime fromOa = DateTime.FromOADate(dataValue);
            Debug.WriteLine("CLASSIC "+ classic);
            Debug.WriteLine("OA "+ fromOa);
0 votes
0 answers

i have a SciChartGroup may have multiple charts, i hope when i click mouse left every chart it is cross only, i click it again every chart it is arrow only

  • Allen Qiu asked 3 weeks ago
  • last active 3 weeks ago
0 votes

Hi,I have upgrade my scichart from v4.2 to v6.2(trial version) After upgrade I have blow problems(I am using visual studio 2019):,
1.” SciStockChart didn’t render, because an exception was thrown:
Message: AxisCollection.GetAxisById(‘DefaultAxisId’) returned no axis with ID=DefaultAxisId. Please check you have added an axis with this Id to the AxisCollection
” shown int the output
2.when i mousewheel to load more data it will happen “System.AccessViolationException”
3.after when i loaded more data,I use the keyboard key left or key right to prev or next data ,it can’t pinpoint, in the TestDemo every minute is a alone data,i want to use the key left or key right to arrive it. the TestDemo “SimpleCursorModifier.cs” is control the cursor how to display, when it is cursors.Arrow i click i hope it change cross only, i click again i hope it change Cursors.Arrow,unfortunately it only change in one map(SciStockChart),i must move it is normal.

marks: when i user v4.2 no above questions, Attached( is my example

0 votes

We bind a view model’s AxisCollection to a surface’s XAxes. But our view model lives longer than the surface. It might get bound to a new surface as users click away (causing surface Dispose), then back to the chart (causing new Surface).

This used to work in SciChart 5.1, but broke when we upgrade to 5.5.

Seems to be because SciChartSurface now does UnsubscribeInnerCollection on that AxisCollection when the surface is disposed.
It means clear and re-add to that AxisCollection no longer automatically set IsPrimaryAxis = true on one axis. Which causes issues with various things that expect one (e.g. modifiers).

We can work around it (set IsPrimaryAxis true ourselves), but does this change mean you’re not expecting one AxisCollection to get re-used across different surface instances (but only one at a time)?


0 votes

I’m tested on iPhone 8 (iOS 13.5.1) and iPad (iPadOS 13.5.1). On iPad the graph always works great but on iPhone sooner or later it always fails.

The exception is always “Thread 1: EXC_BAD_ACCESS (code=1, address=0x11d927ffc)” in the application main:

int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); <–

in the task stack:

0x103b530e0 <+0>:  ldr    x8, [x0, #0x8]
  0x103b530e4 <+4>:  ldr    w8, [x8, w1, sxtw #2]   <--
0x103b530e8 <+8>:  scvtf  d0, w8
0x103b530ec <+12>: ret

The truth is, I have no idea what’s going on. .. Please, anyone know what might be happening?

Thank you very much!

Due to the app upgrade, the code is in objective-c. This is my initialization code:

- (void) loadSciChartSurface:(SCIChartSurface*)surface {
sciChartSurface = surface;
sciChartSurface.translatesAutoresizingMaskIntoConstraints = true;

// scroll
SCIZoomPanModifier *zoomPan = [SCIZoomPanModifier new];
zoomPan.receiveHandledEvents = true;
zoomPan.zoomExtentsY = false;
zoomPan.direction = SCIDirection2D_XDirection;
[sciChartSurface.chartModifiers add:zoomPan];

// zoom
SCIPinchZoomModifier *pinchZoomModifier = [SCIPinchZoomModifier new];
pinchZoomModifier.direction = SCIDirection2D_XDirection;
pinchZoomModifier.scaleFactor = 1.5;
[sciChartSurface.chartModifiers add:pinchZoomModifier];

// series
rSeries = [SCIFastLineRenderableSeries new];
xAxis = [SCINumericAxis new];
yAxis = [SCINumericAxis new];

xAxis.visibleRangeChangeListener = ^(id<ISCIAxis> axis, id<ISCIRange> oldRange, id<ISCIRange> newRange, BOOL isAnimating) {

    int min = newRange.minAsDouble;
    int max = newRange.maxAsDouble;
    int center = (min + max) / 2;

    if (center <= 0) {
        axis.visibleRange.min = @(0.0 - xHalfWidth);
        axis.visibleRange.max = @(xWidth - xHalfWidth);
    } else if (center >= dataSamples) {
        axis.visibleRange.min = @(dataSamples - xHalfWidth);
        axis.visibleRange.max = @(dataSamples + xHalfWidth);
    } else {
        // xWith is updated to keep the zoom factor in limits, when (center <= 0) or (center >= dataSamples)
        xWidth = max - min;
        xHalfWidth = xWidth / 2;

[SCIUpdateSuspender usingWithSuspendable:sciChartSurface withBlock:^{
    [sciChartSurface.xAxes add:xAxis];
    [sciChartSurface.yAxes add:yAxis];
    [sciChartSurface.renderableSeries add:rSeries];
    [SCIAnimations sweepSeries:rSeries duration:0.0 andEasingFunction:[SCICubicEase new]];

dataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Int yType:SCIDataType_Short];

// x
xWidth = theFileFormat.mSampleRate * MIN_SECONDS_IN_GRID * 1;
xIndex = 0;
xHalfWidth = xWidth / 2;
xAxis.visibleRange = [[SCIDoubleRange alloc] initWithMin:0.0 max:xWidth];

// y
yAxis.visibleRange = [[SCIDoubleRange alloc] initWithMin:SHRT_MIN max:SHRT_MAX];

[self loadDefaultStyle];


0 votes

I would like add checkbox to collapse/hide VerticalSliceModifier, but can’t find properties that do it.
Here is my code:

              <s:VerticalSliceModifier ShowTooltipOn = "MouseOver">
                        <s:VerticalLineAnnotation X1="{Binding VerticalLinePosition}" ShowLabel="True"   Stroke="White"/>
0 votes

I’m trying to clear a SCIUniformHeatmapDataSeries after connecting it to a SCIChartSurface, but it is very slow and energy consuming. However, if I clear the data series before it is connected to the sci chart, then the clearing is pretty fast. How can I clear the data series after it is connected to the chart surface quickly? Do I have to make a new data series, clear it, and connect to the scichartsurface every time I want to clear a data series? This is for iOS by the way.
EDIT: code

for i in 0..<data.MATRIX_COLUMNS {
        for j in 0..<data.MATRIX_ROWS  {
            data.ecm2DMatrix[i][j] = Double.nan
            SCIUpdateSuspender.usingWith(charts.ecmSurface) {
      [i][j], atX: i, y: j)
0 votes
0 answers

I am creating a chart to represent certain vitals. The code is almost identical to the Vitals Monitoring Demo application, the difference being
I added some Line and text annotations. I am appending points to the data series every 100ms. I have verified that the anomalous behavior is not caused due to wrong data being provided,
leading me to believe it must be a bug within SciChart. I have attached screenshots of this anomalous behavior. Any help would be greatly appreciated. Thank you.

Edit: This happens randomly, ie it performs normally without glitches on application startup but misbehaves after left running for a while.
I also observed that when I call .clear() on the XyDataSeries objects, the graph returns to normalcy, but only until FIFO_CAPACITY is reached. It then goes back to wreaking havoc.
I have added sample data (data.txt) to the question for reference, and screenshots of Expected behavior and the abnormal behavior in question.

Gif of the problem is here:

Code used for setting up the chart:

     `SciChartBuilder sciChartBuilder;
     static ISciChartSurface chart;
     public final static XyDataSeries<Double, Double> pressureDataSeries = newDataSeries(FIFO_CAPACITY);
     public final static XyDataSeries<Double, Double> pressureSweepDataSeries = newDataSeries(FIFO_CAPACITY);
     public final static XyDataSeries<Double, Double> flowDataSeries = newDataSeries(FIFO_CAPACITY);
     public final static XyDataSeries<Double, Double> flowSweepDataSeries = newDataSeries(FIFO_CAPACITY);
     public final static XyDataSeries<Double, Double> volumeDataSeries = newDataSeries(FIFO_CAPACITY);
     public final static XyDataSeries<Double, Double> volumeSweepDataSeries = newDataSeries(FIFO_CAPACITY);
     public final static XyDataSeries<Double, Double> lastPressureSweepDataSeries = newDataSeries(1);
     public final static XyDataSeries<Double, Double> lastFlowDataSeries = newDataSeries(1);
     public final static XyDataSeries<Double, Double> lastVolumeDataSeries = newDataSeries(1);
     private static XyDataSeries<Double, Double> newDataSeries(int fifoCapacity) {
    final XyDataSeries<Double, Double> ds = new XyDataSeries<>(Double.class, Double.class);
    return ds;
 private void setUpChart() {                          // Called from onCreate()
    try {
    } catch (Exception e) {
    final String pressureId = "pressureId";
    final String flowId = "flowId";
    final String volumeId = "volumeId";
    sciChartBuilder = SciChartBuilder.instance();
    chart = new SciChartSurface(this);
    LinearLayout chartLayout = findViewById(;
    chartLayout.addView((View) chart, 0);
    final NumericAxis xAxis = sciChartBuilder.newNumericAxis()
            .withVisibleRange(0, 10)

    DoubleValues pressureRange = new DoubleValues(); pressureRange.add(-10); pressureRange.add(65);
    DoubleValues flowRange = new DoubleValues(); flowRange.add(-150); flowRange.add(+250);
    DoubleValues volumeRange = new DoubleValues(); volumeRange.add(-500); volumeRange.add(1000);

    final NumericAxis yAxisPressure = generateYAxis(pressureId, getMinMaxRange(pressureRange));
    final NumericAxis yAxisFlow = generateYAxis(flowId, getMinMaxRange(flowRange));
    final NumericAxis yAxisVolume = generateYAxis(volumeId, getMinMaxRange(volumeRange));

    UpdateSuspender.using(chart, new Runnable() {
        public void run() {
                            .withFontStyle(18, ColorUtil.White)
                            .withText(" Pressure (cm H2O)")
                            .withFontStyle(18, ColorUtil.White)
                            .withText(" Flow (lpm)")
                            .withFontStyle(18, ColorUtil.White)
                            .withText(" Volume (ml)")
            Collections.addAll(chart.getXAxes(), xAxis);
            Collections.addAll(chart.getYAxes(), yAxisPressure, yAxisFlow, yAxisVolume);
                    MainActivity.this.generateLineSeries(pressureId, pressureDataSeries, sciChartBuilder.newPen().withColor(Color.parseColor("#00ff00")).withThickness(1.5f).build()),
                    MainActivity.this.generateLineSeries(pressureId, pressureSweepDataSeries, sciChartBuilder.newPen().withColor(Color.parseColor("#00ff00")).withThickness(1.5f).build()),
                    MainActivity.this.generateScatterForLastAppendedPoint(pressureId, lastPressureSweepDataSeries),

                    MainActivity.this.generateLineSeries(flowId, flowDataSeries, sciChartBuilder.newPen().withColor(Color.parseColor("#ff6600")).withThickness(1.5f).build()),
                    MainActivity.this.generateLineSeries(flowId, flowSweepDataSeries, sciChartBuilder.newPen().withColor(Color.parseColor("#ff6600")).withThickness(1.5f).build()),
                    MainActivity.this.generateScatterForLastAppendedPoint(flowId, lastFlowDataSeries),

                    MainActivity.this.generateLineSeries(volumeId, volumeDataSeries, sciChartBuilder.newPen().withColor(Color.parseColor("#FFEA00")).withThickness(1.5f).build()),
                    MainActivity.this.generateLineSeries(volumeId, volumeSweepDataSeries, sciChartBuilder.newPen().withColor(Color.parseColor("#FFEA00")).withThickness(1.5f).build()),
                    MainActivity.this.generateScatterForLastAppendedPoint(volumeId, lastVolumeDataSeries)
            chart.setLayoutManager(new DefaultLayoutManager.Builder().setRightOuterAxesLayoutStrategy(new RightAlignedOuterVerticallyStackedYAxisLayoutStrategy()).build());

private HorizontalLineAnnotation generateBaseLines(String yAxisId) {
    return sciChartBuilder.newHorizontalLineAnnotation().withStroke(1, ColorUtil.White).withHorizontalGravity(Gravity.FILL_HORIZONTAL).withXAxisId("XAxis").withYAxisId(yAxisId).withY1(0d).build();

private NumericAxis generateYAxis(String id, DoubleRange visibleRange) {
    return sciChartBuilder.newNumericAxis().withAxisId(id).withVisibleRange(visibleRange).withAutoRangeMode(AutoRange.Never).withDrawMajorBands(false).withDrawMinorGridLines(true).withDrawMajorGridLines(true).build();
private FastLineRenderableSeries generateLineSeries(String yAxisId, IDataSeries ds, PenStyle strokeStyle) {
    FastLineRenderableSeries lineSeries = new FastLineRenderableSeries();
    lineSeries.setPaletteProvider(new DimTracePaletteProvider());
    return lineSeries;
private IRenderableSeries generateScatterForLastAppendedPoint(String yAxisId, IDataSeries ds) {
    final EllipsePointMarker pm = sciChartBuilder.newPointMarker(new EllipsePointMarker())
            .withStroke(ColorUtil.White, 1f)

    return sciChartBuilder.newScatterSeries()

private static DoubleRange getMinMaxRange(DoubleValues values) {
    final DoubleRange range = new DoubleRange();
    SciListUtil.instance().minMax(values.getItemsArray(), 0, values.size(), range);
    range.growBy(0.1, 0.1);
    return range;

   // Appending to data series with:
    UpdateSuspender.using(MainActivity.chart, new Runnable() {
        public void run() {
            MainActivity.pressureDataSeries.append(x, ppA);
            MainActivity.pressureSweepDataSeries.append(x, ppB);

            MainActivity.flowDataSeries.append(x, vFlowA);
            MainActivity.flowSweepDataSeries.append(x, vFlowB);

            MainActivity.volumeDataSeries.append(x, vtfA);
            MainActivity.volumeSweepDataSeries.append(x, vtfB);

            MainActivity.lastPressureSweepDataSeries.append(x, pp);
            MainActivity.lastFlowDataSeries.append(x, vFlow);
            MainActivity.lastVolumeDataSeries.append(x, vtf);


0 votes
0 answers

Hello. When I try to add to curve some points with very small numbers:

curve.DataSeries = chartData;
chartData.Append(1, -6.525999992441564E-04);
chartData.Append(2, -6.5259999988724722E-04);
chartData.Append(3, -6.52599999843273E-04);
chartData.Append(4, -6.5259999970558607E-04);
chartData.Append(5, -6.5259999978135147E-04);

y axis not shown labels whatever Text Formatting property for this is. What I’m doing wrong? I noticed if I add points with -3 order of value, axis labels will show.
Surface description:

        <sc:FastLineRenderableSeries Name="curve"/>
        <sc:NumericAxis TextFormatting="E3" AutoRange="Always" x:Name="yAxis"/>
0 votes
0 answers


I am trying to make a chart that looks like the attached image.

All information and images are received dynamically and I have to draw it
(About 1,000 pieces of data are received per second, and I will update this on the chart.)

I’ve used XyScatterRenderableSeries and SpritePointMarker, but I could only draw one image

I want you to know how to approach

Please provide me some guide or tutorials.

Looking forward for your reply.


0 votes
0 answers

The issue I am running into is that when we hover over the plot, the tooltip does not represent the series that eventually becomes flagged as selected. This occurs when there are several line series grouped closely together.

I am using the default tooltip modifier together with a custom selection modifier.

I was wondering whether there is a way to obtain the tooltip information in our OnModifierMouseDown or somehow reconcile the hit testing of the tooltip modifier and our custom selection modifier (logic below). Our hit test radius is 9 because this seemed to be closest to the default tooltip hittest radius.

(Note our CustomSeriesSelectionModifier overrides ChartModifierBase. It does not override the default seriesselectionmodifier class because we found that it was not giving us adequate control over the selection rules)

Example scenario: Three curves grouped closely together. Hovering over them shows the tooltip for curve 3. Clicking selects curve 1 (even while the tooltip for curve 3 is still visible)

Thanks in advance

public class CustomSeriesSelectionModifier : ChartModifierBase
    public CustomSeriesSelectionModifier()
    : base()
        ReceiveHandledEvents = true;

    public override void OnModifierMouseDown( ModifierMouseArgs e )
        base.OnModifierMouseDown( e );

        var point = GetPointRelativeTo( e.MousePoint, ModifierSurface );

        Vector smallestDifference = new Vector( double.MaxValue, double.MaxValue );
        IRenderableSeries hitSeries = null;

        foreach ( var series in this.ParentSurface.RenderableSeries )
            var hitTest = series.HitTest( point, 9.0 );
            if ( hitTest.IsHit )
                Vector diff = Point.Subtract( point, hitTest.HitTestPoint );

                if ( smallestDifference.Length > diff.Length )
                    smallestDifference =  diff ;
                    hitSeries = series;

        if ( hitSeries != null )
            // do custom selection stuff

  • John Chow asked 4 weeks ago
  • last active 4 weeks ago
0 votes

Hello Everybody,

I have to continue a Xamarin.Forms application that mainly target android devices. The developer before me wrote everything in shared code and the question is:

Is it possible the use SciChart Xamarin chart in shared code in xaml or I have to code it in Xamarin.Android project?

I am new to Xamarin and just learning the things.
Thanks for the answers and any advice.


0 votes

On a small PC with only Intel HD Graphics 4600 the DirectX rendering is not supported by SciChart. Thats fine but it should use the fallback render surface.

  RenderPriority ="Low"
  s:VisualXcceleratorEngine.FallbackType="{x:Type s:HighQualityRenderSurface}"

I got this exception:

    System.Exception: Your GPU is blacklisted for use by the Visual Xccelerator Engine! There are several reasons why a GPU could belong to the blacklist. For example, low computation capabilities of the GPU could cause Timeout Detection and Recovery of Graphics Adapter Drivers by the OS, resulting in crashing the application.
   at SciChart.Charting.VisualXcceleratorEngine.ivc(DependencyObject t, DependencyPropertyChangedEventArgs u)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)

But it should use HighQualityRenderSurface without any exception.

  • Tobias asked 1 month ago
  • last active 1 month ago
0 votes

I am using RenderSurfaceGL in my chart but I am not able to use Transparency.
What should I do to do this?

0 votes

I would like to change the color of chart legend, but have failed to find information on how can I do this for iOS. Any sort of tutorial would be highly appreciated.

Worst case scenario would be to create a custom theme that is based on Bright Spark theme and update legend parameters there, but for this I would need to know what exactly does Bright Spark theme looks like.

Looking forward to any recommendations.

Best Regards,

0 votes

Hello Everyone,

I have set up a few annotations in my project and set their visibility to hidden.
I am displaying only the selected one from a combobox I have set up for the user.
But each time the chart does ZoomExtents. all the annotations appear and their visibility resets to visible.
Is this intentional?
Can I disable this option?

Thank you in advance.

0 votes


I have multiple custom chart modifiers (PinchZoom, Rollover, SeriesSelection and ZoomPan) and I was wondering if there is a set order in which they handle the touch event or is it random? If there is a set order then can I change this order?

For example now it seems like the rollover modifier handles the touch event before the seriesSelection modifier. This is a bit problematic since the rollover has sourceMode = SourceMode.SelectedSeries and since the touch event goes first to the rollover it updates its position –> then the new series is selected –> but rollover position does not update since it has already handled the touch event.

0 votes

Hi, i am trying to read an excel file which contains a few column of data to be plotted. The number of series depends on number of column in the excel file. Hence, the number of series need to be plotted dynamically. Besides, for each series, the data in not plotted in one shot. There is a timer used to plot each data point dynamically.

I am trying to use “ObservableCollection” in this case, i able to create the fastlinerenderableseries and XyDataSeries for each line series and add them into the ObservableCollection. However, i do not know how to have the real time update on each line series.

Please provide me some guide or tutorials.
Looking forward for your reply.

  • mian ooi asked 1 month ago
  • last active 1 month ago
0 votes
0 answers

I am trying to use IExtremeRenderContext2D.DrawColoredSprites method to draw my custom series, this is a simplified example:

public class MyCustomSeries2 : CustomRenderableSeries
    private readonly WriteableBitmap _bmp;

    public MyCustomSeries2()
        _bmp = new WriteableBitmap(5, 5, 96, 96, PixelFormats.Bgra32, null);

        _bmp.SetPixel(0, 0, Colors.White);
        _bmp.SetPixel(1, 1, Colors.White);
        _bmp.SetPixel(2, 2, Colors.White);
        _bmp.SetPixel(3, 3, Colors.White);
        _bmp.SetPixel(4, 4, Colors.White);

        _bmp.SetPixel(4, 0, Colors.White);
        _bmp.SetPixel(3, 1, Colors.White);
        _bmp.SetPixel(2, 2, Colors.White);
        _bmp.SetPixel(1, 3, Colors.White);
        _bmp.SetPixel(0, 4, Colors.White);

    protected override bool GetIsValidForDrawing()
        return true;

    protected override void Draw(IRenderContext2D renderContext, IRenderPassData renderPassData)
        var extremeRenderContext = renderContext.AsExtremeRenderContext();

        if (extremeRenderContext != null)
            var sprite = renderContext.CreateSprite(_bmp);
            extremeRenderContext.DrawColoredSprites(sprite, new[] {new ColoredVertex {ColorArgb = Colors.White.ToInt(), X = 100, Y = 100}}, 0, 1);

So I would expect to see a pixel-perfect cross with sharp edges etc. But it renders as a smoothed mess instead.
How can I make it draw my sprites pixel-to-pixel?


0 votes
0 answers

My app is composed of tiles that shows charts created dynamically, each creats its own legendModifier like below

var legendModifier = new LegendModifier()
ShowLegend = true,
IsEnabled = true,
LegendPlacement = LegendPlacement.Inside,
Orientation = System.Windows.Controls.Orientation.Vertical,
Margin = new System.Windows.Thickness(3),
ShowVisibilityCheckboxes = true,

It shows up fine first time, if I created a second chart if I use same dataset, legend is fine in this second chart, but if I use different data in third chart, the legend won’t show up, even if I create a fourth chart chart with same data as the first chart, the legend still doesn’t show up. Attached image, thanks.

0 votes


I have two questions about how to get axes or annotations by ID.

First, I trying to update the VisibleRange for X axis in the internalUpdate function in the UniformHeatmapSeriesTooltip. When I use getAxisById, my ECG data series is gone from the chart. But it works if I use getDefault() instead (axis Id not defined). So I kind of confused.

private class CustomHeatmapTooltip extends UniformHeatmapSeriesTooltip {

        public CustomHeatmapTooltip(Context context, UniformHeatmapSeriesInfo heatmapInfo) {
            super(context, heatmapInfo);
        protected void internalUpdate(UniformHeatmapSeriesInfo heatmapInfo) {
            ecgSurface.getXAxes().getAxisById("ecgx").setVisibleRange(new DateRange(startDate, stopDate));

Second, I have one vertical line annotation and multiple text annotations. Every time I render the heatmap, I want to remove the text annotations and add some new text annotations as needed, without touching the vertical line annotation. Is there a way to only remove the text annotations?

Thanks a lot.

  • Gang Xu asked 1 month ago
  • last active 1 month ago
0 votes

Hi guys,

I’m currently evaluating SciChart on iOS using Swift. It seems to have an excellent level of customisation and is almost a drop-in fit for what were are looking for.

I’m creating a timeline chart of candlesticks which the user can pan through. However while the zooming of the Y axis keeps the candles nicely in frame, the zoom snaps into place instantly as the pan happens which is very disorienting. Searching the docs, I cannot see a way to cause a smooth animation as the chart automatically zooms in and out.

This is probably the only thing that we really need to do to make this product work for us so hopefully there is an answer to solve this for us!

Thanks in advance!

0 votes


We have an app where we need to specify a different width for each column. I have attached an image of the result we want. We are currently using “SCIFastColumnRenderableSeries” for the diagram, but all columns have a fixed width and I couldn’t find any way to modify it.

Do you have any suggestions how to accomplish this?


0 votes


I tried to implement a colormap view next to the heatmap chart. But couldn’t figure out how to set it up. It seems like it won’t work this way.

SciChartHeatmapColourMap colorMapView = new SciChartHeatmapColourMap(this);

I don’t know how Bindview works in the example code. Could you tell me how to link SciChartHeatmapColourMap to the view in layout xml?


  • Gang Xu asked 2 months ago
  • last active 2 months ago
0 votes
0 answers

Dear SciChart Team:

I have a time chart of an oscilloscope application, and new values will be added to the curve over time.

I hope that after adjusting the scales of the X-axis and Y-axis, you can use this perspective to view the canvas, and like AutoRangeType.Always, you can watch the newly added values, but will not change the scale of the X-axis and Y-axis.

Is there any way to achieve this function? Thanks for your suggestion.

0 votes

Hello, I’m looking to do something similar to your example titled “WPF Chart Vertically Stacked YAxis”, but I’d like to be able to hide a data series and associated axis based on check boxes, and have the remainder of the series fill the empty space.

Do you have any example of something like this?


0 votes

I have a line chart using an XYDataSeries<DateTime, double> and set the FifoCapacity on the data series to 600. I am sampling the data at a sample rate of 100 ms, which equates to 1 minute of data. When I set the visible range to 2 minutes I can see more data then 1 minute’s worth. In fact, the data series actually has about 1080 points in it. I have verified that the FifoCapacity is in fact 600 on the series.

As new data comes in it is being appended:

_dataSeries.Append(valueSample.Time, valueSample.Value);

Does the chart only overwrite old data if memory constraints require it to? Not sure what is going on.

0 votes


I’d like to set line chart’s date xAxis ticks to be exactly one day apart in a way that where the label is shown, the time would be exactly 24:00.
I know I can set the minorDelta() and majorDelta(), but what value should I provide them? The minor tick when I zoom in should be 2 minutes and the major tick should be 24 hours.

0 votes


I tried to initialize heatmap chart with NaN to make it transparent, but it doesn’t work that way. The color was blue, which is zero in the colormap. Is there a way to make it not showing any color?


public void initECMSciChart() {
    // initialize chart with NaN
    for (int i = 0; i < MATRIX_COLUMNS; i++) {
        for (int j = 0; j < MATRIX_ROWS; j++) {
            heatmap2DMatrix[i][j] = 0;
            heatmapDataSeries.updateZAt(i, j, Double.NaN);
  • Gang Xu asked 2 months ago
  • last active 2 months ago
0 votes


I’m wondering is there a way to temporarily disable zoompan modifier while I re-rendering the chart. My re-rendering on the heatmap might take a second, I hope the interaction can be disabled during that process.

  • Gang Xu asked 2 months ago
  • last active 2 months ago
0 votes

I am evaluating Scichart for high speed real time application. According to ‘Performance tips and tricks’, I enabled VisualXcceleratorEngine in my ScichartSurface. My application was working pretty well when I was using Scichart version 6.0. But when I upgraded it to Scichart version 6.1, my application was crashed every time I run it. I have to disable DirectX engine to run my application.

It seems there is a problem with this file:

Any thought here?

0 votes


I am using Scichart 6.1 in WPF application. I want to access ScichartSurface in my view model to call some commands like ZoomExtentsModifier or SuspandUpdate. So I created all controls like surface, Axis, Series and annotations in my code according to your example ‘Creating your First SciChartSurface’.
My question is how can I attach this view model to my view [*.xaml file] ? I couldn’t find any example of xaml file in this case.


0 votes

I have a ECG chart with a certain capacity.
I want to apply the fading animation to the part of the chart that is being cleared.

0 votes


I have a surface with two x-axes and one y-axis. I am plotting 2 lines, which both have a numerical axis for their x-axis. I would like to be able to pan the lines so that I can align them for further analysis. However, I want the scaling on the two x-axes to stay identical. I have implemented the panning, which was straight forward using the XAxisDragModifier DragMode=”Pan”, so that is sorted. However, the scaling on the two axes is not identical, as each of the two lines have values for different x-ranges. This means that when I overlay them, one is more stretched out relative to the other.

Is there a way to lock the scaling for x-axes? See image below, I would like the red lines to be in sync, and equally big. So that 5 cm on the first x-axis is an equal amount of time as 5 cm on the second x-axis

Thank you,

Showing 1 - 50 of 3k results