iOS Charts库的简单使用 - BarChartView

iOS Charts库的简单使用 - BarChartView

iOS Charts库的简单使用 - PieChartView

iOS Charts库的简单使用 - LineChartView

iOS Charts库的简单使用 - CombinedChartView

Charts 库各类之间属性基本互通,可相互参考,更多属性参看 iOS Charts库的简单使用 - BarChartView

更多使用方法及属性参考 MPAndroidChart 文档:MPAndroidChart Documentation

最后附上 demo,demo有个别错误未修改,请甄别。




BarChartView 的部分属性及简单使用

开局一张简单的柱状图

let barChartView = BarChartView(frame: CGRect(x: 0, y: 500, width: UIScreen.main.bounds.width, height: 200))
view.addSubview(barChartView)

var entries = [BarChartDataEntry]()
for i in 0...10 {
    let entry = BarChartDataEntry(x: Double(i), y: Double(arc4random_uniform(50)))
    entries.append(entry)
}

let set = BarChartDataSet(entries: entries, label: "图例")
let data = BarChartData(dataSet: set)
barChartView.data = data
image.png
HorizontalBarChartView
image.png
BarChartView 属性
//柱状条后面画一个灰色区域,表示最大值。默认 false
barChartView.drawBarShadowEnabled = true
image.png
//显示顶部文字。默认 true
barChartView.drawValueAboveBarEnabled = false
image.png
//在圆柱左右两端各增加一半的条宽。默认 false
barChartView.fitBars = true
image.png
// x、y轴动画
barChartView.animate(xAxisDuration: 1)
barChartView.animate(yAxisDuration: 1)
//barChartView.animate(xAxisDuration: 1, yAxisDuration: 1)
//空表时显示的文字
barChartView.noDataText = "暂无数据"
//空表时显示的文字大小
barChartView.noDataFont = .systemFont(ofSize: 20)
//空表时显示的文字颜色
barChartView.noDataTextColor = .orange
//空表时显示的文字位置
barChartView.noDataTextAlignment = .center
//平移拖动。默认 true
barChartView.dragEnabled = true
//x轴滑动(包括放大后)。默认true
//barChartView.dragXEnabled = true
//y轴滑动(包括放大后)。默认true
//barChartView.dragYEnabled = true

//x轴缩放 默认true
barChartView.scaleXEnabled = true
//y轴缩放 默认true
barChartView.scaleYEnabled = true
//触控放大
barChartView.pinchZoomEnabled = false
//双击放大图表。默认true
barChartView.doubleTapToZoomEnabled = true
//拖动后图表是否继续滚动。默认true
barChartView.dragDecelerationEnabled = true
//减速摩擦系数,间隔0-1,如果将其设置为0,它将立即停止,1是无效值,并将自动转换为0.9999。默认0.9
barChartView.dragDecelerationFrictionCoef = 0.9
//当图表完全缩小的时候,每一次拖动都会高亮显示在图标视图上。默认true
barChartView.highlightPerDragEnabled = true
//设置最大高亮距离(dp)。在图表中的点击位置距离条目的距离超过此距离不会触发高亮显示。默认500
barChartView.maxHighlightDistance = 500
//设置为false后,禁止点击手势高亮显示值,值仍然可以通过拖动或编程方式突出显示。默认true
barChartView.highlightPerTapEnabled = true
//y轴自动缩放
barChartView.autoScaleMinMaxEnabled = false
//是否绘制网格背景。默认false
barChartView.drawGridBackgroundEnabled = true
//网格背景颜色
barChartView.gridBackgroundColor = .purple
image.png
//是否绘制图表边框,绘制后就不需要绘制x轴和y轴的轴线了。默认false
barChartView.drawBordersEnabled = true
//图表边框颜色。默认black
barChartView.borderColor = .red
//图表边框宽度。默认1.0
barChartView.borderLineWidth = 3
image.png
//默认NO
barChartView.clipValuesToContentEnabled = false
//false时,则柱状图(x轴线)下方不裁剪突出的显示(图表放大后可看出效果)。默认true
barChartView.clipDataToContentEnabled = true
//图表周围的最小偏移量,值越大图表越小。
barChartView.minOffset = 50
//图表偏移量(上)。
barChartView.extraTopOffset = 50
//图表偏移量(下)。
barChartView.extraBottomOffset = 50
//图表偏移量(左)。
barChartView.extraLeftOffset = 50
//图表偏移量(右)。
barChartView.extraRightOffset = 50

