如何使用ios-charts创建浮动图标记

Rob*_*ack 13 ios swift ios-charts

我正在使用ios-charts框架,并希望创建一个标记,当我触摸并从一侧移动到另一侧时,浮动在图形上.我使用折线图仅供参考.

但是,当我触摸它时,我无法弄清楚如何在图表上获得标记的位置.

我读过有关继承MarkerView的子类,但这不起作用.你能告诉我如何获得触摸ios图表时出现的点的位置吗?

Rob*_*ack 26

所以我终于让这个工作,并希望将它添加到社区.这是我的图表的样子:

在此输入图像描述

当您在图表上方移动手指时,上方的阅读器会移动并从图表中读取值.

要实现这一点,我必须执行以下操作:

  1. 在要实现图形的文件中,请确保包含 ChartViewDelegate

  2. 然后实现chartValueSelected方法.

  3. 如果您随后使用getMarkerPosition方法,则可以将"标记"置于任何您想要的位置.

这是一些示例代码:

class MarkerView: UIView {
    @IBOutlet var valueLabel: UILabel!
    @IBOutlet var metricLabel: UILabel!
    @IBOutlet var dateLabel: UILabel!
}

let markerView = MarkerView()

func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, dataSetIndex: Int, highlight: ChartHighlight) { 

    let graphPoint = chartView.getMarkerPosition(entry: entry,  highlight: highlight)

    // Adding top marker
    markerView.valueLabel.text = "\(entry.value)"
    markerView.dateLabel.text = "\(months[entry.xIndex])"
    markerView.center = CGPointMake(graphPoint.x, markerView.center.y)
    markerView.hidden = false

}
Run Code Online (Sandbox Code Playgroud)

markerView是一个xib,我手动添加到主视图,也包含图形视图.markerView是一个包含三个标签的UIView.这是3.0,印象,4月你在图片中看到.

graphPoint是CGPoint位于图表上.你可以使用它的x和y graphPoint重新定位你的markerView.在这里,我只是保持相同的y值markerView并改变它的x值,使其在触摸时来回移动.

  • 所以忘记带有 3 个标签的顶部标记,你如何在值上绘制垂直线和圆圈?@RobNorback (2认同)
  • @RobNorback 伙计,我怎样才能在不使用 xib 的情况下实现这一目标? (2认同)

Dog*_*fee 7

这是基于iOS-Charts存储库中提供的示例BallonMarker

希望这对某人有用,因为我找不到其他子类示例,MarkerImage所以这对我来说是很多CGContext以前从未使用过的线索和错误

在此处输入图片说明

要使用添加这个类

class PillMarker: MarkerImage {

    private (set) var color: UIColor
    private (set) var font: UIFont
    private (set) var textColor: UIColor
    private var labelText: String = ""
    private var attrs: [NSAttributedString.Key: AnyObject]!

    static let formatter: DateComponentsFormatter = {
        let f = DateComponentsFormatter()
        f.allowedUnits = [.minute, .second]
        f.unitsStyle = .short
        return f
    }()

    init(color: UIColor, font: UIFont, textColor: UIColor) {
        self.color = color
        self.font = font
        self.textColor = textColor

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center
        attrs = [.font: font, .paragraphStyle: paragraphStyle, .foregroundColor: textColor, .baselineOffset: NSNumber(value: -4)]
        super.init()
    }

    override func draw(context: CGContext, point: CGPoint) {
        // custom padding around text
        let labelWidth = labelText.size(withAttributes: attrs).width + 10
        // if you modify labelHeigh you will have to tweak baselineOffset in attrs
        let labelHeight = labelText.size(withAttributes: attrs).height + 4

        // place pill above the marker, centered along x
        var rectangle = CGRect(x: point.x, y: point.y, width: labelWidth, height: labelHeight)
        rectangle.origin.x -= rectangle.width / 2.0
        let spacing: CGFloat = 20
        rectangle.origin.y -= rectangle.height + spacing

        // rounded rect
        let clipPath = UIBezierPath(roundedRect: rectangle, cornerRadius: 6.0).cgPath
        context.addPath(clipPath)
        context.setFillColor(UIColor.white.cgColor)
        context.setStrokeColor(UIColor.black.cgColor)
        context.closePath()
        context.drawPath(using: .fillStroke)

        // add the text
        labelText.draw(with: rectangle, options: .usesLineFragmentOrigin, attributes: attrs, context: nil)
    }

    override func refreshContent(entry: ChartDataEntry, highlight: Highlight) {
        labelText = customString(entry.y)
    }

    private func customString(_ value: Double) -> String {
        let formattedString = PillMarker.formatter.string(from: TimeInterval(value))!
        // using this to convert the left axis values formatting, ie 2 min
        return "\(formattedString)"
    }
}
Run Code Online (Sandbox Code Playgroud)

然后为您的图表激活

let marker = PillMarker(color: .white, font: UIFont.boldSystemFont(ofSize: 14), textColor: .black)
chartView.marker = marker
Run Code Online (Sandbox Code Playgroud)