MPAndroidChart自定义标记有时不显示

时间:2018-09-04 15:56:01

标签: android mpandroidchart

我有一个BarChart,在点击指标时会填充它。此外,此BarChart具有自定义标记,我不了解原因,但有时可行,有时不可行。 (Check the video)。似乎图表未正确失效。

包含图表(XML)的片段代码。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingBottom="@dimen/workout_summary_expand_collapse_container_padding_bottom"
    android:clipChildren="false"
    android:clipToPadding="false">

    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/workout_summary_premium_metrics_detail_bar_chart"
        android:layout_width="match_parent"
        android:layout_height="@dimen/workout_detail_bar_chart_height"
        android:layout_marginTop="10dp"
        android:background="@drawable/background_detail_sub_section_card"
        android:layout_marginStart="@dimen/workout_summary_premium_margin"
        android:layout_marginEnd="@dimen/workout_summary_premium_margin"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:visibility="gone"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/workout_summary_premium_metrics_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp" />
</LinearLayout>

包含图表的片段代码。

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

private void setUpChart() {
    int colorGray = ContextCompat.getColor(getActivity(), R.color.gray_chart_dash);
    Typeface typeface = FontUtil.getTypeface(getContext(), FontUtil.CHART_FONT);

    barChart.getLegend().setEnabled(false);
    Description description = new Description();
    description.setText("");
    barChart.setDescription(description);
    barChart.getAxisRight().setEnabled(false);
    barChart.getAxisLeft().setTypeface(typeface);
    barChart.getAxisLeft().setTextColor(colorGray);
    barChart.getAxisLeft().setGridColor(colorGray);
    barChart.getAxisLeft().setAxisLineColor(Color.TRANSPARENT);
    barChart.getXAxis().setAxisLineColor(Color.TRANSPARENT);
    barChart.getXAxis().setGridColor(ContextCompat.getColor(getActivity(), R.color.gray_chart_dash));
    barChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
    barChart.getXAxis().setTypeface(typeface);
    barChart.getXAxis().setTextColor(colorGray);
    barChart.getXAxis().setGranularity(1f);
    barChart.setNoDataTextColor(ContextCompat.getColor(getContext(), R.color.defaultTextColor));
    barChart.setNoDataTextTypeface(typeface);
    barChart.setExtraOffsets(0f, 35f, 0, 10f);

    //setup custom marker
    barChart.setMarker(new CustomChartMarkerView(getContext(), R.layout.custom_chart_marker_view,
            R.drawable.background_meditation_chart_text, R.color.defaultBackgroundAlpha, barChart, true, true, false));

    barChart.setHighlightPerTapEnabled(true);
    barChart.setHighlightPerDragEnabled(true);
    barChart.setTouchEnabled(true);
    barChart.setPinchZoom(false);
    barChart.setScaleEnabled(false);
    barChart.setDoubleTapToZoomEnabled(false);
    barChart.setDrawMarkers(true);
}

@Override
public void onWorkoutSummaryItemSelected(@NonNull WorkoutSummaryItem item) {
    resetChart();
    BarData barData = new BarData();
    barData.setBarWidth(Constants.BAR_SMALL_WIDTH);

    if (!item.entries.isEmpty()) {
        BarDataSet dataSet = new BarDataSet(item.entries, null);
        dataSet.setColor(ContextCompat.getColor(getContext(), R.color.workout_summary_item_selected));
        dataSet.setDrawValues(false);
        dataSet.setDrawIcons(false);
        dataSet.setHighLightColor(ContextCompat.getColor(getContext(), R.color.defaultTextColor));
        dataSet.setHighLightAlpha(255);
        dataSet.setHighlightEnabled(true);

        barChart.getXAxis().setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                SimpleDateFormat dateFormat;
                DateTime date;
                if (granularity == GetWorkoutSummaryRequest.SummaryGranularity.Year) {
                    dateFormat = DATE_FORMAT_X_AXIS_MONTH;
                    date = TimeUtils.fromMonthsBetweenEpoch((int) value);
                } else {
                    dateFormat = DATE_FORMAT_X_AXIS_DAY;
                    date = TimeUtils.fromDaysBetweenEpoch((int) value);
                }
                return dateFormat.format(date.toDate());
            }
        });

        barChart.getAxisLeft().setAxisMaximum(dataSet.getYMax() + 5);
        ((CustomChartMarkerView) barChart.getMarker()).setBottomUnit(item.unit);
        barData.addDataSet(dataSet);
    }

    barChart.setData(barData);
    barChart.animateXY(0, Constants.ANIMATION_DURATION);
    barChart.invalidate();
}