//barChartView.setExtraOffsets(left: 0, top: 0, right: 0, bottom: 0)
//默认YES
barChartView.drawMarkers = true
let markerView = MarkerView()
markerView.chartView = barChartView;
barChartView.marker = markerView;
//自定义的maskView
let maskView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
maskView.backgroundColor = .red
markerView.addSubview(maskView)
image.png
let chartDescription = Description()
chartDescription.position = CGPoint(x: 220, y: 120)
chartDescription.text = "图表描述文字"
chartDescription.textAlign = .right
chartDescription.font = .systemFont(ofSize: 30)
chartDescription.textColor = .red
barChartView.chartDescription = chartDescription
image.png
//是否有图例。默认true
barChartView.legend.enabled = true
barChartView.legend.formSize = 20
barChartView.legend.font = .systemFont(ofSize: 30)
barChartView.legend.textColor = .red
barChartView.legend.horizontalAlignment = .right
barChartView.legend.orientation = .vertical
//换行
barChartView.legend.wordWrapEnabled = true
//比例
barChartView.legend.maxSizePercent = 0.95
image.png
//仅适用于堆叠式(stacked),当为true时,点击圆柱时即使只选中了一个堆栈条目,也会高亮整条圆柱。默认false
barChartView.highlightFullBarEnabled = false
//绘制值的最大项数,大于此值的条目号将导致value-label消失。默认100
barChartView.maxVisibleCount = 100
//刷新图表

barChartView.notifyDataSetChanged()
barChartView.data?.notifyDataChanged()
xAxis x轴
let xAxis = barChartView.xAxis
//是否显示x轴。默认true
xAxis.enabled = true
//默认5.0
xAxis.xOffset = 5.0
//偏移量。改变值时文字位置不变,图表整体上移或下移距离的大小。默认5.0
xAxis.yOffset = 5.0 
//绘制x轴的标签。默认true
xAxis.drawLabelsEnabled = true
//标签文字大小。默认10
xAxis.labelFont = .systemFont(ofSize: 10)
//标签文字颜色。默认black
xAxis.labelTextColor = .black
//将轴标签居中,而不是将它们画在原来的位置。默认false
xAxis.centerAxisLabelsEnabled = false
//显示x轴的轴线。默认true
xAxis.drawAxisLineEnabled = true
//轴线的颜色。默认gray
xAxis.axisLineColor = .red
//轴线的宽度。默认0.5
xAxis.axisLineWidth = 2
//默认0
xAxis.axisLineDashPhase = 0
//轴线的虚线效果
xAxis.axisLineDashLengths = [5]
image.png
//显示网格线。默认true
xAxis.drawGridLinesEnabled = true
//网格线的颜色
xAxis.gridColor = .red
//网格线的宽度。默认0.5
xAxis.gridLineWidth = 2
xAxis.gridLineDashPhase = 0
//网格线的虚线效果,间距值
xAxis.gridLineDashLengths = [5]
image.png
//粒度。为false时,如果两个相邻的轴值四舍五入到相同的值,则轴值可能重复。默认false
xAxis.granularityEnabled = true
//granularityEnabled = true时,设置x轴标签显示,例如:设置3则每隔两个柱子显示一个标签。默认1
xAxis.granularity = 3
image.png
//x轴显示数量,默认6,全部显示柱子,不可滑动。
//搭配设置setVisibleXRangeMaximum则可滑动。需要在设置完 barChartView.data 后设置 setVisibleXRangeMaximum
xAxis.labelCount = 6

