返回顶部
首页 > 资讯 > 移动开发 >AndroidRecyclerBarChart绘制使用教程
  • 220
分享到

AndroidRecyclerBarChart绘制使用教程

AndroidRecyclerBarChart绘制AndroidRecyclerBarChart 2022-12-09 12:12:33 220人浏览 安东尼
摘要

目录正文1.drawBarChart2. drawHighLight正文 上篇介绍了几种图表的公共组件X、Y轴、背景Board的绘制。这章节介绍柱状图表的绘制,相对其它图表而言简单一

正文

上篇介绍了几种图表的公共组件X、Y轴、背景Board的绘制。这章节介绍柱状图表的绘制,相对其它图表而言简单一些,这里主要介绍图表主体的绘制,以及高亮选中的其中一个的选中框的绘制的相关逻辑。对每个ItemView中的ItemDecoration上进行onDraw的操作,需要将View跟Model进行绑定在一起,单个柱子的一些属性可以通过Model来获取,整体的一些绘制的辅助信息color、size等可以通过Attribute类设置。View 跟Model的绑定不止是BarChart图表,所以的都是一样的。

以下是在BarAdapter中的onBindViewHolder方法中进行关联二者:

根据之前的介绍绘制的逻辑都在ItemDecoration里,我们看下BarChartItemDecoration的onDrawOver, 对于X、Y轴、Board的绘制其实可以沉淀到BaseItemDecoration中的,这里直接写了。

这里我们着重看下drawBarChart、drawHighLight、drawBarChartValues的绘制。

1.drawBarChart

绘制柱状图的主体,通过ItemView拿到对应的Entry对象,根据Entry中的Y值进行Y坐标值的转化,然后绘制单个Item RectF的绘制。

//绘制柱状图, mYAxis这个坐标会实时变动,所以通过 BarChartItemDecoration 传过来的精确值。
    final public void drawBarChart(final canvas canvas, @NonNull final RecyclerView parent, final YAxis mYAxis) {
        final float parentRight = parent.getWidth() - parent.getPaddingRight();
        final float parentLeft = parent.getPaddingLeft();
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            BarEntry barChart = (BarEntry) child.getTag();
            RectF rectF = ChartComputeUtil.getBarChartRectF(child, parent, mYAxis, mBarChartAttrs, barChart);
            drawChart(canvas, rectF, parentLeft, parentRight);
        }
    }

绘制的逻辑具体在 drawChart(canvas, rectF, parentLeft, parentRight) 的方法里,这里我们先看看 RectF 的计算,工具类ChartComputeUtil.getBarChartRectF() 的方法。

public static <T extends BarEntry, V extends BaseYAxis, E extends BaseChartAttrs> RectF getBarChartRectF(View child, final RecyclerView parent, V mYAxis, E chartAttrs, T barEntry) {
        final RectF rectF = new RectF();
        float contentBottom = parent.getHeight() - parent.getPaddingBottom() - chartAttrs.contentPaddingBottom;
        float realYAxisLabelHeight = contentBottom - parent.getPaddingTop() - chartAttrs.contentPaddingTop;
        float width = child.getWidth();
        float barSpaceWidth = width * chartAttrs.barSpace;
        float barChartWidth = width - barSpaceWidth;//柱子的宽度
        final float left = child.getLeft() + barSpaceWidth / 2;
        final float right = left + barChartWidth;
        float height = barEntry.getY() / mYAxis.getAxisMaximum() * realYAxisLabelHeight;
        if (chartAttrs.yAxisReverse && barEntry.getY() > 0) {
            float valueTemp = mYAxis.getAxisMaximum() - barEntry.getY();
            height = valueTemp / mYAxis.getAxisMaximum() * realYAxisLabelHeight;
        }
        final float top = Math.max(contentBottom - height, parent.getPaddingTop());
        rectF.set(left, top, right, contentBottom);
        return rectF;
    }

柱子RectF 的计算,Width根据 itemView的width 以及每个ItemView的空余所占比例的一个ChartAttrs中的参数

barSpace计算得来,算出RectF的 left、right; height 的计算,涉及到Entry 的Y值以及YAxis 当前显示情况下的getAxisMaximum(),这里默认了Minmum为0,业务逻辑的Y值比例转化成 屏幕Pixel对应的高度,然后根据ItemView的top、bottom计算得到 RectF的 top, bottom. (这里的计算,到时候其它图表高度也可以用)。

获取到 单个ItemView 中BarChart 所占的RectF确定后,画RectF就比较简单了,稍微有点难点的是处理一下边界的问题,边界问题,柱状图相比线形图等简单一些,处于边界的柱子绘制的颜色不一样,交给用户mBarChartAttrs.chartEdgeColor传color值,这里默认设置的是Gray。

