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

0
0

I am working on CreateMultiPaneStockChartFragment example. Sometimes after I refresh data and call surface.zoomExtents(), the chart does not zoom to fit but stays the same. Why is this? I can then manually zoom to extents by double tapping the chart.

This is my (simplified) fragment code (stemming from the example but optimized for my case of regular updating) below. updateChart() is called periodically every 10 sec.

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    SciChartBuilder.init(getActivity());
    sciChartBuilder = SciChartBuilder.instance();
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    surface = view.findViewById(R.id.priceChart);
    initChart();
}

private void initChart(){
    final DefaultLayoutManager layoutManager = new DefaultLayoutManager.Builder().setRightOuterAxesLayoutStrategy(new RightAlignedOuterVerticallyStackedYAxisLayoutStrategy()).build();
    surface.setLayoutManager(layoutManager);

    final CategoryDateAxis xAxis = sciChartBuilder.newCategoryDateAxis()
        .withLabelProvider(new TradeChartAxisLabelProviderDateTime())
        .withAutoRangeMode(AutoRange.Once)
        .build();
    xAxis.setMinimalZoomConstrain(10d); // minimum data points

    surface.getXAxes().add(xAxis);

    final NumericAxis yAxisPrice = sciChartBuilder.newNumericAxis()
        .withAxisId(PRICES)
        .withAutoRangeMode(AutoRange.Always)
        .withGrowBy(new DoubleRange(0.01d, 0.01d))
        .withLabelProvider(new NumericLabelProviderPrice(coinCurrency))
        .build();
    yAxisPrice.setMinimalZoomConstrain(0d);
    surface.getYAxes().add(yAxisPrice);

    // add axes for MACD, RSI, VOL..


    legendModifier = sciChartBuilder.newModifierGroup()
        .withLegendModifier().withShowCheckBoxes(false).withShowSeriesMarkers(false).build()
        .build();
    // surface.getChartModifiers().add(legendModifier); // this causes crash; add it after series are present

    interactionModifiers = sciChartBuilder.newModifierGroup()
        .withPinchZoomModifier().withReceiveHandledEvents(true).withXyDirection(Direction2D.XDirection).build()
        .withZoomPanModifier().withReceiveHandledEvents(true).withClipModeX(ClipMode.ClipAtExtents).build()
        .withZoomExtentsModifier().withReceiveHandledEvents(true).build()
        .build();
    surface.getChartModifiers().add(interactionModifiers);

    cursorModifier = sciChartBuilder.newModifierGroup()
        .withCursorModifier().build()
        .build();
    cursorModifier.setIsEnabled(false);
    surface.getChartModifiers().add(cursorModifier);
}

private void updateChart(int daysToShow) {
    final PriceSeries priceData = getData(daysToShow);

    surface.getRenderableSeries().clear();
    surface.getAnnotations().clear();

    // price chart
    final OhlcDataSeries<Date, Double> stockPrices = sciChartBuilder.newOhlcDataSeries(Date.class, Double.class).withSeriesName(getString(R.string.price)).build();
    stockPrices.append(series.getDateData(), series.getOpenData(), series.getHighData(), series.getLowData(), series.getCloseData());
    final BaseRenderableSeries seriesOHLCV = sciChartBuilder.newCandlestickSeries().withDataSeries(stockPrices).withSeriesInfoProvider(new CustomOHLCSeriesInfoProvider()).withYAxisId(PRICES).build();
    surface.getRenderableSeries().add(seriesOHLCV);

    surface.getAnnotations().add(sciChartBuilder.newAxisMarkerAnnotation().withY1(stockPrices.getYValues().get(stockPrices.getCount()-1)).withBackgroundColor(Color.WHITE).withFontStyle(12, Color.BLACK).withYAxisId(PRICES).build());

    // do the same for MACD, RSI, VOL ...

    if(!surface.getChartModifiers().contains(legendModifier))
        surface.getChartModifiers().add(legendModifier); // this causes crash if added before any series is present

    if(!silent) {
        Log.d("debug", "surface.zoomExtents()");
        surface.zoomExtents(); // sometimes this does not work
    }
}
Version
2.2.1.2391
  • You must to post comments
0
0

Hi Primoz,

Without project which reproduce this issue it will be very hard to determine the cause of this issue because ZoomExtendsModifier uses zoomExtends() under the hood. So it’s probably some kind of race condition when you call zoomExtends() too soon when data isn’t updated yet or something like that.

Also it could be some exception so I would suggest you to check logcat output. Do you see any errors there?

Best regards,
Yura

  • Primoz
    Hi Yura! I’ve commented zoomExtentsModifier and the same still happens. Also there is no error or debug message in logcat regarding zoomExtents(). So all that happens is series and annotation is updated and zoomExtents() is called. Maybe at that time the min/max datarange is not yet calculated by SciChart internally so I should wait a few ms before calling this function? I found out the following answer (which is for WPF), but it has same issue. I didn’t find any beginInvoke function in Android though. See here: https://www.scichart.com/questions/question/mvvm-viewportmanager-zoomextents-doesnt-seem-to-work-as-expected
  • Primoz
    I also tried using UpdateSuspender when replacing the series and annotation and calling zoomExtents() at the end but the issue persists because the underlying cause is still there (no min max datarange calculated yet internally?).
  • Yura Khariton
    Can you modify one of our examples from demo app or provide a project which reproduces this issue so I could debug it on my PC?
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.