private void resetChart() {
    barChart.highlightValue(null);
    barChart.clear();
    barChart.fitScreen();
    if (barChart.getData() != null) {
        barChart.getData().clearValues();
    }
    barChart.getXAxis().setValueFormatter(null);
    barChart.notifyDataSetChanged();
    barChart.invalidate();
}

CustomMarker代码。

public class CustomChartMarkerView extends MarkerView {

    public static final String MARKER_TYPE_TIMESTAMP = "timestamp";
    public static final String MARKER_TYPE_MINUTES = "minutes";
    public static final String MARKER_TYPE_SECONDS = "seconds";
    public static final String MARKER_TYPE_HOURS = "hours";
    public static final String MARKER_TYPE_WEEK_MONTH_YEAR = "week_month_year";
    public static final String MARKER_TYPE_MINUTES_FROM_EPOCH = "minutes_from_epoch";

    private CustomTextView topLabel;
    private CustomTextView bottomLabel;
    private String topUnit;
    private String bottomUnit;
    private boolean useAxisXFormatter = false;
    private boolean useAxisYFormatter = false;
    private boolean hasBringToFront = false;
    private long extraTimestampOffset = 0; //Hack for meditations activity charts
    private String extraTopUnitTextInfo = ""; //Hack workout details charts
    private String extraBottomUnitTextInfo = ""; //Hack workout details charts
    private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("hh:mm a", Locale.getDefault());
    private final SimpleDateFormat DATE_FORMAT_WEEK_MONTH_YEAR = new SimpleDateFormat("MMM d", Locale.getDefault());

    public CustomChartMarkerView(Context context, @LayoutRes int layoutResource,
                                 @DrawableRes int backgroundRes, @ColorRes int textColor,
                                 String topUnit, String bottomUnit, Chart chart, boolean useAxisXFormatter,
                                 boolean useAxisYFormatter, boolean hasBringToFront) {

        super(context, layoutResource);

        this.useAxisXFormatter = useAxisXFormatter;
        this.useAxisYFormatter = useAxisYFormatter;
        this.hasBringToFront = hasBringToFront;

        this.topUnit = topUnit;
        this.bottomUnit = bottomUnit;

        setChartView(chart);
        setBackgroundResource(backgroundRes);

        topLabel = findViewById(R.id.chart_marker_view_top_label);
        bottomLabel = findViewById(R.id.chart_marker_view_bottom_label);

        topLabel.setTextColor(ContextCompat.getColor(context, textColor));
        bottomLabel.setTextColor(ContextCompat.getColor(context, textColor));
    }

    public CustomChartMarkerView(Context context, @LayoutRes int layoutResource,
                                 @DrawableRes int backgroundRes, @ColorRes int textColor,
                                 String topUnit, String bottomUnit, Chart chart) {
        this(context, layoutResource, backgroundRes, textColor, topUnit, bottomUnit, chart, false, false, false);
    }

    public CustomChartMarkerView(Context context, @LayoutRes int layoutResource,
                                 @DrawableRes int backgroundRes, @ColorRes int textColor, Chart chart, boolean useAxisXFormatter,
                                 boolean useAxisYFormatter, boolean hasBringToFront) {
        this(context, layoutResource, backgroundRes, textColor, "", "", chart, useAxisXFormatter, useAxisYFormatter, hasBringToFront);
    }

    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        switch (topUnit.toLowerCase()) {
            case MARKER_TYPE_WEEK_MONTH_YEAR:
                topLabel.setText(getFinalTextLeftUnit(DATE_FORMAT_WEEK_MONTH_YEAR.format(TimeUtils.fromDaysBetweenEpoch((int) e.getX()).toDate())));
                break;
            case MARKER_TYPE_TIMESTAMP:
                topLabel.setText(getFinalTextLeftUnit(DATE_FORMAT.format(new DateTime((int) e.getX() + extraTimestampOffset).toDate())));
                break;
            case MARKER_TYPE_MINUTES:
                topLabel.setText(getFinalTextLeftUnit(TimeUtils.formatSeconds((int) (e.getX() * 60))));
                break;
            case MARKER_TYPE_SECONDS:
                topLabel.setText(getFinalTextLeftUnit(TimeUtils.formatSeconds((int) (e.getX()))));
                break;
            case MARKER_TYPE_HOURS:
                topLabel.setText(getFinalTextLeftUnit(TimeUtils.formatSeconds((int) (e.getX() * 60 * 60))));
                break;
            case MARKER_TYPE_MINUTES_FROM_EPOCH:
                topLabel.setText(getFinalTextLeftUnit(DATE_FORMAT.format(TimeUtils.fromMinutesBetweenEpoch((int) e.getX()).toDate())));
                break;
            default:
                if (useAxisXFormatter && getChartView().getXAxis().getValueFormatter() != null) {
                    String label = getChartView().getXAxis().getValueFormatter().getFormattedValue(e.getX(), getChartView().getXAxis()).replaceAll("\n", " ");
                    topLabel.setText(getFinalTextLeftUnit(label));
                } else {
                    topLabel.setText(getFinalTextLeftUnit(Constants.DECIMAL_FORMAT_1.format(e.getX())));
                }
                break;
        }

