单列的堆叠柱状图

目的

MSingleColumnStackBarChart类被设计用于创建只有单列的堆叠柱状图,用于血糖数据的统计。以下是封装这个类的目的的详细描述:

  1. 抽象复杂性: 通过创建MSingleColumnStackBarChart类,你将复杂的MPAndroidChart库的使用和配置封装在一个独立的类中。这有助于降低代码的复杂性,使得在其他部分的代码中更容易理解和维护。

  2. 提高可读性: 将与图表配置相关的代码集中在一个类中,使得主要的业务逻辑部分的代码更加清晰。其他开发者在查看代码时能够更轻松地理解图表的配置和使用方式。

  3. 重用性: 通过封装这个类,你可以在不同的部分或项目中重复使用相同的图表配置。这意味着,如果将来有其他地方需要显示类似的单列堆叠柱状图,你可以轻松地引入这个类,而无需重新实现相同的配置。

  4. 模块化: 类的封装使得代码更加模块化。这允许你将图表的配置和数据处理与其他功能分离,促使代码更易于组织和维护。

  5. 简化调用: 通过提供简单的接口,类的使用者只需几行代码就能创建和显示单列堆叠柱状图。这有助于降低使用图表功能时的学习曲线,并使代码更加整洁。

总体而言,MSingleColumnStackBarChart类的封装旨在提供一种简单、灵活且易于使用的方式,以满足特定场景下(如血糖数据统计)显示单列堆叠柱状图的需求。这样的封装是为了在开发中提高效率、降低出错概率,并促使代码更具可维护性。

示例 

中间的就是柱状形,只要按百分比进行堆叠显示。

调用示例
List<MSingleColumnStackBarChart.MBarData> dataList = new ArrayList<>();

for (int x = 0; x < 1; x++) {
    MSingleColumnStackBarChart.MBarData data = new MSingleColumnStackBarChart.MBarData(15, getColor(R.color.colorHHigh), "15% 很高 > 13.0 mmol/L");
    dataList.add(data);

    data = new MSingleColumnStackBarChart.MBarData(10, getColor(R.color.colorHigh), "10% 偏高 > 10.0 mmol/L");
    dataList.add(data);

    data = new MSingleColumnStackBarChart.MBarData(60, getColor(R.color.colorNormal), "60% 正常 3.9-10.0 mmol/L");
    dataList.add(data);

    data = new MSingleColumnStackBarChart.MBarData(10, getColor(R.color.colorLow), "10% 偏低 < 3.9 mmol/L");
    dataList.add(data);

    data = new MSingleColumnStackBarChart.MBarData(5, getColor(R.color.colorLLow), "5% 很低 < 3.0 mmol/L ");
    dataList.add(data);
}

BarChart barChart = findViewById(R.id.bar_chart);
MSingleColumnStackBarChart barChartView = new MSingleColumnStackBarChart(barChart);
barChartView.setBarDataSets(dataList);
完整的代码实现类
package com.jaredrummler.compent;

import android.graphics.Color;
import android.graphics.PointF;

import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LegendEntry;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * author :hello
 * date : 2024/1/15 8:47
 * description : 只有一列数据的StackBarChart
 */
public class MSingleColumnStackBarChart {
    private BarChart barChart;
    private MLegend mLegend;
    public MSingleColumnStackBarChart(BarChart barChart) {
        this.barChart = barChart;
        this.mLegend = new MLegend();
        init();
    }

    public void setBarDataSets(List<MBarData> dataList) {
        MBarDataSet barDataSet = new MBarDataSet(0, dataList);
        BarData barData = new BarData(barDataSet.getBarDataSet());
        barData.setBarWidth(.8f);

        this.barChart.setData(barData);
        this.mLegend.setLegendConfig(barDataSet.getBarDataSetsColors(), barDataSet.getBarLegendLabels().toArray(new String[0]));
        this.barChart.invalidate();
    }