......省略代码

barChartView.data = data
barChartView.setVisibleXRangeMaximum(6)
image.png
//标签格式化,设置后则titles显示换成0开始的序列号
let formatter = NumberFormatter();
formatter.positivePrefix = "第";
formatter.positiveSuffix = "个";
xAxis.valueFormatter = DefaultAxisValueFormatter(formatter: formatter)
image.png
let values = ["1#", "2#", "3#", "4#", "5#", "6#", "7#", "8#", "9#", "10#", "11#"]
xAxis.valueFormatter =  IndexAxisValueFormatter(values: values)

xAxis.labelCount = values.count
image.png
//不强制绘制指定数量的label
xAxis.forceLabelsEnabled = false
//设置最小值
xAxis.axisMinimum = 2
//设置最大值
xAxis.axisMaximum = 6

//撤销axisMinimum设置的最小值
//xAxis.resetCustomAxisMax()
//撤销axisMaximum设置的最大值
//xAxis.resetCustomAxisMin()
image.png
//第一条数据距最左端距离,相当于偏移几个单位量。默认0.5
xAxis.spaceMin = 2
//最后一条数据距最左端距离,相当于偏移几个单位量。默认0.5
xAxis.spaceMax = 2
image.png
//x轴标签文字倾斜度(图表会上移)。默认0.0
xAxis.labelRotationAngle = .pi * 8
image.png
//x轴第一个和最后一个标签条目超过图表边缘时剪切。默认false
xAxis.avoidFirstLastClippingEnabled = false
//x轴文字位置。默认top
xAxis.labelPosition = .bottom
image.png
//x轴标签文字换行。默认false
xAxis.wordWrapEnabled = true
//wordWrapEnabled == true时,x轴标签显示宽度的百分比。默认1.0
xAxis.wordWrapWidthPercent = 1.0
//限制线位置。true时,线在圆柱后面。false时,线在圆柱前面。默认false
xAxis.drawLimitLinesBehindDataEnabled = false
//添加限制线
let limit7 = ChartLimitLine(limit: 7, label: "7");
//添加到Y轴上
xAxis.addLimitLine(limit7)
//
////添加限制线
let limit3 = ChartLimitLine(limit: 3, label: "3");
limit3.lineDashLengths = [6]
limit3.lineColor = .orange
limit3.valueTextColor = .red
limit3.lineWidth = 5
limit3.labelPosition = .bottomLeft
limit3.valueFont = .systemFont(ofSize: 20)
//添加到Y轴上
xAxis.addLimitLine(limit3)
image.png
leftAxis y轴

属性参考 xAxis

//偏移量。改变值时图表位置不变,y轴标签文字右移距离的大小。默认5.0
leftAxis.xOffset = 5.0
//y轴最大值
leftAxis.axisMaximum = 100
//y值最小值,不设置此值在stacked时,圆柱悬空(不从x轴线开始)
leftAxis.axisMinimum = 0
//显示y轴底部标签项,默认true
leftAxis.drawBottomYLabelEntryEnabled = true
//显示y轴顶部标签项,默认true
leftAxis.drawTopYLabelEntryEnabled = true
//柱状图是否倒置,默认false
leftAxis.inverted = true
image.png
//是否显示y轴零线。默认false
leftAxis.drawZeroLineEnabled = true
//y轴零线颜色。默认gray
leftAxis.zeroLineColor = .red
//y轴零线宽度。默认1.0
leftAxis.zeroLineWidth = 5
//默认0.0
leftAxis.zeroLineDashPhase = 0
//y轴零线虚线效果
leftAxis.zeroLineDashLengths = [5, 8]
image.png
barChartView.backgroundColor = .lightGray
//最大值到顶部所占整个轴的百分比,默认0.1
leftAxis.spaceTop = 0.5
//最小值到底部所占整个轴的百分比,默认0.1
leftAxis.spaceBottom = 0.3
image.png
//y轴标签的显示位置 
leftAxis.labelPosition = .outsideChart
//y轴文字的对齐方式 
leftAxis.labelAlignment = .left
//y轴标签的水平偏移量。大于0则y轴标签文字往右移动,小于0往左
leftAxis.labelXOffset = 10

