You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中使用DGCharts v4.0添加坐标轴标题的方法

适配DGCharts v4.0实现坐标轴标题(指定红线位置)

问题背景

我们正在将代码适配DGCharts v4.0(原Charts库),此前用于添加X、Y轴标题的方案已失效,原因是找不到ChartUtils类。希望将坐标轴标题显示在图中红线位置:
坐标轴标题期望位置

旧失效代码如下:

// MARK: Y-Axis titles.
private extension LineChartYAxisRenderer {
    func renderTitle(title: String, inContext context: CGContext, x: CGFloat) {
        var foregroundColor = UIColor.darkGray

        if #available(iOS 13.0, *) {
            foregroundColor = UIColor.secondaryLabel
        }
        
        let attributes: [NSAttributedString.Key: Any] = [
            .font: self.axis.labelFont,
            .foregroundColor: foregroundColor
        ]
        
        // Determine the chart title's y-position.
        let titleSize = title.size(withAttributes: attributes)
        let verticalTitleSize = CGSize(width: titleSize.height, height: titleSize.width)
        let point = CGPoint(x: x, y: ((viewPortHandler.chartHeight - verticalTitleSize.height) / 2)-30)
        
        // Render the chart title.
        ChartUtils.drawText(context: context,
                            text: title,
                            point: point,
                            attributes: attributes,
                            anchor: .zero,
                            angleRadians: .pi / -2)
    }
}

解决方案

DGCharts v4.0移除了ChartUtils类,我们可以用Core Graphics原生文本绘制API替代,同时自定义坐标轴Renderer来实现标题渲染:

1. 自定义Y轴Renderer,实现标题绘制逻辑

通过扩展LineChartYAxisRenderer并自定义子类,在渲染流程中添加标题绘制:

private extension LineChartYAxisRenderer {
    func renderYAxisTitle(_ title: String, inContext context: CGContext) {
        // 配置文本样式
        var textColor = UIColor.darkGray
        if #available(iOS 13.0, *) {
            textColor = UIColor.secondaryLabel
        }
        let attributes: [NSAttributedString.Key: Any] = [
            .font: axis.labelFont,
            .foregroundColor: textColor
        ]
        
        // 计算旋转后的文本尺寸
        let titleSize = title.size(withAttributes: attributes)
        let rotatedSize = CGSize(width: titleSize.height, height: titleSize.width)
        
        // 计算标题位置:垂直居中,左侧偏移匹配红线位置
        let xPos: CGFloat = viewPortHandler.offsetLeft - rotatedSize.width - 15 // 可调整偏移量
        let yPos: CGFloat = viewPortHandler.chartHeight / 2 + titleSize.width / 2
        
        // 保存上下文状态,绘制旋转文本
        context.saveGState()
        context.translateBy(x: xPos, y: yPos)
        context.rotate(by: -CGFloat.pi / 2)
        
        let attributedText = NSAttributedString(string: title, attributes: attributes)
        attributedText.draw(at: CGPoint(x: 0, y: -titleSize.height / 2))
        
        context.restoreGState()
    }
}

// 自定义Renderer子类,重写render方法添加标题绘制
class CustomYAxisRenderer: LineChartYAxisRenderer {
    var yAxisTitle: String?
    
    override func render(context: CGContext) {
        super.render(context: context)
        guard let title = yAxisTitle else { return }
        renderYAxisTitle(title, inContext: context)
    }
}

2. 为图表配置自定义Renderer

在初始化图表时,替换默认的Y轴Renderer并设置标题:

// 假设你的图表实例为lineChartView
let customYRenderer = CustomYAxisRenderer(
    viewPortHandler: lineChartView.viewPortHandler,
    axis: lineChartView.leftAxis,
    transformer: lineChartView.getTransformer(forAxis: .left)
)
customYRenderer.yAxisTitle = "Y轴标题"
lineChartView.leftAxisRenderer = customYRenderer

3. X轴标题实现思路

如果需要实现X轴标题,可参照上述逻辑扩展LineChartXAxisRenderer,无需旋转文本,直接计算底部居中或指定位置的坐标即可。

关键说明

  • 用NSAttributedString.draw(at:)替代了原ChartUtils.drawText,是Core Graphics原生兼容DGCharts v4.0的方案。
  • 基于viewPortHandler的布局参数计算位置,保证标题在图表视图内适配不同屏幕。
  • 可通过调整xPos的偏移值(如示例中的-15)微调标题与Y轴的距离,精准匹配红线位置。

内容的提问来源于stack exchange,提问作者user9062458

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:35:22