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. [terry笔记]学校管理系统

    如下是要求: # 角色:学校.学员.课程.讲师# 要求:# 1. 创建北京.上海 2 所学校# 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上 ...

  2. linux mint(Ubuntu、Debian) 18修改环境变量

    修改环境变量 sudo gedit /etc/profile sudo gedit /etc/profile 在profile文件的末尾添加以下代码 export JAVA_HOME=/usr/lib ...

  3. jquery mobile常用的data-role类型介绍

    转自原文 jquery mobile常用的data-role类型介绍 data-role参数表: page        页面容器,其内部的mobile元素将会继承这个容器上所设置的属性 header ...

  4. python-Pymyslql-requests_html:把腾讯新闻的今日推荐和链接存进数据库

    使用pumsql封装的部分功能 request_html:打开www.qq.com的例子 结果: PS:记得处理数据

  5. Java5新特性之枚举

    1.  概念 首先,枚举并非一种新技术,而是一种基础数据类型.它隶属于两种基础类型中的值类型,例如以下: 2.  为什么要有枚举 枚举在真正的开发中是非经常常使用的,它的作用非常easy也非常纯粹:它 ...

  6. Systemd启动图形界面过程

    1 启动命令 systemctl isolate graphical.target 2 启动过程: 文件:/etc/systemd/system/graphical.target 来自:systemd ...

  7. vue 结合 echarts

    http://blog.csdn.net/mr_wuch/article/details/70225364

  8. spring中bean标签factory-method和factory-bean)详解工厂方法(factory-method和factory-bean)

    转自:http://blog.sina.com.cn/s/blog_6d3c1ec601019f3j.html A.factory-method The name of a factory metho ...

  9. Binary Indexed Tree

    我借鉴了这个视频中的讲解的填坑法,我认为非常易于理解.有FQ能力和基本英语听力能力请直接去看视频,并不需要继续阅读. naive 算法 考虑一个这样的场景: 给定一个int数组, 我们想知道它的连续子 ...

  10. SpringBoot(三) SpringBoot中的日志配置

    SLF4J Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如:Java Util Logging,Log4J, Log4J2和Logb ...