//y轴最小宽度
leftAxis.minWidth = 20
//y轴最大宽度
leftAxis.maxWidth = 50
rightAxis
let rightAxis = barChartView.rightAxis

属性参考 leftAxis

data

BarChartDataSet
let set = BarChartDataSet(entries: entries, label: "图例")
//圆柱颜色
set.setColor(.red)
let formatter = NumberFormatter()
formatter.positiveSuffix = "%"
formatter.positivePrefix = "+"
set.valueFormatter = DefaultValueFormatter(formatter: formatter)
image.png
//高亮显示
set.highlightEnabled = true
//高亮显示颜色
set.highlightColor = .purple
//高亮颜色透明度
set.highlightAlpha = 0.6
//圆柱边宽。默认0.0
set.barBorderWidth = 3
//圆柱边色。默认black
set.barBorderColor = .red
//圆柱阴影色。(red: 215.0/255.0, green: 215.0/255.0, blue: 215.0/255.0, alpha: 1.0)
set.barShadowColor = .orange
image.png
//圆柱上是否显示文字
set.drawValuesEnabled = false 
BarChartData
//显示柱状图顶部文字。默认true
data.setDrawValues(true)
data.setValueFont(.systemFont(ofSize: 20))
data.setValueTextColor(.red)
//圆柱和间距的比例,默认0.85
data.barWidth = 0.3
image.png
单柱
        var entries = [BarChartDataEntry]()
        for i in 0...10 {
            let entry = BarChartDataEntry(x: Double(i), y: Double(arc4random_uniform(50)))
            entries.append(entry)
        }
        
        let set = BarChartDataSet(entries: entries, label: "图例")
        let data = BarChartData(dataSet: set)
        barChartView.data = data
image.png
GroupData
let datas: [[Double]] = [[78, 32, 23, 35, 78, 15], [12, 22, 57, 8, 56, 28], [19, 67, 35, 21, 57, 20]]

var dataSetMax: Double = 0
let groupSpace = 0.4
let barSpace = 0.03
//柱子宽度((barSpace + barWidth) * 系列数 + groupSpace = 1.00 -> interval per "group")
let barWidth = 0.17

var dataSets = [BarChartDataSet]()
for i in 0..<datas.count {
   var yValues = [BarChartDataEntry]()
   var set = BarChartDataSet()
   
   let data = datas[i]
   for j in 0..<data.count {
       let value = data[j]
       dataSetMax = max(value, dataSetMax)
       yValues.append(BarChartDataEntry(x: Double(j), y: value))
       
       set = BarChartDataSet(entries: yValues, label: "第\(i)个图例")
       set.setColor(UIColor(red: CGFloat(arc4random() % 256) / 255.0, green: CGFloat(arc4random() % 256) / 255.0, blue: CGFloat(arc4random() % 256) / 255.0, alpha: 1.0))
       set.valueColors = [.red]
   }
   dataSets.append(set)
}

dataSetMax = (dataSetMax + dataSetMax * 0.1)

barChartView.leftAxis.axisMaximum = dataSetMax
barChartView.leftAxis.axisMinimum = 0

let data = BarChartData(dataSets: dataSets)
data.barWidth = barWidth
data.groupBars(fromX: -0.5, groupSpace: groupSpace, barSpace: barSpace)

barChartView.data = data
image.png
StackedData
let datas: [[Double]] = [[30, 30, 30], [35, 78, 15], [12, 22, 57], [8, 56, 28], [19, 67, 35]]
let stackLabels = ["Label1", "Label2", "Label3"]

