我正在使用Objective-C创建一个iOS应用程序,需要使用ios-charts。
现在我面临的问题是找不到向我的图表视图添加标记的方法。
此外,我需要通过用户操作更改Y轴数据集,但我不知道如何实现此功能。
谢谢您的帮助。
现在我面临的问题是找不到向我的图表视图添加标记的方法。
此外,我需要通过用户操作更改Y轴数据集,但我不知道如何实现此功能。
谢谢您的帮助。
很不幸,在库本身中没有显示带有文本标记的类。在github提供的示例中有BalloonMarker类,但它未包含在库中。因此,您可以使用来自github示例的BalloonMarker,或者以下是另一种简单的标记类,您可以使用它代替。我认为它可能比BallonMarker更容易理解和定制:
class ChartMarker: MarkerView {
var text = ""
override func refreshContent(entry: ChartDataEntry, highlight: Highlight) {
super.refreshContent(entry: entry, highlight: highlight)
text = String(entry.y)
}
override func draw(context: CGContext, point: CGPoint) {
super.draw(context: context, point: point)
var drawAttributes = [NSAttributedStringKey : Any]()
drawAttributes[.font] = UIFont.systemFont(ofSize: 15)
drawAttributes[.foregroundColor] = UIColor.white
drawAttributes[.backgroundColor] = UIColor.darkGray
self.bounds.size = (" \(text) " as NSString).size(withAttributes: drawAttributes)
self.offset = CGPoint(x: 0, y: -self.bounds.size.height - 2)
let offset = self.offsetForDrawing(atPoint: point)
drawText(text: " \(text) " as NSString, rect: CGRect(origin: CGPoint(x: point.x + offset.x, y: point.y + offset.y), size: self.bounds.size), withAttributes: drawAttributes)
}
func drawText(text: NSString, rect: CGRect, withAttributes attributes: [NSAttributedStringKey : Any]? = nil) {
let size = text.size(withAttributes: attributes)
let centeredRect = CGRect(x: rect.origin.x + (rect.size.width - size.width) / 2.0, y: rect.origin.y + (rect.size.height - size.height) / 2.0, width: size.width, height: size.height)
text.draw(in: centeredRect, withAttributes: attributes)
}
}
并将其与给定的图表一起使用:
let marker = ChartMarker()
marker.chartView = chartView
chartView.marker = marker
将以下代码和 BalloonMarker 类添加到 Charts->Components 文件夹中:
var charts = LineChartView()
let marker:BalloonMarker = BalloonMarker(color: UIColor(red: 93/255, green: 186/255, blue: 215/255, alpha: 1), font: UIFont(name: "Helvetica", size: 12)!, textColor: UIColor.white, insets: UIEdgeInsets(top: 7.0, left: 7.0, bottom: 25.0, right: 7.0))
marker.minimumSize = CGSize(width: 75.0, height: 35.0)//CGSize(75.0, 35.0)
charts.marker = marker
//气球标记类
import Foundation
import CoreGraphics
import UIKit
open class BalloonMarker: MarkerImage
{
open var color: UIColor?
open var arrowSize = CGSize(width: 15, height: 11)
open var font: UIFont?
open var textColor: UIColor?
open var insets = UIEdgeInsets()
open var minimumSize = CGSize()
fileprivate var label: String?
fileprivate var _labelSize: CGSize = CGSize()
fileprivate var _paragraphStyle: NSMutableParagraphStyle?
fileprivate var _drawAttributes = [String : AnyObject]()
public init(color: UIColor, font: UIFont, textColor: UIColor, insets: UIEdgeInsets)
{
super.init()
self.color = color
self.font = font
self.textColor = textColor
self.insets = insets
_paragraphStyle = NSParagraphStyle.default.mutableCopy() as? NSMutableParagraphStyle
_paragraphStyle?.alignment = .center
}
open override func offsetForDrawing(atPoint point: CGPoint) -> CGPoint
{
let size = self.size
var point = point
point.x -= size.width / 2.0
point.y -= size.height
return super.offsetForDrawing(atPoint: point)
}
open override func draw(context: CGContext, point: CGPoint)
{
guard let label = label else { return }
let offset = self.offsetForDrawing(atPoint: point)
let size = self.size
var rect = CGRect(
origin: CGPoint(
x: point.x + offset.x,
y: point.y + offset.y),
size: size)
rect.origin.x -= size.width / 2.0
rect.origin.y -= size.height
context.saveGState()
if let color = color
{
context.setFillColor(color.cgColor)
context.beginPath()
context.move(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width,
y: rect.origin.y))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x + (rect.size.width + arrowSize.width) / 2.0,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x + rect.size.width / 2.0,
y: rect.origin.y + rect.size.height))
context.addLine(to: CGPoint(
x: rect.origin.x + (rect.size.width - arrowSize.width) / 2.0,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y + rect.size.height - arrowSize.height))
context.addLine(to: CGPoint(
x: rect.origin.x,
y: rect.origin.y))
context.fillPath()
}
rect.origin.y += self.insets.top
rect.size.height -= self.insets.top + self.insets.bottom
UIGraphicsPushContext(context)
label.draw(in: rect, withAttributes: _drawAttributes)
UIGraphicsPopContext()
context.restoreGState()
}
open override func refreshContent(entry: ChartDataEntry, highlight: Highlight)
{
setLabel(String(entry.y))
}
open func setLabel(_ newLabel: String)
{
label = newLabel
_drawAttributes.removeAll()
_drawAttributes[NSFontAttributeName] = self.font
_drawAttributes[NSParagraphStyleAttributeName] = _paragraphStyle
_drawAttributes[NSForegroundColorAttributeName] = self.textColor
_labelSize = label?.size(attributes: _drawAttributes) ?? CGSize.zero
var size = CGSize()
size.width = _labelSize.width + self.insets.left + self.insets.right
size.height = _labelSize.height + self.insets.top + self.insets.bottom
size.width = max(minimumSize.width, size.width)
size.height = max(minimumSize.height, size.height)
self.size = size
}
}
基于这篇答案,介绍了ChartMarker
类。我已将其更新到Swift 5并进行了清理,减少了不必要的分配,提高了可读性。
class ChartMarker: MarkerView {
private var text = String()
private let drawAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 15),
.foregroundColor: UIColor.white,
.backgroundColor: UIColor.darkGray
]
override func refreshContent(entry: ChartDataEntry, highlight: Highlight) {
text = String(entry.y)
}
override func draw(context: CGContext, point: CGPoint) {
super.draw(context: context, point: point)
let sizeForDrawing = text.size(withAttributes: drawAttributes)
bounds.size = sizeForDrawing
offset = CGPoint(x: -sizeForDrawing.width / 2, y: -sizeForDrawing.height - 4)
let offset = offsetForDrawing(atPoint: point)
let originPoint = CGPoint(x: point.x + offset.x, y: point.y + offset.y)
let rectForText = CGRect(origin: originPoint, size: sizeForDrawing)
drawText(text: text, rect: rectForText, withAttributes: drawAttributes)
}
private func drawText(text: String, rect: CGRect, withAttributes attributes: [NSAttributedString.Key: Any]? = nil) {
let size = bounds.size
let centeredRect = CGRect(
x: rect.origin.x + (rect.size.width - size.width) / 2,
y: rect.origin.y + (rect.size.height - size.height) / 2,
width: size.width,
height: size.height
)
text.draw(in: centeredRect, withAttributes: attributes)
}
}
使用方法:
let marker = ChartMarker()
marker.chartView = chartView
chartView.marker = marker
BalloonMarker *marker = [[BalloonMarker alloc] initWithColor:[UIColor colorWithWhite:180/255. alpha:1.0] font:[UIFont systemFontOfSize:12.0] insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0)];
marker.minimumSize = CGSizeMake(80.f, 40.f);
_chartView.marker = marker;
addEntry
添加新条目到数据集并调用notifyDataSetChanged
,或者重新创建一个新的chartData(可能会有性能问题)。https://gist.github.com/jakehoskins/8d668688f62fa93ecf8bf7921428c53f