MPAndroidChart是实现图表功能的优秀控件, 能够完毕大多数绘制需求. 对于改动第三方库而言, 优秀的架构是继承开发, 而不是把源代码拆分出去. MP在显示标记控件(MarkView)时, 会有异常, 导致标志在图表边缘显示不全, 则须要重写控件解决这个问题.

继承LineChart, 提取高亮位置坐标getHighLightPos, 重绘标记drawMarkers.

/**
* 数据中心的图表折线图, 继承MPChart的折线图
* <p>
* Created by wangchenlong on 15/10/13.
*/
public class CYDataLineChart extends LineChart { @SuppressWarnings("unused")
private static final String TAG = "DEBUG-WCL: " + CYDataLineChart.class.getSimpleName(); // 默认构造器
public CYDataLineChart(Context context) {
super(context);
} public CYDataLineChart(Context context, AttributeSet attrs) {
super(context, attrs);
} public CYDataLineChart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} // 获取高亮点坐标
public float[] getHighLightPos(Entry e, Highlight highlight) {
return getMarkerPosition(e, highlight);
} // 重写这种方法, 修复Bug
@Override
protected void drawMarkers(Canvas canvas) { // if there is no marker view or drawing marker is disabled
if (mMarkerView == null || !mDrawMarkerViews || !valuesToHighlight())
return; Rect newRect = canvas.getClipBounds();
newRect.inset(-80, 0); //make the rect larger canvas.clipRect(newRect, Region.Op.REPLACE); //noinspection ForLoopReplaceableByForEach
for (int i = 0; i < mIndicesToHighlight.length; i++) { Highlight highlight = mIndicesToHighlight[i];
int xIndex = highlight.getXIndex(); if (xIndex <= mDeltaX && xIndex <= mDeltaX * mAnimator.getPhaseX()) { Entry e = mData.getEntryForHighlight(mIndicesToHighlight[i]); // make sure entry not null
if (e == null || e.getXIndex() != mIndicesToHighlight[i].getXIndex())
continue; float[] pos = getMarkerPosition(e, highlight); // Marker偏移
float tmpY = pos[1] - 8 * AppUtils.getPerDp(); Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setStrokeWidth(5); // noinspection deprecation
paint.setColor(getResources().getColor(R.color.chart_circle));
canvas.drawCircle(pos[0], pos[1], 2 * AppUtils.getPerDp(), paint); // check bounds
if (!mViewPortHandler.isInBounds(pos[0], tmpY))
continue; mMarkerView.refreshContent(e, highlight); mMarkerView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mMarkerView.layout(0, 0, mMarkerView.getMeasuredWidth(),
mMarkerView.getMeasuredHeight()); if (tmpY - mMarkerView.getHeight() <= 0) {
float y = mMarkerView.getHeight() - tmpY;
mMarkerView.draw(canvas, pos[0], tmpY + y);
} else {
mMarkerView.draw(canvas, pos[0], tmpY);
}
}
}
}
}

getMarkerPosition是LineChart类中的protected方法, 继承类, 使用public方法导出.

float tmpY = pos[1] - 8 * AppUtils.getPerDp();, 又一次计算Y坐标, 偏离原始画布.

可是这样做有一个问题, 在移动MarkView时, 父控件会有残留. 怎样解决呢?

办法就是在移动时, 重绘父控件的canvas, 使用invalidate()函数.

        // 设置图表点击事件, 监听高亮位置
mLcChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
int index = e.getXIndex();
Log.e(TAG, "index = " + index);
setChartIndex(index);
mCallback.setCurIndex(index);
mIndex = index; float[] pos = mLcChart.getHighLightPos(e, h);
Log.e(TAG, "x: " + pos[0] + ", y: " + pos[1]); mLlContainer.invalidate(); // 重绘父控件, 避免残留
} @Override
public void onNothingSelected() {
// 再次点击时调用这个, 要不非高亮
mLcChart.highlightValue(mIndex, 0);
}
});
    // 外部设置图表高亮
private void setChartHighlight(int index) {
if (mLcChart.getData() == null) return; mMarkerView.setDateText(mMarkers.get(index));
mLcChart.highlightValue(index, 0); mLlContainer.invalidate(); // 重绘父控件, 避免残留
}

