MPAndroidChart - 饼图 - 自定义标签线

2024-04-26

我正在尝试使用 MPAndroidChart 和饼图绘制如图所示的标签线。我不知道如何

  1. 将线条与图表分离
  2. 在该行的开头画一个小圆圈。

谢谢。


这绝非易事。要将线条与图表分离,您可以使用valueLinePart1OffsetPercentage并调整线条部分的长度。但要让图表在行尾绘制点,您需要一个自定义渲染器。这是一个:

class CustomPieChartRenderer(pieChart: PieChart, val circleRadius: Float)
    : PieChartRenderer(pieChart, pieChart.animator, pieChart.viewPortHandler) {

    override fun drawValues(c: Canvas) {
        super.drawValues(c)

        val center = mChart.centerCircleBox

        val radius = mChart.radius
        var rotationAngle = mChart.rotationAngle
        val drawAngles = mChart.drawAngles
        val absoluteAngles = mChart.absoluteAngles

        val phaseX = mAnimator.phaseX
        val phaseY = mAnimator.phaseY

        val roundedRadius = (radius - radius * mChart.holeRadius / 100f) / 2f
        val holeRadiusPercent = mChart.holeRadius / 100f
        var labelRadiusOffset = radius / 10f * 3.6f

        if (mChart.isDrawHoleEnabled) {
            labelRadiusOffset = (radius - radius * holeRadiusPercent) / 2f
            if (!mChart.isDrawSlicesUnderHoleEnabled && mChart.isDrawRoundedSlicesEnabled) {
                rotationAngle += roundedRadius * 360 / (Math.PI * 2 * radius).toFloat()
            }
        }

        val labelRadius = radius - labelRadiusOffset

        val dataSets = mChart.data.dataSets

        var angle: Float
        var xIndex = 0

        c.save()
        for (i in dataSets.indices) {
            val dataSet = dataSets[i]
            val sliceSpace = getSliceSpace(dataSet)
            for (j in 0 until dataSet.entryCount) {
                angle = if (xIndex == 0) 0f else absoluteAngles[xIndex - 1] * phaseX
                val sliceAngle = drawAngles[xIndex]
                val sliceSpaceMiddleAngle = sliceSpace / (Utils.FDEG2RAD * labelRadius)
                angle += (sliceAngle - sliceSpaceMiddleAngle / 2f) / 2f

                if (dataSet.valueLineColor != ColorTemplate.COLOR_NONE) {
                    val transformedAngle = rotationAngle + angle * phaseY
                    val sliceXBase = cos(transformedAngle * Utils.FDEG2RAD.toDouble()).toFloat()
                    val sliceYBase = sin(transformedAngle * Utils.FDEG2RAD.toDouble()).toFloat()
                    val valueLinePart1OffsetPercentage = dataSet.valueLinePart1OffsetPercentage / 100f
                    val line1Radius = if (mChart.isDrawHoleEnabled) {
                        (radius - radius * holeRadiusPercent) * valueLinePart1OffsetPercentage + radius * holeRadiusPercent
                    } else {
                        radius * valueLinePart1OffsetPercentage
                    }
                    val px = line1Radius * sliceXBase + center.x
                    val py = line1Radius * sliceYBase + center.y

                    if (dataSet.isUsingSliceColorAsValueLineColor) {
                        mRenderPaint.color = dataSet.getColor(j)
                    }
                    c.drawCircle(px, py, circleRadius, mRenderPaint)
                }

                xIndex++
            }
        }
        MPPointF.recycleInstance(center)
        c.restore()
    }
}

此自定义渲染器扩展了默认饼图渲染器。我基本上只是复制了代码PieChartRenderer.drawValues方法,将其转换为 Kotlin,并删除所有不需要的内容。我只保留了确定行尾点位置所需的逻辑。

我尝试重现您显示的图像:


val chart: PieChart = view.findViewById(R.id.pie_chart)
chart.setExtraOffsets(40f, 0f, 40f, 0f)

// Custom renderer used to add dots at the end of value lines.
chart.renderer = CustomPieChartRenderer(chart, 10f)

val dataSet = PieDataSet(listOf(
        PieEntry(40f),
        PieEntry(10f),
        PieEntry(10f),
        PieEntry(15f),
        PieEntry(10f),
        PieEntry(5f),
        PieEntry(5f),
        PieEntry(5f)
), "Pie chart")

// Chart colors
val colors = listOf(
        Color.parseColor("#4777c0"),
        Color.parseColor("#a374c6"),
        Color.parseColor("#4fb3e8"),
        Color.parseColor("#99cf43"),
        Color.parseColor("#fdc135"),
        Color.parseColor("#fd9a47"),
        Color.parseColor("#eb6e7a"),
        Color.parseColor("#6785c2"))
dataSet.colors = colors
dataSet.setValueTextColors(colors)

// Value lines
dataSet.valueLinePart1Length = 0.6f
dataSet.valueLinePart2Length = 0.3f
dataSet.valueLineWidth = 2f
dataSet.valueLinePart1OffsetPercentage = 115f  // Line starts outside of chart
dataSet.isUsingSliceColorAsValueLineColor = true

// Value text appearance
dataSet.yValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE
dataSet.valueTextSize = 16f
dataSet.valueTypeface = Typeface.DEFAULT_BOLD

// Value formatting
dataSet.valueFormatter = object : ValueFormatter() {
    private val formatter = NumberFormat.getPercentInstance()

    override fun getFormattedValue(value: Float) =
            formatter.format(value / 100f)
}
chart.setUsePercentValues(true)

dataSet.selectionShift = 3f

// Hole
chart.isDrawHoleEnabled = true
chart.holeRadius = 50f

// Center text
chart.setDrawCenterText(true)
chart.setCenterTextSize(20f)
chart.setCenterTextTypeface(Typeface.DEFAULT_BOLD)
chart.setCenterTextColor(Color.parseColor("#222222"))
chart.centerText = "Center\ntext"

// Disable legend & description
chart.legend.isEnabled = false
chart.description = null

chart.data = PieData(dataSet)

再说一次,这不是很简单。我希望你喜欢 Kotlin!如果您经常需要,可以将大部分配置代码移至子类中。结果如下:

我不是 MPAndroidChart 专家。事实上,我只用过一次,那是两年前的事了。但如果你进行研究,大多数时候你都可以找到解决方案。幸运的是,MPAndroidChart 是一个非常可定制的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MPAndroidChart - 饼图 - 自定义标签线 的相关文章

  • 如何对这个字符串进行子串化

    我想得到这个字符串的 4 个部分 String string 10 trillion 896 billion 45 million 56873 我需要的4个部分是 10万亿 8960亿 4500万 和 56873 我所做的是删除所有空格 然
  • Sqlite数据库生命周期?关闭应用程序后它会被删除吗?

    我正在遵循一个简单的教程 该教程创建一个从 SQLiteOpenHelper 扩展的类 并创建一个包含一个表和 5 行的数据库 好的 但我需要更多地了解 android Sqlite 数据库 例如 如果应用程序关闭或手机关机会发生什么 数据
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • 如何在android中获取Camera2 API的当前曝光

    In android hardware Camera旧的 我使用下面的代码获取当前曝光并获取它Camera Camera Parameters param mCamera getParameters currentExposure para
  • android xamarin 中的 reCaptcha

    我想在 Xamarin android 应用程序中实现验证码 我抓住了这个在 Android 中集成 googles reCaptcha 验证 https www c sharpcorner com article how to integ
  • Android Activity 生命周期函数基础知识

    我正在测试这段代码 它显示活动所处的状态 public class Activity101Activity extends Activity String tag Lifecycle Called when the activity is
  • 当文本输入聚焦在 React Native for Android 的底部工作表上时,视图移出屏幕

    我正在使用图书馆 https github com osdnk react native reanimated bottom sheet https github com osdnk react native reanimated bott
  • Android 模拟器插件无法初始化后端 EGL 显示

    我在 Cloudbees 上设置了 Jenkins 作业 并且可以在那里成功签出并编译我的 Android 项目 现在我想在 android 模拟器中运行一些 JUnit 测试并添加 Android 模拟器插件 我将 显示模拟器窗口 选项设
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 在gradle插件中获取应用程序变体的包名称

    我正在构建一个 gradle 插件 为每个应用程序变体添加一个新任务 此新任务需要应用程序变体的包名称 这是我当前的代码 它停止使用最新版本的 android gradle 插件 private String getPackageName
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 在 SQLite 中搜索时排除 HTML 标签和一些 UNICODE 字符

    更新 4 我已经成功运行了firstchar例如 但现在的问题是使用regex 即使包含头文件 它也无法识别regex操作员 有什么线索可以解决这个问题吗 更新 2 我已经编译了sqlite3我的项目中的库 我现在正在寻找任何人帮助我为我的
  • 尝试在 ubuntu 中编译 android 内核时出错

    我正在尝试从源代码编译 Android 内核 并且我已经下载了所有正确的软件包来执行此操作 但由于某种原因我收到此错误 arm linux androideabi gcc error unrecognized command line op
  • 错误:在根项目“projectName”中找不到项目“app”

    我有一个在 Eclipse 中开发的旧应用程序 现在尝试将其迁移到 Android Studio 我更新了库并遵循了基本步骤 现在 我收到此错误 Error Project app not found in root project pro
  • Android访问远程SQL数据库

    我可以直接从 Android 程序访问远程 SQL 数据库 在网络服务器上 吗 即简单地打开包含所有必需参数的连接 然后执行 SQL 查询 这是一个私人程序 不对公众开放 仅在指定的手机上可用 因此我不担心第三方获得数据库访问权限 如果是这
  • Android 套接字和 asynctask

    我即将开始制作一个应该充当 tcp 聊天客户端的应用程序 我一直在阅读和阅读 我得出的结论是最好 如果不需要 将我的套接字和异步任务中的阅读器 问题是我不确定从哪里开始 因为我是 Android 新手 这至少对我来说是一项艰巨的任务 但据我
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 将 Intent 包装在 LabeledIntent 中以用于显示目的

    要求 我的应用程序中有一个 共享 按钮 我需要通过 Facebook 分享 我需要选择是否安装原生 Facebook 应用程序 我们的决定是 如果未安装该应用程序 则将用户发送到 facebook com 进行分享 当前状态 我可以检测何时
  • 如何将 google+ 登录集成到我的 Android 应用程序中?

    大家好 实际上我需要通过我的应用程序从 google 登录人们 现在我阅读了 google 上的文档 其中指出 要允许用户登录 请将 Google Sign In 集成到您的应用中 初始化 GoogleApiClient 对象时 请求 PL
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • nix 构建守护进程是否保留构建日志?

    有时候跑步的时候nix build and nixos rebuild我发现了易于修复的问题 例如已弃用的警告或冗余导入 并且我认为 有趣 我也许能够在空闲时间解决这个问题 我知道我可以将构建日志重定向到一个文件 但我总是忘记这样做 直到再
  • 如何熟悉代码签名问题?

    每次当我处理代码签名和配置文件时 都会发生奇怪的事情 大多数时候我会收到错误 找不到代码签名身份 如果没有 则会出现 找不到匹配的配置文件 和 没有具有有效签名身份的配置文件 之类的错误 尽管我非常熟悉代码签名和配置背后的理论和事物 但我每
  • 结构体的指针运算

    给定一个包含 1 个 double 和 3 个 int 变量 总共 4 个变量 的结构体定义 如果 p 是指向该结构体的指针 其值为 0x1000 那么 p 的值为多少 这不是作业问题 所以不用担心 我只是想准备考试 但我无法解决这个练习题
  • 使用蓝牙调用应用程序

    我们可以使用蓝牙从一个 Android 设备中调用另一台 Android 设备中的应用程序吗 如果可以的话流程是什么 不 您不能从一个 Android 设备调用另一个应用程序 除非两个应用程序都使用蓝牙权限并进行配置
  • 检测文本中哪个单词被点击

    我正在构建一个 JS 脚本 该脚本在某个时刻能够在给定页面上允许用户单击任何单词并将该单词存储在变量中 我有一个非常丑陋的解决方案 并且涉及使用 jQuery 进行类解析 我首先解析整个 html 将所有内容拆分到每个空间上 并重新附加包含
  • 在 Reshape Cast() 中使用来自 Shiny Widget 的输入

    我试图在我闪亮的网络应用程序中创建一种数据透视表 用户可以在其中选择他们想要相互转换的变量 我发现的问题是 当我尝试将强制转换与 输入 列 一起使用时 我得到以下信息 错误 强制转换公式包含在熔融数据中找不到的变量 输入 列 input c
  • 如何提高 PySerial 读取速度

    我目前正在构建一台使用 Arduino Mega2560 作为主控制器的机器 Arduino 通过串口连接 获取命令 执行它并每 1ms 吐出一堆测量数据 我有一个运行 Python 的 Raspberry Pi 为用户提供一个漂亮的 GU
  • eclipse中Tomcat服务器发布问题

    当我尝试启动服务器时 出现以下异常 Could not publish to the server java lang IndexOutOfBoundsException 技术 JSF 2 Primefaces 3 5 Tomcat 7 J
  • Chrome webNavigation.onComplete 不起作用?

    我正在尝试编写一个 chrome 扩展 当用户位于包含视频的 YouTube 页面时执行一些代码 据我所知 我的代码是正确的 但它不起作用 事件页面 js chrome webNavigation onCompleted addListen
  • Python:当键盘中断被转发到多处理子进程时?

    我在 Windows 上执行了以下测试代码 import multiprocessing import time def child while True time sleep 2 if name main multiprocessing
  • Meteor 公共文件夹不工作

    我是 Meteor 的新手 我试图了解如何提供静态内容 图像 JS 等 我按照文档创建了正确的文件夹结构 它并没有真正涉及 但使对此内容的请求只是故障转移到服务主应用程序页面 例如 将图像放入 app root public image p
  • 从子模块隐式导入

    我有一个这样的包 foo init py bar py baz py 我希望在导入时自动使用子模块的功能foo So if bar py has def spam 在某个地方 我希望能够直接调用它 就像foo spam 实现这一目标的最佳方
  • 疑难解答“WSGIRequest”对象没有属性“用户”?

    我正在尝试使用 login required装饰者但我得到了 WSGIRequest object has no attribute user 属性错误 我有进口声明from django contrib auth decorators i
  • MathJax:隐藏Mathjax加载过程

    I have Mathjax在我显示的代码中UIWebView 尽管Mathjax正在加载它在我的左下角显示加载过程UIWebView与下面的图片相同 我想隐藏它们 我不希望我的用户看到它们 note 虚拟解决方案显示假 正在加载 几秒钟
  • type="range" HTML 输入的刻度

    看完之后this http css tricks com datalists different input types 我想知道是否可以在 Chrome 和 Firefox 中显示刻度type range 输入号码 我能找到的关于这个主题
  • 使用 keras 和多个序列进行时间序列预测

    我明白了有状态 LSTM 预测示例 https github com fchollet keras blob master examples stateful lstm py在 Keras 中的单个序列上 该示例有一个包含 50k 个观察值
  • mysql_real_escape_string 未定义

    我正在使用 PHP 版本 5 3 并尝试使用mysql real escape string unescaped string 在我的代码中 但出现错误 Fatal error Call to undefined function mysq
  • 查询字符串:查询字符串是否可以包含也包含查询字符串的 URL?

    Example http foo com generatepdf aspx u http foo com somepage aspx color blue size 15 我添加了 iis 标签 因为我猜它也取决于您使用的服务器技术 服务器
  • OpenSSL 和 CryptoJS SHA256 加密转换

    我的问题是 OpenSSL 的新版本与 CryptoJS 的默认设置不兼容 openssl enc 用于基于密码的密钥派生的默认哈希值 1 1 0 中更改为 SHA256 而较低版本中更改为 MD5 https unix stackexch
  • MPAndroidChart - 饼图 - 自定义标签线

    我正在尝试使用 MPAndroidChart 和饼图绘制如图所示的标签线 我不知道如何 将线条与图表分离 在该行的开头画一个小圆圈 谢谢 这绝非易事 要将线条与图表分离 您可以使用valueLinePart1OffsetPercentage