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

0
1

Hello Friends ,

   Sync two Chart in Android Bottom chart can be change on top chart touch

We are looking a solution where we want show two chart at Top and Bottom in Android Screen.based on Top chart changed by gesture /finger touch should be expend/shrink like zoom in and out bottom chart

Assume at top chart data range has between 0 to 3,00,000 , I want to capture in bottom chart only selected/touched part in with expanded form.

I have attached below screen shot which may be helpful.

Solution can be like this but not able to get code for this implementation

https://blog.scichart.com/content/images/2021/06/Navigate-ECG-strip-with-Pocket-ECM.gif

https://blog.scichart.com/android-app-to-view-long-term-ecg-signals/

I appreciate any help regarding this issue.

Version
4.3.0.4660
Images
  • You must to post comments
0
0

Hi Vasim,

Well I think you can implement desired behavior by adding listener for top chart’s xAxis and changing VisibleRange of other bottom chart’s xAxis. Also I would suggest to take a look on Realtime Ticking Stock Chart example which has 2 charts, where one chart changes its state based on VisibleRange of other chart by using VisibleRangeChangeListener API.

Best regards,
Yura

  • Yura Khariton
    Well I understand that this isn’t exactly behavior that you’re trying to achieve. Example from link just a demonstration of how VisibleRangeListener API can be used to track changes in VisibleRange in one chart and based on this change update other chart. So in your case you’ll need need to add listener to xAxis of chart that you zoom, pan, and based on values received in listener update second chart
  • vasim simform
    Thank you for quick response I would request to you help me to provide more code which works for visible range listener code, As of now i can see only snippet code but couldn’t see actual implementation like passing touched (x,y) coordinate to next chart for panning and zooming
  • Yura Khariton
    OK, I probably misunderstood what you’re trying to achieve. I thought that one chart should be changed based on X range which is displayed by other chart. Could you provide more detailed description of how chart should react when something happens ( e.g. on gesture or adding new data )? It looks like you’re trying to achieve some complex behavior and in this case I can only give you links on documentation or examples which can be useful. If you need touch coordinates you’ll need to use ChartModifier API ( https://www.scichart.com/documentation/android/current/webframe.html#Custom%20Modifiers%20-%20ChartModifierBase%20API.html ), which is responsible for interaction with chart and override its onTouch() method to receive touch events from chart. Also here some useful links if you need to convert pixel coordinates to data coordinates (https://www.scichart.com/documentation/android/current/webframe.html#Axis%20APIs%20-%20Convert%20Pixel%20to%20Data%20Coordinates.html) or find data point from specific series ( https://www.scichart.com/example/android-chart-example-hit-test-api/ ).
  • vasim simform
    Hello Yura ,Thanks for quick response As you showed different ways to implementation for expected output but by doing this which takes enormous time to us which impacting to our business ,Although I couldn’t see your example with advance implementation , if we have to do this way then what’s benefits to purchase SciChart plan. Please I would request provide to more simple implementation technique Thanks
  • vasim simform
    Hello Yura Could you provide any other solution for above question?
0
0

Hi there,

I modified one of our examples to show to implement behavior from GIF that you attached before ( when you drag annotation on bottom chart this changes VisibleRange on top chart and when you pan top chart this changes position of line annotation on bottom chart ) :

public class SyncMultipleChartsFragment extends ExampleBaseFragment<ExampleSyncMultipleChartsFragmentBinding> {
    private final static int POINTS_COUNT = 500;
    private final static double RANGE_WINDOW = 5d;

    private final DoubleRange topXRange = new DoubleRange();

    @Override
    public boolean showDefaultModifiersInToolbar() { return false; }

    @Override
    protected ExampleSyncMultipleChartsFragmentBinding inflateBinding(LayoutInflater inflater) {
        return ExampleSyncMultipleChartsFragmentBinding.inflate(inflater);
    }

    @Override
    protected void initExample(ExampleSyncMultipleChartsFragmentBinding binding) {
        initBottomChart(binding.chart1);
        initTopChart(binding.chart0);
    }

    private void initTopChart(final SciChartSurface surface) {
        final IAxis xAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).withVisibleRange(topXRange).withAutoRangeMode(AutoRange.Never).build();
        final IAxis yAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).withAutoRangeMode(AutoRange.Always).build();

        final FastLineRenderableSeries line = sciChartBuilder.newLineSeries().withDataSeries(createDataSeries()).withStrokeStyle(ColorUtil.Green, 1f, true).build();

        UpdateSuspender.using(surface, new Runnable() {
            @Override
            public void run() {
                Collections.addAll(surface.getXAxes(), xAxis);
                Collections.addAll(surface.getYAxes(), yAxis);
                Collections.addAll(surface.getRenderableSeries(), line);
                Collections.addAll(surface.getChartModifiers(), sciChartBuilder.newModifierGroupWithDefaultModifiers().build());
            }
        });

    }

    private void initBottomChart(final SciChartSurface surface) {
        final IAxis xAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).withAutoRangeMode(AutoRange.Always).build();
        final IAxis yAxis = sciChartBuilder.newNumericAxis().withGrowBy(0.1d, 0.1d).withAutoRangeMode(AutoRange.Always).build();

        final FastLineRenderableSeries line = sciChartBuilder.newLineSeries().withDataSeries(createDataSeries()).withStrokeStyle(ColorUtil.Green, 1f, true).build();

        final double initialValue = 5d;
        VerticalLineAnnotation lineAnnotation = sciChartBuilder.newVerticalLineAnnotation()
                .withStroke(5f, Color.RED)
                .withX1(initialValue)
                .withIsEditable(true)
                .withAnnotationLabel(LabelPlacement.Axis)
                .build();
        topXRange.setMinMaxDouble(initialValue - RANGE_WINDOW, initialValue + RANGE_WINDOW);

        topXRange.addRangeChangeObserver(new IRangeChangeObserver<Double>() {
            @Override
            public void onRangeChanged(Double oldMin, Double oldMax, Double newMin, Double newMax, int changedProperty) {
                lineAnnotation.setX1((newMax + newMin) / 2d); // update position of annotation when range changes
            }
        });

        lineAnnotation.setOnAnnotationDragListener(new OnAnnotationDragListener() {
            @Override
            public void onDragStarted(IAnnotation annotation) {

            }

            @Override
            public void onDragEnded(IAnnotation annotation) {

            }

            @Override
            public void onDragDelta(IAnnotation annotation, float horizontalOffset, float verticalOffset) {
                final double xValue = ComparableUtil.toDouble(annotation.getX1());

                // update X range of top axis when dragging line annotation 
                topXRange.setMinMaxDouble(xValue - RANGE_WINDOW, xValue + RANGE_WINDOW);
            }
        });

        UpdateSuspender.using(surface, new Runnable() {
            @Override
            public void run() {
                Collections.addAll(surface.getXAxes(), xAxis);
                Collections.addAll(surface.getYAxes(), yAxis);
                Collections.addAll(surface.getRenderableSeries(), line);
                Collections.addAll(surface.getAnnotations(), lineAnnotation);
            }
        });

    }

    private IDataSeries createDataSeries() {
        IXyDataSeries<Double, Double> dataSeries = new XyDataSeries<>(Double.class, Double.class);

        for (int i = 1; i < POINTS_COUNT; i++) {
            dataSeries.append((double) i, POINTS_COUNT * Math.sin(i * Math.PI * 0.1) / i);
        }

        return dataSeries;
    }
}

Hope this will help you!

Best regards,
Yura

  • vasim simform
    Hello Yura Thank you for quick response. It seems suitable solution , We can follow you code . One suggestion please explore this kind of example over your tutorial destination. Once again Thank you.
  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.