在图表控件中, 内部外部都会触发高亮位置.

OK, Enjoy It!

重写MPAndroidChart显示标记的更多相关文章

  1. 2019.03.20 读书笔记 as is 以及重写隐式/显示

    强转.as is 的用法 强制转换类型有两种:子类转基类,重写隐式(implicit )\显示(explicit) 转换操作符 class myclass { private int value; p ...

  2. IIS-URL重写模块配置参考

    本文提供了URL重写模块的概述,并解释了该模块使用的配置概念. 功能概述URL重写模块将请求URL重写为显示给用户或Web应用程序的简单,用户友好和搜索引擎友好的地址.URL重写使用定义的规则进行评估 ...

  3. 【MyLocations】标记位置App开发体会

    实现功能: 1.能通过Cora Location获取地址信息 2.用户获取地址信息后能编辑相关信息 3.使用Core Data保存数据 4.使用MapKit,在Map上显示标记的位置,并可以编辑位置信 ...

  4. jquery.validate 以alert方式显示错误方法

    $.validator.setDefaults({ submitHandler: function() { alert("submitted!");return false; } ...

  5. html标记语言 --格式标记

    html标记语言 --格式标记 一.格式标记 1.<br>单标记,强制换行标记,让后面的文字.图片.表格等显示在下一行 2.<p>换段落标记 3.<center>居 ...

  6. android scrollview listview显示不全

    原来处理方法是重写ListView import android.content.Context; import android.util.AttributeSet; import android.v ...

  7. Html常用标记总结

    超文本标记语言的结构包括“头”部分(英语:Head).和“主体”部分(英语:body),其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容. Web页面绝大多数都是由html所编写的. 一 ...

  8. opencv+python视频实时质心显示

    利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...

  9. html相关标记的含义

    HTML标记含义1.<html>...</html> :html 文档标记2.<head>...</head> :文档头标记3.<title> ...

随机推荐

  1. Js原生实现抽奖功能

    <div>代码 按钮代码 JS原生代码  完整的代码: <div style="width:365px;height:300px;border:2px solid gree ...

  2. js获得 json对象的个数(长度)

    function getJsonObjLength(jsonObj) { var Length = 0; for (var item in jsonObj) { Length++; } return ...

  3. 05006_Linux的jdk、mysql、tomcat安装

    1.软件包下载链接:软件包下载 密码:advk 2.安装JDK (1)查看当前Linux系统是否已经安装java,输入 rpm -qa | grep java : (2)卸载两个openJDK (3) ...

  4. Eclipse删除多余工作空间

    选择perferences-->General -->Startup and Shutdown-->workspace-->选择多余的工作空间 -> remove -&g ...

  5. C#-入门思维导图

    C#-入门思维导图 百度云盘 链接:http://pan.baidu.com/s/1jI5zMS2 密码:0ypc 如有错误,请告知我

  6. Java7的那些新特性

    本文介绍的java 7新特性很多其它的感觉像是语法糖.毕竟java本身已经比較完好了.不完好的非常多比較难实现或者是依赖于某些底层(比如操作系统)的功能. 不过java7也实现了类似aio的强大功能. ...

  7. QQ在线人数统计图数据解析

    转载请注明出处:http://blog.csdn.net/xiaoy_h/article/details/27980851 我相信非常多人一定去过这个地方: http://im.qq.com/onli ...

  8. [CSS3] Create Dynamic Styles with CSS Variables

    In this lesson we are going to use CSS variables to keep our application's colors consistent. This i ...

  9. Binary Tree Inorder Traversal--leetcode

    原题链接:https://oj.leetcode.com/problems/binary-tree-inorder-traversal/ 题目大意:中序遍历二叉树 解题思路:中序遍历二叉树.中序遍历二 ...

  10. m_Orchestrate learning system---十五、如何快速查错

    m_Orchestrate learning system---十五.如何快速查错 一.总结 一句话总结: a.删除代码法 b.添加提示代码法 c.仔细看错误信息 1.评论板块和论坛板块的实时更新? ...