I have two line graphs that show complementary data over the same time period. Is there any way to send any touch events received by one graph to the other? I essentially want it so that the graphs always show the same viewing rectangle (at least on horizontally). So if a user swipes left 'n' units on the top graph, the bottom graph will automatically scroll left 'n' units to match.
Zooms can be done with the current MPAndroidChart release, for scrolling check out or wait for my extension to be merged: https://github.com/PhilJay/MPAndroidChart/pull/545
You need to set up an OnChartGestureListener on the master chart that copies the translation matrix values to the slave charts:
public class CoupleChartGestureListener implements OnChartGestureListener {
private Chart srcChart;
private Chart[] dstCharts;
public CoupleChartGestureListener(Chart srcChart, Chart[] dstCharts) {
this.srcChart = srcChart;
this.dstCharts = dstCharts;
}
[...other overrides...]
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
//Log.d(TAG, "onChartScale " + scaleX + "/" + scaleY + " X=" + me.getX() + "Y=" + me.getY());
syncCharts();
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
//Log.d(TAG, "onChartTranslate " + dX + "/" + dY + " X=" + me.getX() + "Y=" + me.getY());
syncCharts();
}
public void syncCharts() {
Matrix srcMatrix;
float[] srcVals = new float[9];
Matrix dstMatrix;
float[] dstVals = new float[9];
// get src chart translation matrix:
srcMatrix = srcChart.getViewPortHandler().getMatrixTouch();
srcMatrix.getValues(srcVals);
// apply X axis scaling and position to dst charts:
for (Chart dstChart : dstCharts) {
if (dstChart.getVisibility() == View.VISIBLE) {
dstMatrix = dstChart.getViewPortHandler().getMatrixTouch();
dstMatrix.getValues(dstVals);
dstVals[Matrix.MSCALE_X] = srcVals[Matrix.MSCALE_X];
dstVals[Matrix.MTRANS_X] = srcVals[Matrix.MTRANS_X];
dstMatrix.setValues(dstVals);
dstChart.getViewPortHandler().refresh(dstMatrix, dstChart, true);
}
}
}
}
Then set up your master/slave connections for example like this:
//
// Couple chart viewports:
//
tripChart.setOnChartGestureListener(new CoupleChartGestureListener(
tripChart, new Chart[] { powerChart, energyChart }));
powerChart.setOnChartGestureListener(new CoupleChartGestureListener(
powerChart, new Chart[] { tripChart, energyChart }));
energyChart.setOnChartGestureListener(new CoupleChartGestureListener(
energyChart, new Chart[] { tripChart, powerChart }));
You need add this to CoupleChartGestureListener
@Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
((BarLineChartTouchListener) srcChart.getOnTouchListener()).stopDeceleration();
for (Chart dstChart : dstCharts) {
if (dstChart.getVisibility() == View.VISIBLE) {
((BarLineChartTouchListener) dstChart.getOnTouchListener()).stopDeceleration();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With