    public void init() {
        setXAxisConfig();
        setYAxisConfig();

        ///所有值均绘制在其条形顶部上方
        barChart.setDrawValueAboveBar(false);
        // 添加下面这行代码,关闭堆叠模式
        barChart.setDrawBarShadow(false);

        barChart.setFitBars(true);
        barChart.getDescription().setEnabled(false);
        barChart.animateXY(1000,1000);

        //选中高亮显示
        barChart.setHighlightFullBarEnabled(false);
        //双击缩放
        barChart.setDoubleTapToZoomEnabled(false);
        // 设置 是否可以缩放
        barChart.setScaleEnabled(false);
        barChart.setDrawGridBackground(false);

        barChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
            @Override
            public void onValueSelected(Entry e, Highlight h) {
                mLegend.showLegendSelected(h.getStackIndex());

            }



            @Override
            public void onNothingSelected() {
                mLegend.resetLegendDefault();
            }
        });

        barChart.invalidate(); // 刷新图表
    }
    private void setXAxisConfig() {
        // 使柱状图的中心与 X 轴标签对齐
        XAxis xAxis = barChart.getXAxis();
        xAxis.setEnabled(false);
        xAxis.setDrawLabels(false);
        //取消 垂直 网格线
        xAxis.setDrawGridLines(false);
    }

    private void setYAxisConfig() {
        YAxis yLeftAxis = barChart.getAxisLeft();
        yLeftAxis.setEnabled(false);
        yLeftAxis.setDrawLabels(false);
        yLeftAxis.setDrawGridLines(false);
        yLeftAxis.setAxisMinimum(0);
        yLeftAxis.setAxisMaximum(100);
        YAxis yRightAxis = barChart.getAxisRight();
        yRightAxis.setEnabled(false);
        yRightAxis.setDrawLabels(false);
        yRightAxis.setDrawGridLines(false);
    }

    private static class MBarDataSet {
        private BarDataSet barDataSet;
        private List<BarEntry> barEntries;
        private List<MBarData> dataList;
        public MBarDataSet(int index, List<MBarData> dataList) {
            this.dataList = dataList;
            barEntries = covertToBarEntry(index, dataList);
            barDataSet = new BarDataSet(barEntries, "");
            barDataSet.setColors(dataList.stream().map(MBarData::getColor).collect(Collectors.toList()));
//            barDataSet.setValueTextSize(10f);
            barDataSet.setDrawValues(false);
//            barDataSet.setValueTextColor(Color.WHITE);
//            barDataSet.setValueFormatter(new ValueFormatter() {
//                @Override
//                public String getFormattedValue(float value) {
//                    return String.format("%.1f", value) + "%";
//                }
//
//            }); // 设置值文本的位置为外部
            barDataSet.setBarShadowColor(Color.WHITE);
            barDataSet.setBarBorderWidth(2f);
            barDataSet.setBarBorderColor(Color.WHITE);
        }

        public BarDataSet getBarDataSet() {
            return barDataSet;
        }

        public List<BarEntry> getBarEntries() {
            return barEntries;
        }

        private List<BarEntry> covertToBarEntry(float index, List<MBarData> dataList) {
            // y 数据
            ArrayList<BarEntry> yValues = new ArrayList<>();

            float[] stackedValues = new float[dataList.size()];

            // 遍历 yourDataList,获取每个数据项的百分比值,构建堆叠数据
            for (int i = 0; i < dataList.size(); i++) {
                float yValue = dataList.get(i).getYValue();
                stackedValues[i] = yValue;
            }

            BarEntry barEntry = new BarEntry(index, stackedValues);
            yValues.add(barEntry);

            return yValues;
        }

        private List<Integer> getBarDataSetsColors() {
            List<Integer> barColors = new ArrayList<>();

            for (MBarData data : this.dataList) {
                barColors.add(data.getColor());
            }

            return barColors;
        }

        private List<String> getBarLegendLabels() {
            List<String> legendLabels = new ArrayList<>();

            for (MBarData data : this.dataList) {
                legendLabels.add(data.getLabel());
            }

            return legendLabels;
        }
    }

    public static class MBarData {
        private float yValue;
        private int color;
        private String label;

        public MBarData(float percentage, int color, String label) {
            this.yValue = percentage;
            this.color = color;
            this.label = label;
        }

        public float getYValue() {
            return yValue;
        }

        public int getColor() {
            return color;
        }

        public String getLabel() {
            return label;
        }
    }

    private class MLegend {
        public static final float SELECTED_FORM_SIZE = 16f;
        public static final float DEFAULT_FORM_SIZE = 10f;
        public void showLegendSelected(int index) {
            // 选中时突出显示相应的 Legend 标签
            // 获取 Legend 对象
            Legend legend = barChart.getLegend();
            // 获取当前 Legend 的条目
            LegendEntry[] entries = legend.getEntries();

            for (int i = 0; i < entries.length; i++) {
                if (i == index) {
                    entries[index].formSize = SELECTED_FORM_SIZE;
                } else {
                    entries[i].formSize = DEFAULT_FORM_SIZE;
                }
            }
            // 刷新图表
            barChart.invalidate();
        }

        public void resetLegendDefault() {
            // 获取当前 Legend 的条目
            // 获取 Legend 对象
            Legend legend = barChart.getLegend();
            LegendEntry[] entries = legend.getEntries();

            for (int i = 0; i < entries.length; i++) {
                entries[i].formSize = DEFAULT_FORM_SIZE;
            }
            barChart.invalidate();
        }

        public void setLegendConfig(List<Integer> barColors, String[] legendLabels) {
            Legend legend = barChart.getLegend();
            legend.setFormToTextSpace(8f);
            legend.setStackSpace(16f);
            legend.setForm(Legend.LegendForm.CIRCLE);
            legend.setTextSize(14f);

            YAxis yAxis = barChart.getAxisLeft();
            float spaceTop = yAxis.getSpaceTop();
            float spaceBottom = yAxis.getSpaceBottom();
            float yAxisHeight = yAxis.getAxisMaximum() - spaceTop - spaceBottom;
            legend.setYEntrySpace(yAxisHeight / (legendLabels.length));
            legend.setYOffset(spaceTop);
            legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
            legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
            legend.setOrientation(Legend.LegendOrientation.VERTICAL);
            legend.setStackSpace(1f);
            legend.setDrawInside(false);

            if (legendLabels != null && legendLabels.length > 0) {
                List<LegendEntry> legendEntries = new ArrayList<>();
                for (int i = 0; i < legendLabels.length; i++) {
                    LegendEntry entry = new LegendEntry();
                    entry.label = legendLabels[i];
                    entry.formColor = barColors.get(i);
                    entry.formSize = 10f;
                    legendEntries.add(entry);
                }
                legend.setCustom(legendEntries);
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/324593.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

合并两个有序数组(简单)

一、题目 给你两个按 非递减顺序 排列的整数数组nums1和nums2&#xff0c;另有两个整数m和n&#xff0c;分别表示nums1和nums2中的元素数目。请你 合并 nums2到nums1中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a; 最终&#xff0c;合并后数组不应由…

PyTorch——torchtext与PyTorch匹配的版本

一、匹配版本的对照表 二、按照对应版本的命令 例子&#xff1a; pip install torchtext0.9.1参考资料&#xff1a; Torchtext and PyTorch s Version Compatibility

第七在线荣获百灵奖 Buylink Awards 2023零售圈年度卓越服务商品牌

1月11日&#xff0c;由零售圈主办、20零售连锁协会协办、30零售行业媒体支持的中国零售圈大会暨2024未来零售跨年盛典在西安落下帷幕&#xff0c;在这个零售行业盛典中&#xff0c;第七在线凭借其高精尖产品和卓越的服务质量成功入选&#xff0c;并荣获了“百灵奖 Buylink Awar…

基于 IDEA 创建 Maven 的 Java SE 工程和 Java Web 工程

一、概念简介 Maven 工程相对之前的项目&#xff0c;多出一组 gavp 属性&#xff0c;gav 需要我们在创建项目的时候指定&#xff0c;p 有默认值&#xff0c;我们先行了解下这组属性的含义。 Maven 中的 GAVP 是指 GroupId、ArtifactId、Version、Packaging 等四个属性的缩写&am…

c语言嵌套循环

c语言嵌套循环 c语言嵌套循环 c语言嵌套循环一、c语言嵌套循环类型二、嵌套循环案例九九惩罚口诀 一、c语言嵌套循环类型 for(初始值&#xff1b;表达式&#xff1b;表达式) {for&#xff08;初始值&#xff1b;表达式&#xff1b;表达式&#xff09;{代码} }int main() {for (…

Springboot3新特性:GraalVM Native Image Support和虚拟线程(从入门到精通)

说明&#xff1a;都知道&#xff0c;我是搞java的&#xff0c;最近搞c的算法和redis数据库比较多&#xff0c;所以对于以下文章&#xff0c;都是我自己这样认为的&#xff0c;各位看完之后&#xff0c;可尽情评论。 GraalVM Native Image Support 具体用法 以往文章&#xff…

基于SSM的项目监管系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

C#用Math.Round和double.TryParse方法实现四舍五入

目录 一、涉及到的知识点 1.double.TryParse&#xff08;&#xff09;方法 2.Math.Round(Decimal, Int32) 方法 3.comboBox1没有选项 二、示例 1.源码 2.生成 一、涉及到的知识点 1.double.TryParse&#xff08;&#xff09;方法 详见本文作者写的其他文章&#xff0…

C++(1) —— 基础语法入门

目录 一、C初识 1.1 第一个C程序 1.2 注释 1.3 变量 1.4 常量 1.5 关键字 1.6 标识符命名规则 二、数据类型 2.1 整型 2.2 sizeof 关键字 2.3 实型&#xff08;浮点型&#xff09; 2.4 字符型 2.5 转义字符 2.6 字符串型 2.7 布尔类型 bool 2.8 数据的输入 三…

【EI会议征稿通知】第四届图像处理与智能控制国际学术会议(IPIC 2024)

第四届图像处理与智能控制国际学术会议&#xff08;IPIC 2024&#xff09; 2024 4th International Conference on Image Processing and Intelligent Control 2024年第四届图像处理与智能控制国际学术会议&#xff08;IPIC 2024&#xff09;将于2024年5月3日-5日在吉隆坡举…

Web server failed to start. Port 8080 was already in use. 端口被占用

Web server failed to start. Port 8080 was already in use. 端口被占用。 1、cmd回车打开命令窗口 查看端口号是否被占用 netstat -ano|findstr “8080” 2、查看进程号对应的进程名称 tasklist|findstr “12760” 3、直接杀死进程 taskkill /F /pid 12760或 taskkill /F …

Mysql中DATETIME字段设置自动更新

在MySQL里&#xff0c;我们可以设置默认时间值来让数据表记录当时数据表更新时间。 在创建表时设置。我们可以在创建表的时候&#xff0c;指定一个字段的默认值为当前时间CURRENT_TIMESTAMP 示例代码&#xff1a; CREATE TABLE test (id INT PRIMARY KEY AUTO_INCREMENT,crea…

yolov1:背景介绍与算法精讲

目录 一、背景介绍1.1 yolo发展历史1.2 作者介绍 二、算法精讲2.1 预测阶段2.2 训练阶段 三、论文细节 一、背景介绍 其实在写这篇博客的时候yolov1~yolov8的所有网络结构以及算法思想和源码都已经研究很久了&#xff0c;回过头继续读v1会发现有很多细节是自己没有留意的&#…

Windows10解决大小核调度问题

文章目录 1.开启高性能模式2.下载安装PowerSettingsExplorer3.修改配置生效的异类策略异类线程调度策略异类短时间线程调度策略 4.你的电源策略5.CPU展示 该教程是给笔记本电脑用的&#xff0c;经过我实践是成功的。 1.开启高性能模式 使用管理员模式的PowerShell输入下列指令 …

Mantle: A Programmable Metadata Load Balancer for the Ceph File System——论文泛读

SC 2015 Paper 元数据论文阅读汇总 问题 优化Ceph的元数据局部性和负载平衡。 现有方法 提高元数据服务性能的最常见技术是在专用的元数据服务器&#xff08;MDS&#xff09;节点之间平衡负载 [16, 25, 26, 21, 28]。常见的方法是鼓励独立增长并减少通信&#xff0c;使用诸…

HuiYong.Online 私有化博客系统

HuiYong.Online 私有化博客系统 一站式支持MarkDown、Drawio、XMind 免费、简单、强大... 用思维导图、流程图、写文章、做笔记、记录生活;搭建自己 / 组织 / 公司的知识储备系统;这里就是你所寻找的。 链接 官网&#xff1a;https://huiyong.onlineGithub&#xff1a;http…

【iOS】数据存储方式总结(持久化)沙盒结构

在iOS开发中&#xff0c;我们经常性地需要存储一些状态和数据&#xff0c;比如用户对于App的相关设置、需要在本地缓存的数据等等&#xff0c;本篇文章将介绍六个主要的数据存储方式 iOS中数据存储方式&#xff08;数据持久化&#xff09; 根据要存储的数据大小、存储数据以及…

基于Pytorch的身份证及其他证件检测矫正模型应用

前言 在做身份证和其他证件识别的时候&#xff0c;图片基本都不是摆正的状态&#xff0c;此时在进行OCR文字识别的提取文字信息的时候会出现很多误差&#xff0c;如何将证件摆正&#xff0c;再进行OCR文字识别就可以大大提高准确率。 准备工作 1、Python环境&#xff0c;在P…

【Docker】CentOS stream 上安装 Docker 环境详细指南

文章目录 1. 定义2. 优势3. 安装1&#xff09;Linux 上安装&#xff08;强烈推荐&#xff09;2&#xff09;Windows 和 MAC 上安装 4. 验证1&#xff09;查看版本2&#xff09;运行 Hello World 总结 Docker 是一种轻量级的容器化技术&#xff0c;提供了一种在不同环境中快速、…

Android Framework | AOSP源码下载及编译指南(基于Android13)

Android Framework | AOSP源码下载及编译指南(基于Android13) 引言 AOSP&#xff08;Android Open Source Project&#xff09;是Android操作系统的开源项目&#xff0c;通过下载和编译AOSP源码&#xff0c;您可以获得原始的Android系统&#xff0c;并进行定制和开发。本教程…