private void drawChart(Canvas canvas, RectF rectF, float parentLeft, float parentRight) {
    float radius = (rectF.right - rectF.left) *mBarChartAttrs.barChartRoundRectRadiusRatio;
    // 浮点数的 == 比较需要注意
    if (DecimalUtil.smallOrEquals(rectF.right, parentLeft)) {
      //continue 会闪,原因是end == parentLeft 没有过滤掉,显示出来柱状图了。
      return;
    } else if (rectF.left < parentLeft && rectF.right > parentLeft) {
      //左边部分滑入的时候,处理柱状图的显示
      rectF.left = parentLeft;
      Path path = CanvasUtil.createRectRoundPath(rectF, radius, RoundRectType.TYPE_RIGHT);
      mBarChartPaint.setColor(mBarChartAttrs.chartEdgeColor);
      canvas.drawPath(path, mBarChartPaint);
    } else if (DecimalUtil.biGorEquals(rectF.left, parentLeft) && DecimalUtil.smallOrEquals(rectF.right, parentRight)) {
      //中间的; 浮点数的 == 比较需要注意
      mBarChartPaint.setColor(mBarChartAttrs.chartColor);
      Path path = CanvasUtil.createRectRoundPath(rectF, radius);
      canvas.drawPath(path, mBarChartPaint);
    } else if (DecimalUtil.smallOrEquals(rectF.left, parentRight) && 
               rectF.right > parentRight) {
      //右边部分滑出的时候,处理柱状图,文字的显示
      float distance = (parentRight - rectF.left);
      rectF.right = rectF.left + distance;
      Path path = CanvasUtil.createRectRoundPath(rectF, radius, RoundRectType.TYPE_LEFT);
            mBarChartPaint.setColor(mBarChartAttrs.chartEdgeColor);
            canvas.drawPath(path, mBarChartPaint);
        }
   }

下面是个步数的周视图:

2. drawHighLight

首先看下这里高亮具体是如何显示的,直观的看些图:

当前的RecyclerView的getChildCount内每个ItemView对应的Entry,设定了一个 selected 的字段来确定显示高亮,至于该字段的值的设定及变化,后续章节会介绍,这里假定已经确定了当前的某一个ItemView的Entry的selected是选中状态的,它有可能在中间,或者在边界需要处理边界绘制的问题,这里分画顶部的矩形框及drawTextValue值,底部绘制drawLine(这个不存在绘制的边界问题)

//绘制选中时 highLight 标线及浮框。
public <E extends BaseYAxis> void drawHighLight(Canvas canvas, @NonNull RecyclerView parent, E yAxis) {
  if (mBarChartAttrs.enableValueMark) {
    int childCount = parent.getChildCount();
    View child;
    for (int i = 0; i < childCount; i++) {
      child = parent.getChildAt(i);
      T entry = (T) child.getTag();
      RectF rectF = ChartComputeUtil.getBarChartRectF(child, parent, yAxis, mBarChartAttrs, entry);
      float width = child.getWidth();
      float childCenter = child.getLeft() + width / 2;
      String valueStr = mHighLightValueFORMatter.getBarLabel(entry);
      if (entry.isSelected() && !TextUtils.isEmpty(valueStr)) {
        int chartColor = getChartColor(entry);
        float rectHeight = drawHighLightValue(canvas, valueStr, childCenter, parent, chartColor);//绘制顶部的poupWindow,高亮矩形框及drawText
        float[] points = new float[]{childCenter, rectF.top, childCenter, rectHeight};
        drawHighLightLine(canvas, points, chartColor);//绘制底部的Line
      }
    }
  }
}

以上中 drawHighLightValue 中, 包含了绘制矩形、drawText两项具体的内容:

//绘制柱状图选中浮框
protected float drawHighLightValue(Canvas canvas, String valueStr, float childCenter,
                                   RecyclerView parent, int barChartColor) {
  float parentTop = parent.getPaddingTop();
  float contentRight = parent.getWidth() - parent.getPaddingRight();
  float contentLeft = parent.getPaddingLeft();
  String[] strings = valueStr.split(DefaultHighLightMarkValueFormatter.CONNECT_STR);
  float leftEdgeDistance = Math.abs(childCenter - contentLeft);
  float rightEdgeDistance = Math.abs(contentRight - childCenter);
  float leftPadding = DisplayUtil.dip2px(8);
  float rightPadding = DisplayUtil.dip2px(8);
  float centerPadding = DisplayUtil.dip2px(16);
  float rectBottom = parentTop;
  float txtTopPadding = DisplayUtil.dip2px(8);
  String leftStr = strings[0];
  String rightStr = strings[1];
  float txtLeftWidth = mHighLightValuePaint.measureText(leftStr);
  float txtRightWidth = mHighLightValuePaint.measureText(rightStr);
  float rectFHeight = TextUtil.getTxtHeight1(mHighLightValuePaint) + txtTopPadding * 2;
  float txtWidth = txtLeftWidth + txtRightWidth + leftPadding +
    rightPadding + centerPadding;
  float edgeDistance = txtWidth / 2.0f;
  float rectTop = parentTop - rectFHeight;
  //绘制RectF
  RectF rectF = new RectF();
  mBarChartPaint.setColor(barChartColor);
  if (leftEdgeDistance <= edgeDistance) {//矩形框靠左对齐
    rectF.set(contentLeft, rectTop, contentLeft + txtWidth, rectBottom);
    float radius = DisplayUtil.dip2px(8);
    canvas.drawRoundRect(rectF, radius, radius, mBarChartPaint);
  } else if (rightEdgeDistance <= edgeDistance) {//矩形框靠右对齐
    rectF.set(contentRight - txtWidth, rectTop, contentRight, rectBottom);
    float radius = DisplayUtil.dip2px(8);
    canvas.drawRoundRect(rectF, radius, radius, mBarChartPaint);
  } else {//居中对齐。
    rectF.set(childCenter - edgeDistance, rectTop, childCenter + edgeDistance, rectBottom);
    float radius = DisplayUtil.dip2px(8);
    canvas.drawRoundRect(rectF, radius, radius, mBarChartPaint);
  }
  //绘文字
  RectF leftRectF = new RectF(rectF.left + leftPadding, rectTop + txtTopPadding,
                              rectF.left + leftPadding + 
                              txtLeftWidth, rectTop + txtTopPadding + rectFHeight);
  mHighLightValuePaint.setTextAlign(Paint.Align.LEFT);
  Paint.FontMetrics fontMetrics = mHighLightValuePaint.getFontMetrics();
  float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
  float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
  int baseLineY = (int) (leftRectF.centerY() + (top + bottom) / 2);//基线中间点的y轴计算公式
  canvas.drawText(leftStr, rectF.left + leftPadding, baseLineY, mHighLightValuePaint);
  float dividerLineStartX = rectF.left + leftPadding + txtLeftWidth + centerPadding / 2.0f;
  float dividerLineStartY = rectTop + DisplayUtil.dip2px(10);
  float dividerLineEndX = dividerLineStartX;
  float dividerLineEndY = rectBottom - DisplayUtil.dip2px(10);
  float[] lines = new float[]{dividerLineStartX, dividerLineStartY, 
                              dividerLineEndX, dividerLineEndY};
  canvas.drawLines(lines, mHighLightValuePaint);
  float rightRectFStart = rectF.left + leftPadding + txtLeftWidth + centerPadding;
  RectF rightRectF = new RectF(rightRectFStart, rectTop + txtTopPadding,
                               rectF.right - rightPadding, rectBottom - txtTopPadding);
  canvas.drawText(rightStr, rightRectF.left, baseLineY, mHighLightValuePaint);
  return rectFHeight;
}

具体的文案绘制内容 valueStr 从 ValueFormatter里获取,我这里需要拆分一下ValueStr,然后绘制leftStr, rightStr这里相当于各个项目自己的需求。

以上就是Android RecyclerBarChart绘制使用教程的详细内容,更多关于Android RecyclerBarChart绘制的资料请关注编程网其它相关文章!

--结束END--

本文标题: AndroidRecyclerBarChart绘制使用教程