        switch (bottomUnit.toLowerCase()) {
            case MARKER_TYPE_WEEK_MONTH_YEAR:
                bottomLabel.setText(getFinalTextRightUnit(DATE_FORMAT_WEEK_MONTH_YEAR.format(TimeUtils.fromDaysBetweenEpoch((int) e.getY()).toDate())));
                break;
            case MARKER_TYPE_TIMESTAMP:
                bottomLabel.setText(getFinalTextRightUnit(DATE_FORMAT.format(new DateTime((int) e.getY() + extraTimestampOffset).toDate())));
                break;
            case MARKER_TYPE_MINUTES:
                bottomLabel.setText(getFinalTextRightUnit(TimeUtils.formatSeconds((int) (e.getY() * 60))));
                break;
            case MARKER_TYPE_SECONDS:
                bottomLabel.setText(getFinalTextRightUnit(TimeUtils.formatSeconds((int) (e.getY()))));
                break;
            case MARKER_TYPE_HOURS:
                bottomLabel.setText(getFinalTextRightUnit(TimeUtils.formatSeconds((int) (e.getY() * 60 * 60))));
                break;
            case MARKER_TYPE_MINUTES_FROM_EPOCH:
                bottomLabel.setText(getFinalTextRightUnit(DATE_FORMAT.format(TimeUtils.fromMinutesBetweenEpoch((int) e.getY()).toDate())));
            default:
                if (useAxisYFormatter) {
                    if (getChartView() instanceof BarChart && ((BarChart) getChartView()).getAxisLeft().getValueFormatter() != null) {
                        AxisBase axis = ((BarChart) getChartView()).getAxisLeft();
                        String label = axis.getValueFormatter().getFormattedValue(e.getY(), axis);
                        bottomLabel.setText(getFinalTextRightUnit(label));
                    } else {
                        bottomLabel.setText(getFinalTextRightUnit(Constants.DECIMAL_FORMAT_1.format(e.getY())));
                    }
                } else {
                    bottomLabel.setText(getFinalTextRightUnit(Constants.DECIMAL_FORMAT_1.format(e.getY())));
                }
                break;
        }

        super.refreshContent(e, highlight);

        /*if (getChartView() instanceof BarChart) {
            setOffset(-getWidth() / 2, -getHeight() + getContext().getResources().getDimensionPixelSize(R.dimen.extra_offset_y_marker_bar));
        } else {
            setOffset(-getWidth() / 2, -highlight.getYPx());
        }*/

        setOffset(-getWidth() / 2, -highlight.getYPx());

        if (hasBringToFront) {
            getChartView().bringToFront();
        }
    }

    private String getFinalTextLeftUnit(String text) {
        StringBuilder builder = new StringBuilder(text.trim());
        if (StringUtils.isNotBlank(topUnit) && !isCustomMarkerUnit(topUnit.toLowerCase())) {
            builder.append(" ").append(topUnit.toUpperCase());
        }

        if (StringUtils.isNotBlank(getExtraTopUnitTextInfo())) {
            builder.append(" ").append(getExtraTopUnitTextInfo());
        }

        return builder.toString();
    }

    private boolean isCustomMarkerUnit(String unit) {
        return MARKER_TYPE_TIMESTAMP.equals(unit) ||
                MARKER_TYPE_MINUTES.equals(unit) ||
                MARKER_TYPE_SECONDS.equals(unit) ||
                MARKER_TYPE_HOURS.equals(unit) ||
                MARKER_TYPE_WEEK_MONTH_YEAR.equals(unit) ||
                MARKER_TYPE_MINUTES_FROM_EPOCH.equals(unit);
    }

    private String getFinalTextRightUnit(String text) {
        StringBuilder builder = new StringBuilder(text.trim());
        if (StringUtils.isNotBlank(bottomUnit) && !isCustomMarkerUnit(bottomUnit.toLowerCase())) {
            builder.append(" ").append(bottomUnit.toUpperCase());
        }

        if (StringUtils.isNotBlank(getExtraBottomUnitTextInfo())) {
            builder.append(" ").append(getExtraBottomUnitTextInfo());
        }

        return builder.toString();
    }

    @Override
    public void draw(Canvas canvas, float posX, float posY) {
        super.draw(canvas, posX, posY);
       getOffsetForDrawingAtPoint(posX, posY);
    }
  }

谢谢。

0 个答案:

没有答案