9

I am using MPandroidchart for showing line charts in my application.I have added following code to show Marker View, but it isn't showing on

private void initializeChart(LineChart chart, String chartName) {
    // Chart view
    chart.setDrawGridBackground(false);
    chart.setDescription("");
    chart.getLegend().setEnabled(true);
    //chart.setTouchEnabled(false);
    int color = getResources().getColor(R.color.white);
    chart.getAxisLeft().setTextColor(color); // left y-axis
    chart.getXAxis().setTextColor(color);

    chart.setTouchEnabled(true);
    CustomMarkerView mv = new CustomMarkerView(this.getActivity(), R.layout.marker_view_tv);
    chart.setMarkerView(mv);

    //X axis
    XAxis xAxis = chart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setDrawGridLines(false);
    xAxis.setDrawLabels(true);

    //Y axis
    YAxis leftAxis = chart.getAxisLeft();
    YAxis rightAxis = chart.getAxisRight();
    rightAxis.setDrawLabels(false);
    rightAxis.setDrawGridLines(false);
    leftAxis.setDrawLabels(true);
    leftAxis.setDrawGridLines(false);
    leftAxis.setStartAtZero(false);

    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());


    leftAxis.setLabelCount(Constants.KEY_LINE_YAXIS_SCALECOUNT, true);
    ChartItem item = CannonJsonParser.parseCanonJson(act, act.res);
    int maxYVal = pref.getInt(Constants.KEY_YAXIS_VALUE, 0);
    leftAxis.setAxisMaxValue(maxYVal);
    leftAxis.setAxisMinValue(0);
    setLineData(item, chartName);
    // set data
    chart.setData(lineData);

    chart.getLegend().setEnabled(false);
    //animate
    //chart.animateX(2000, Easing.EasingOption.EaseInExpo);
    chart.setDragEnabled(true);
    chart.setScaleXEnabled(true);
    chart.setScaleYEnabled(false);
    chart.setHighlightPerDragEnabled(false);
    chart.setHighlightPerTapEnabled(false);


}

My CustomMarkerView class

public class CustomMarkerView extends MarkerView {
private TextView tvContent;

public CustomMarkerView(Context context, int layoutResource) {
    super(context, layoutResource);

    tvContent = (TextView) findViewById(R.id.tvContent);
}

// callbacks everytime the MarkerView is redrawn, can be used to update the
// content (user-interface)
@Override
public void refreshContent(Entry e, Highlight highlight) {

    if (e instanceof CandleEntry) {

        CandleEntry ce = (CandleEntry) e;

        tvContent.setText("" + Utils.formatNumber(ce.getHigh(), 0, true));
    } else {

        tvContent.setText("" + Utils.formatNumber(e.getVal(), 0, true));
    }
}

@Override
public int getXOffset(float xpos) {
    // this will center the marker-view horizontally
    return -(getWidth() / 2);
}

@Override
public int getYOffset(float ypos) {
    // this will cause the marker-view to be above the selected value
    return -getHeight();
}

}

Note: I am using fragment to show charts.

Philipp Jahoda
  • 50,880
  • 24
  • 180
  • 187
musica
  • 1,373
  • 3
  • 15
  • 34
  • For some reason in version 3.1.0-alpha, if you're using `ConstraintLayout` with child's (`TextView`?) property as `match_constraint // represented as 0dp`. The marker doesn't even show. Make sure to give it a fixed width or `match_parent`. – Naveen Niraula Feb 17 '19 at 11:08

4 Answers4

10

Your MarkerView is not showing because you have not highlighted any entry in your chart. The MarkerView is only displayed for entries that are highlighted.

Since you disabled the functionality to highlight entries per tap (by calling chart.setHighlightPerTapEnabled(false)), you can only highlight values programmatically, like this:

chart.highlightValue(...)

More on that in the documentation.

Philipp Jahoda
  • 50,880
  • 24
  • 180
  • 187
  • In addition, if you are using Compose, you might need to setup a data and isHighlightEnabled in your update block – Hitrene Oct 07 '21 at 10:49
6

Faced a similar problem. You should call super to refresh markerview. Example on Kotlin:

 class CustomMarkerView(context: Context, layoutResource: Int) : MarkerView(context, layoutResource) {

    override fun refreshContent(e: Entry?, highlight: Highlight?) {
        markerDate.text = e?.data.toString()
        markerValue.text = e?.y.toString()
        super.refreshContent(e, highlight)
    }
}
Kroha
  • 168
  • 2
  • 9
2

try this, class

import android.content.Context;
import android.widget.TextView;

import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.CandleEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.utils.Utils;

/**
 * Custom implementation of the MarkerView.
 *
 * @author Philipp Jahoda
 */
public class MyMarkerView extends MarkerView {

    private TextView tvContent;

    public MyMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);

        tvContent = (TextView) findViewById(R.id.tvContent);
    }

    // callbacks everytime the MarkerView is redrawn, can be used to update the
    // content (user-interface)
    @Override
    public void refreshContent(Entry e, int dataSetIndex) {

        if (e instanceof CandleEntry) {

            CandleEntry ce = (CandleEntry) e;

            tvContent.setText("" + Utils.formatNumber(ce.getHigh(), 0, true));
        } else {

            tvContent.setText("" + Utils.formatNumber(e.getVal(), 0, true));
        }
    }

    @Override
    public int getXOffset() {
        // this will center the marker-view horizontally
        return -(getWidth() / 2);
    }

    @Override
    public int getYOffset() {
        // this will cause the marker-view to be above the selected value
        return -getHeight();
    }
}

And in Fragment Class, Add

        MyMarkerView mv = new MyMarkerView(this.getActivity(),    R.layout.custom_marker_view);

        // set the marker to the chart
        mChart.setMarkerView(mv);

May this helpful to you..

Amol Sawant
  • 13,842
  • 2
  • 20
  • 27
1

none of the previous answers worked for me, i found that when you fill the entries from higher to lowest in xAxis the marker don't appear and even other bugs may appear, something like this will cause the error

int countX = speedTest.size(); 
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < speedTests.size(); i++) {
    SpeedTest st = speedTests.get(i);
    yVals1.add(new BarEntry(countX,st.getResultFloat()));
    countX--;
}

for me, the only way to fix this was to fill the entries in xAxis from lowest to higher, so the next code worked for me after hours of debugging

int countX = 0;
ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
for (int i = 0; i < speedTests.size(); i++) {
    SpeedTest st = speedTests.get(i);
    yVals1.add(new BarEntry(countX,st.getResultFloat()));
    countX++;
}
karique
  • 533
  • 6
  • 17