本文链接: https://www.lsjlt.com/news/174627.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • AndroidRecyclerBarChart绘制使用教程
    目录正文1.drawBarChart2. drawHighLight正文 上篇介绍了几种图表的公共组件X、Y轴、背景Board的绘制。这章节介绍柱状图表的绘制,相对其它图表而言简单一...
    99+
    2022-12-09
    Android RecyclerBarChart绘制 Android RecyclerBarChart
  • python使用matplotlib绘制柱状图教程
    Matplotlib的概念这里就不多介绍了,关于绘图库Matplotlib的安装方法:点击这里 小编之前也和大家分享过python使用matplotlib实现的折线图和制饼图效果,感兴趣的朋友们也可以点击查...
    99+
    2022-06-04
    教程 柱状图 python
  • python使用matplotlib绘制折线图教程
    matplotlib简介 matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。 ...
    99+
    2022-06-04
    教程 折线图 python
  • PythonPandas工具绘制数据图使用教程
    目录背景介绍折线图条形图水平条形图堆积图散点图饼图蜂巢图箱线图绘制子图背景介绍 Pandas的DataFrame和Series在Matplotlib基础上封装了一个简易的绘图函数,使...
    99+
    2024-04-02
  • 入门教程:学习使用matplotlib绘制折线图
    简易教程:学会使用Matplotlib绘制折线图 引言:Matplotlib是Python中常用的绘图库之一,可以用于绘制各种类型的图形,包括折线图。折线图是一种常用的数据可视化方式,能够清晰展示数据的变化趋势。本文将通过具体的...
    99+
    2024-01-17
    教程 折线图
  • 教你使用python绘制五星红旗
    语言:python 使用库:turtle 效果如下:   话不多说,进入正题↓ 代码 from turtle import *"""绘制五角星,大小可变"""def wujiaoxing(size): for i in range(...
    99+
    2023-10-06
    python 开发语言 程序人生 学习 节日
  • Python怎么绘制三维图_Python绘制三维图教程
    1、首先打开python。 2、然后创建python文件。 3、引入相关python库。 4、接着定义数据。 5、定义三维函数。 6、再绘制三维图。 7、点击【Run】运行程序...
    99+
    2024-04-02
  • R语言绘图学习教程VennDiagram绘制venn
    目录导读一、模拟输入二、venn基础图三、个性化参数调整四、保存导读 使用VennDiagram函数包中的venn.diagram函数绘制三数据集venn图。 安装依赖包: # ve...
    99+
    2024-04-02
  • 使用R语言绘制棒棒糖图火柴杆图教程
    目录 使用原生ggplot方法1)生成数据使用ggpubr包中的ggdotchart()参考 使用原生ggplot方法 最容易也是最简单想到的方法是直接使用ggp...
    99+
    2024-04-02
  • 如何绘制生产管理流程图,教你快速绘制流程图
    生产管理又称生产控制,是指对企业整个生产系统设置和运行进行各种管理的工作。以往工作中,我们花费大量时间写生产管理流程介绍,还要确保各个环节是否有重复和多于事项。随着科技发展,各种管理软件可以轻松帮助企业...
    99+
    2024-04-02
  • 利用Matlab绘制地图的超详细教程
    目录MappingToolbox工具箱安装局部区域陆地绘制映射贴图纹理贴图线路图绘制usamapaxesm一些地图绘制可用简易函数subplottightmap边框标签网格快速开关函...
    99+
    2024-04-02
  • 教你怎么用python绘制dotplot
    目录一、前言二、安装三、模块导入四、数据准备五、画图六、写在篇末一、前言 R语言不少库都可以方便的画dotplot,但是低频使用R这么多年,我依旧觉得R不是一门真正的编程语言。目前,...
    99+
    2024-04-02
  • python绘制三维图的详细教程
    本篇文章给大家带来了关于Python的相关知识,通常我们用 Python 绘制的都是二维平面图,但有时也需要绘制三维场景图,下面介绍了关于python绘制三维图的相关资料,希望对大家有帮助。【相关推荐:Python3视频教程 】本文仅仅梳理...
    99+
    2024-04-02
  • Python绘制散点图的教程详解
    少废话,直接上代码  import matplotlib.pyplot as plt import numpy as np # 1. 首先是导入包,创建数据 n = 10 ...
    99+
    2024-04-02
  • 一文教你如何使用Python绘制瀑布图
    目录前期准备方法一:waterfall_ax方法二:waterfall_chart方法三:plotly什么是瀑布图?瀑布图用表达两个数值之间的变化过程,过程值为正的时候,向上加,过程...
    99+
    2023-05-16
    Python绘制瀑布图 Python 瀑布图
  • 使用matplotlib绘制热图(heatmap)全过程
    目录matplotlib绘制热图(heatmap)拿出来跟大家分享一下效果图如下主题色参数可选总结matplotlib绘制热图(heatmap) python常用的绘图库就是matp...
    99+
    2022-12-17
    matplotlib绘制热图 绘制热图heatmap 使用matplotlib绘制热图
  • 使用R语言绘制散点图结合边际分布图教程
    目录1. 使用ggExtra结合ggplot21)传统散点图2)密度函数3)直方图4)箱线图(宽窄的显示会有些问题)5)小提琴图(会有重叠,不建议使用)6)密度函数与直方图同时展现2...
    99+
    2024-04-02
  • PythonOpenCV简单的绘图函数使用教程
    目录1、画直线的函数是cv2.line2、画矩形的函数是cv2.rectangle3、画圆函数是cv2.circle4、画椭圆的函数是cv2.elipes5、画多边形的函数是cv2....
    99+
    2024-04-02
  • Excel中绘制直观的股价图教程
    要在Excel中绘制直观的股价图,您可以按照以下步骤操作:步骤1:准备数据在Excel中,您需要准备股价的数据。通常,股价数据包括日...
    99+
    2023-09-15
    excel
  • Pythonmatplotlib超详细教程实现图形绘制
    目录前言1. matplotlib.patches概述2. 绘制图形方法3. 绘制图形步骤4. 绘制图形属性设置透明度设置颜色5. 小试牛刀前言 我们前面对matplotlib模块底...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作