var entries = [BarChartDataEntry]()
for i in 0..<datas.count {
    var total: Double = 0
    let data = datas[i]
    for j in 0..<data.count {
        total += data[j]
    }
    
    var num: Double = 0
    var yValues = [Double]()
    for i in 0..<data.count {
        num = data[i] * 100.0 / total
        yValues.append(num)
    }
    
    let entry = BarChartDataEntry(x: Double(i), yValues: yValues)
    entries.append(entry)
}

let set = BarChartDataSet(entries: entries, label: "图例")
set.stackLabels = stackLabels
set.colors = ChartColorTemplates.vordiplom()

let data = BarChartData(dataSet: set)
barChartView.data = data
image.png

IChartAxisValueFormatter

barChartView.xAxis.valueFormatter = self

自定义 x轴 文字

func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    return "#\(value)"
}

ChartViewDelegate

barChartView.delegate = self
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
    // 点击
}

func chartValueNothingSelected(_ chartView: ChartViewBase) {
    // 没有选择任何内容或取消选择
}

func chartViewDidEndPanning(_ chartView: ChartViewBase) {
    // 停止在图表上的值之间移动
}

func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat) {
    // 缩放图表
}

func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat) {
    // 拖动手势移动/转换图表
}

func chartView(_ chartView: ChartViewBase, animatorDidStop animator: Animator) {
    // 停止动画
}

TIPS

如果图表数据为空仍想展示图表,暂时没找到其它方法,下面也算是曲线救国吧。如果您有好的办法希望可以私信告诉我,谢谢。

判断 entries 为空时,添加一条数据 BarChartDataEntry(x: -10000, y: -10000) ,记得设置 axisMinimumaxisMaximum

barChartView.xAxis.axisMinimum = 0
barChartView.xAxis.axisMaximum = 100

barChartView.leftAxis.axisMinimum = 0
barChartView.leftAxis.axisMaximum = 200

barChartView.rightAxis.enabled = false

var entries = [BarChartDataEntry]()
for i in 0...10 {
    let entry = BarChartDataEntry(x: Double(i), y: Double(arc4random_uniform(50)))
    // entries.append(entry)
}

if entries.isEmpty {
    entries.append(BarChartDataEntry(x: -10000, y: -10000))
}
let set = BarChartDataSet(entries: entries, label: "图例")
let data = BarChartData(dataSet: set)
barChartView.data = data
image.png

2022.07.28 更新

在此感谢大佬 lchenwanli 对于我和 那些傲慢的404 问题的回复,

设置柱体成圆角

BarChartRenderer 类中方法 @objc open func drawDataSet(context: CGContext, dataSet: IBarChartDataSet, index: Int) { }context.fill(barRect) 代码注释掉,换成如下代码:

context.beginPath()
context.move(to: CGPoint(
    x: barRect.origin.x,
    y: barRect.origin.y))

// 右上
context.addArc(tangent1End: CGPoint(x: barRect.origin.x + barRect.width, y: barRect.origin.y),
               tangent2End: CGPoint(x: barRect.origin.x + barRect.width, y: barRect.origin.y + barRect.height), radius: 12);

// 右下
context.addArc(tangent1End: CGPoint(x: barRect.origin.x + barRect.width, y: barRect.origin.y + barRect.height),
               tangent2End: CGPoint(x: barRect.origin.x, y: barRect.origin.y + barRect.height), radius: 12);

// 左下
context.addArc(tangent1End: CGPoint(x: barRect.origin.x, y: barRect.origin.y + barRect.height),
               tangent2End: CGPoint(x: barRect.origin.x, y: barRect.origin.y), radius: 12);

// 左上
context.addArc(tangent1End: CGPoint(x: barRect.origin.x, y: barRect.origin.y),
               tangent2End: CGPoint(x: barRect.origin.x + barRect.width, y: barRect.origin.y), radius: 3);

context.fillPath()
image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容