Qml热力甜甜圈控件(嵌套饼图)附使用Demo

        嵌套甜甜圈图,每个小圈内的切片具有相同角度,每个切片采用不同颜色(热力值)代表该切片处数值的大小,该图表适用于展示具有相同周期的重复数据的密度,应用于例如连续多日的24小时各时段数据密度等场景,Demo效果图:

 属性

[readonly]donutSeries:嵌套的每一圈的对象列表
donutCount:嵌套的圈数
maxValue:所有数据中最大的值(用于热力计算,如不设置热力计算值有偏差)
minSize:最内圈尺寸(0~1)
maxSize:最外圈尺寸(0~1)
backgroundColor:控件的背景色
defaultColo:无数据值时切片颜色(默认为"#000000")
labelVisible:切片外标签是否显示
sliceCount:每个小圈的切片数,默认:24
heatLegend:热力颜色标识是否显示
donutAnimation:鼠标悬浮于切片时,切片旋转动画是否显示,默认:true
explodeDistanceFactor:鼠标悬浮于切片时,切片向外拓展的距离

信号

hoved(var slice,var order,var position,var value,var state):鼠标悬浮切片时发出该信号,返回当前切片的对象,所处的嵌套圈序列,在该圈中切片的位置,切片值,悬浮状态

函数

setDonutValue(int order,int positon,int value,string name):设置每个切片的数值,注意:使用该函数前,请先设置donutCount

示例Demo地址:

https://github.com/zjgo007/QmlDemo/tree/master/MyTimePieCharticon-default.png?t=LA92https://github.com/zjgo007/QmlDemo/tree/master/MyTimePieChart

组件MyTimePieChart完整代码:

import QtQuick 2.11
import QtQml 2.11
import QtCharts 2.2

ChartView {
      id: chart
      antialiasing: true
      backgroundColor: "transparent"
      title: "甜甜圈图"
      titleFont.family: "微软雅黑"
      titleFont.bold: true
      titleFont.pointSize: 15
      titleColor: "#38d3dc"
      animationOptions: ChartView.SeriesAnimations

      readonly property var donutSeries: []
      property int donutCount: 0
      property double minSize : 0.08
      property double maxSize: 0.9
      property color defaultColor: "#000000"
      property int maxValue: 2
      property bool labelVisible: true
      property int sliceCount: 24
      property bool heatLegend: true
      property bool donutAnimation: true

      signal hoved(var slice,var order,var position,var value,var state)

      Rectangle{
          width: 20
          height: parent.height*3/5
          anchors.verticalCenter: parent.verticalCenter
          anchors.right: parent.right
          anchors.rightMargin: 0
          visible: heatLegend
          gradient: Gradient {
              GradientStop {
                  position: 0
                  color: "red"
              }

              GradientStop {
                  position: 0.2
                  color: "magenta"
              }
              GradientStop {
                  position: 0.4
                  color: "yellow"
              }
              GradientStop {
                  position: 0.6
                  color: "green"
              }
              GradientStop {
                  position: 0.8
                  color: "cyan"
              }
              GradientStop {
                  position: 1
                  color: "blue"
              }

          }

      }

      onDonutCountChanged: {
          for(var i=0;i<donutCount;i++){
              var pie = chart.createSeries(ChartView.SeriesTypePie,String(i))
              pie.onHovered.connect(explodeSlice)
              donutSeries.push(pie)
              for(var j=0;j<sliceCount;j++){
                  var sliceLabel = String(j)+ "~" + String(j+1)
                  var slice = pie.append(sliceLabel,1)
                  slice.color = "#00000000"
                  slice.borderColor = "#38d3dc"
                  slice.explodeDistanceFactor=0.05
                  slice.seriesIndex = i
                  slice.sliceIndex = j
                  slice.heat = 0
                  if(i==donutCount-1){
                      slice.labelVisible = chart.labelVisible
                      slice.labelArmLengthFactor = 0
                      slice.labelColor = "ghostwhite"
                  }
              }
              pie.holeSize = minSize + i * (maxSize - minSize) / donutCount
              pie.size = minSize + (i + 1) * (maxSize - minSize) / donutCount
          }
      }

      function setDonutValue(order,positon,value,name){
          if(order>=donutSeries.length || positon>=sliceCount)
              return
          var pie = donutSeries[order]
          var slice = pie.at(positon)
          slice.order = order
          slice.name = name
          if(value>maxValue){
              maxValue = value
          }
          var colorIndex = Math.ceil(value*100/maxValue)
          slice.color = heatList[colorIndex]
          slice.heat = value

      }

      function explodeSlice(slice,exploded){
          if(donutAnimation){
              if(exploded){
                  var sliceStartAngle = slice.startAngle
                  var sliceEndAngle = slice.startAngle+slice.angleSpan
                  for(var i=slice.seriesIndex+1;i<donutSeries.length;i++){
                      donutSeries[i].startAngle = sliceEndAngle
                      donutSeries[i].endAngle = 360 + sliceStartAngle
                  }
              }else{
                  for(var j=slice.seriesIndex+1;j<donutSeries.length;j++){
                      donutSeries[j].startAngle = 0
                      donutSeries[j].endAngle = 360
                  }
              }
          }
          slice.exploded = exploded
          hoved(slice,slice.seriesIndex,slice.sliceIndex,slice.heat,exploded)
      }


      margins{
          left:0;right:20;top:0;bottom: 0
      }

      legend{
          visible: false
      }

      readonly property var heatList: [defaultColor, defaultColor, "#001cff", "#0026ff", "#0035ff", "#003fff", "#004eff", "#0058ff", "#0067ff", "#0071ff", "#007fff", "#008eff", "#0098ff", "#00a7ff", "#00b1ff", "#00c0ff", "#00caff", "#00daff", "#00e4ff", "#00f3ff", "#00fdff", "#00fff2", "#00ffe3", "#00ffd9", "#00ffca", "#00ffc0", "#00ffb1", "#00ffa7", "#00ff98", "#00ff8e", "#00ff7f", "#00ff71", "#00ff67", "#00ff58", "#00ff4e", "#00ff3f", "#00ff35", "#00ff26", "#00ff1c", "#00ff0d", "#00ff03", "#0cff00", "#1bff00", "#25ff00", "#34ff00", "#3eff00", "#4dff00", "#57ff00", "#66ff00", "#70ff00", "#80ff00", "#8fff00", "#99ff00", "#a8ff00", "#b2ff00", "#c1ff00", "#cbff00", "#daff00", "#e4ff00", "#f3ff00", "#fdff00", "#fff20d", "#ffe31c", "#ffd926", "#ffca35", "#ffc03f", "#ffb14e", "#ffa758", "#ff9867", "#ff8e71", "#ff7f7f", "#ff718e", "#ff6798", "#ff58a7", "#ff4eb1", "#ff3fc0", "#ff35ca", "#ff26d9", "#ff1ce3", "#ff0df2", "#ff03fc", "#ff00f0", "#ff00dc", "#ff00ce", "#ff00b9", "#ff00ab", "#ff0097", "#ff008a", "#ff0077", "#ff006a", "#ff0056", "#ff0042", "#ff0034", "#ff0020", "#ff0013", "#ff0000", "#ff0000", "#ff0000", "#ff0000", "#ff0000", "#ff0000"]
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵喵叫的猴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值