Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The chart gets cut off and the rest stays white when scrolling programmatically. #5473

Open
a7asoft opened this issue Sep 9, 2024 · 0 comments

Comments

@a7asoft
Copy link

a7asoft commented Sep 9, 2024

I want to synchronize the scrolling of a RecyclerView with a LineChart, but I'm having issues. When the chart is scrolled to a part that is not initially visible, it simply shows as blank.

I'm using version 3.1.0.

RecyclerView scroll:

binding.rvDaysDetails.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
    binding.chart1.scrollBy(scrollX - oldScrollX, scrollY - oldScrollY);
    binding.chart1.notifyDataSetChanged();
    binding.chart1.invalidate();
});

LineGraph scroll:

lineChart.setOnChartGestureListener(new OnChartGestureListener() {
    @Override
    public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {}

    @Override
    public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {}

    @Override
    public void onChartLongPressed(MotionEvent me) {}

    @Override
    public void onChartDoubleTapped(MotionEvent me) {}

    @Override
    public void onChartSingleTapped(MotionEvent me) {}

    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {}

    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {}

    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {
        binding.rvDaysDetails.scrollBy((int) -dX, (int) -dY);
        lineChart.notifyDataSetChanged();
        lineChart.invalidate();
    }
});

The scrolling works fine, the only issue is that the chart gets cut off.

This is my whole graph code:

public void setLineChartData(LineChart lineChart) {
        float density = getDensity();

        lineValues = generateData();
        LineDataSet lineDataSet = new LineDataSet(lineValues, "");

        lineDataSet.setColor(getResources().getColor(R.color.grey_line));
        lineDataSet.setDrawCircles(true);
        lineDataSet.setCircleColor(Color.BLACK);
        lineDataSet.setCircleRadius(3f);
        lineDataSet.setCircleHoleRadius(3f);
        lineDataSet.setDrawFilled(false);
        lineDataSet.setDrawValues(false);
        lineDataSet.setMode(LineDataSet.Mode.LINEAR);

        LineData data = new LineData(lineDataSet);
        lineChart.setData(data);
        lineChart.getDescription().setEnabled(false);
        lineChart.getLegend().setEnabled(false);

        XAxis xAxisTop = lineChart.getXAxis();
        xAxisTop.setPosition(XAxis.XAxisPosition.TOP);
        xAxisTop.setDrawLabels(true);
        xAxisTop.setDrawGridLines(false);
        xAxisTop.setDrawAxisLine(false);
        xAxisTop.setGranularity(10f);
        xAxisTop.setSpaceMin(5f);
        xAxisTop.setSpaceMax(5f);
        xAxisTop.setTextSize(10f);

        xAxisTop.setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value) {
                int index = (int) (value / 10);
                if (index >= 0 && index < lineValues.size()) {
                    return String.format(Locale.getDefault(), "%.1f°C", lineValues.get(index).getY());
                }
                return "";
            }
        });

        lineChart.setExtraLeftOffset(0f);
        lineChart.setExtraRightOffset(0f);
        lineChart.setExtraTopOffset(15f);
        lineChart.setExtraBottomOffset(0f);

        YAxis yAxisLeft = lineChart.getAxisLeft();
        yAxisLeft.setDrawLabels(false);
        yAxisLeft.setDrawGridLines(false);
        yAxisLeft.setDrawAxisLine(false);
        yAxisLeft.setDrawLimitLinesBehindData(true);
        yAxisLeft.setEnabled(true);

        float minY = yAxisLeft.getAxisMinimum();
        float maxY = yAxisLeft.getAxisMaximum();

        float interval = (maxY - minY) / 12;

        for (int i = 0; i <= 12; i++) {
            LimitLine limitLine = new LimitLine(minY + i * interval, "");
            if (i == 6) {
                limitLine.setLineColor(ContextCompat.getColor(requireContext(), R.color.day_blue));
                limitLine.setLineWidth(1f);
            } else {
                limitLine.setLineColor(ContextCompat.getColor(requireContext(), R.color.grey_details));
                limitLine.setLineWidth(0.5f);
            }
            yAxisLeft.addLimitLine(limitLine);
        }

        YAxis yAxisRight = lineChart.getAxisRight();
        yAxisRight.setEnabled(false);

        lineChart.setDrawBorders(false);
        lineChart.setBackgroundColor(getResources().getColor(R.color.white));
        lineChart.setScaleEnabled(false);
        lineChart.setDragEnabled(true);

        float referenceDensity = 2.0f;
        float referenceVisibleXRange = 46.7f;

        float slope = 16.08f;
        float adjustedVisibleXRange = referenceVisibleXRange + (slope * (density - referenceDensity));

        lineChart.setVisibleXRangeMaximum(adjustedVisibleXRange);
        lineChart.setVisibleXRangeMinimum(adjustedVisibleXRange);
        lineChart.setViewPortOffsets(0f, 40f, 0f, 0f);

        lineChart.animateXY(250, 250, Easing.EaseInCubic);
        lineChart.moveViewToX(-5f);

        lineChart.setOnChartGestureListener(new OnChartGestureListener() {
            @Override
            public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
                scrollingChart = true;
            }

            @Override
            public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
                scrollingChart = false;
            }

            @Override
            public void onChartLongPressed(MotionEvent me) {
            }

            @Override
            public void onChartDoubleTapped(MotionEvent me) {
            }

            @Override
            public void onChartSingleTapped(MotionEvent me) {
            }

            @Override
            public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
            }

            @Override
            public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
            }

            @Override
            public void onChartTranslate(MotionEvent me, float dX, float dY) {
                binding.rvDaysDetails.scrollBy((int) -dX, (int) -dY);
                lineChart.notifyDataSetChanged();
                lineChart.invalidate();
            }
        });
    }

Example1 -> Before scroll.
Example2 -> After scroll.
example1
example2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant