# Swift 实现数据分布图 块状分布图

2019.11.08 16:43 758浏览

1.处理数据 成模块分配模式 按上图分配 ->[[数据1，数据2],[数据3],[数据4，数据5],[数据6，数据7，数据8],[数据9，数据10],[数据11],[数据12，数据13]......]

//处理数组

func makeDownDatas(arr:[CGFloat]) -> [[CGFloat]] {

var dataList:[[CGFloat]] = []

var left:CGFloat = 0

var num = 0

while num < (arr.count <= 10 ? arr.count : 10) {

let item = arr[num]

if item/(1.0-left) > 0.4 {

dataList.append([item])

left = left + item

num += 1

}else if dataList.count == 9 {

var lastSum:CGFloat = 0

for index in 9..<arr.count{

lastSum = lastSum + arr[index]

}

dataList.append([lastSum])

left = left + lastSum

num += 1

}else if num < arr.count-2{

let second = arr[num+1]

if (item+second)/(1.0-left) > 0.45{

dataList.append([item,second])

num += 2

left = left + item + second

}else if num < arr.count-3{

let third = arr[num+2]

dataList.append([item,second,third])

num += 3

left = left + item + second + third

}

}

}

return dataList

}

//求和

func sumDatas(arr:[CGFloat]) -> CGFloat {

guard arr.count > 0 else {

return 0

}

var sum:CGFloat = 0

for item in arr {

sum += item

}

return sum

}

2.UI绘制 难点，计算每个不同颜色的子块的大小和位置

var left:CGFloat = 0

var hasSum:CGFloat = 0

var top:CGFloat = 0

let width = self.frame.width

let height = self.frame.height

var sumIndex = 0

let newArr =  makeDownDatas(arr: datas)

for (index,array) in newArr.enumerated() {

let sum = sumDatas(arr: array)

let w = index%2 == 0 ? (width - left)*sum/(1.0-hasSum) : (width-left)

let h = index%2 == 0 ?                    (height-top) : (height-top)*sum/(1.0-hasSum)

var subTop = top

var subLeft = left

for (_,item) in array.enumerated(){

let subW = index%2 == 0 ? w : w * item/sum

let subH = index%2 == 0 ? h*item/sum : h

let sep = UIView(frame: CGRect(x: subLeft, y: subTop, width: subW, height: subH))

sep.backgroundColor = colors[sumIndex]

let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapViewForReloadDatas(tap:)))

let lab = UILabel(frame: CGRect(x: 5, y: 5, width: (subW-10 < 20 ? subW : subW-10), height: (subH < 10 ? 0 : 10)))

lab.textColor = UIColor.white

lab.text = "\(item)"

lab.font = UIFont.systemFont(ofSize: 10)

subLeft = subLeft + (index%2 == 0 ? 0 : w*item/sum)

subTop = subTop + (index%2 == 0 ? h*item/sum : 0)

sumIndex += 1

}

hasSum += sum

left = left + (index%2 == 0 ? w : 0)

top = top + (index%2 == 0 ? 0 : h)

}

}

index%2 == 0 为蓝色模块的计算下标符合的条件

index%2 == 1 为绿色模块的计算下标符合的条件

left 为当前计算模块的左边距，right为当前计算模块的上边距

hasSum 为已经计算过的数据的和

sumIndex 为子数据的计算下标，注意和模块的下标index的区别  （每个模块里可能有1-3个子数据）

subTop、subLeft 为子数据相对于所在模块的上边距和左边距

subW、subH为子数据的宽和高

@objc func tapViewForReloadDatas(tap:UITapGestureRecognizer) -> Void {

UIView.animate(withDuration: 0.7) {

for item in self.subviews{

item.alpha = 0

}

}

let subDatas = [CGFloat(0.28),CGFloat(0.2),CGFloat(0.18),CGFloat(0.16),CGFloat(0.10),CGFloat(0.06),CGFloat(0.02)]

let rect = tap.view?.frame

let hotMap = HotMapView(frame:self.bounds)

hotMap.transform = CGAffineTransform.init(scaleX: rect!.width/self.frame.width, y: rect!.height/self.frame.height)

hotMap.center = tap.view!.center

UIView.animate(withDuration: 0.5) {

hotMap.transform = CGAffineTransform.identity

hotMap.center = CGPoint(x: self.frame.width*0.5, y: self.frame.height*0.5)

}

}

0人点赞

• 推荐
• 评论
• 收藏
• 共同学习，写下你的评论

0/150