我正在使用“图表”库在我的iOS应用程序中绘制烛台图表。
如何在限制线上贴标签,如下图所示?
据我所知,我必须为Y轴创建自定义渲染器并覆盖绘制限制线和/或Y轴标签的方法。到目前为止,我设法实现了这个screenshot,但标签没有附加到限制线的右端并且具有静态位置,这意味着如果我缩放或拖动图表它不能正确移动轴上的其他标签。截至目前,Y标签由图表自动生成。
我试着按照这个例子,但它对我不起作用:Custom view of Limit Line in MPAndroidChart
你能告诉我到底要做什么来制作限制线,它的标签在示例图像上看起来像什么?因为我是iOS编程的新手,所以有一个详细的解释+代码会很高兴。
好吧,所以在对Y轴渲染器进行一些修补之后,我设法实现了这种外观和行为。
因此,为了获得这种外观,您必须:
setDrawLabelsEnabled()
并将参数设置为false
来禁用默认限制线标签internal func drawYLabels(...)
以为每个限制线绘制额外的标签。请参阅下面的代码。chart.leftAxis.xOffset = 10.0
chart.leftAxis.yOffset = 0.0
这是新的internal func drawYLabels(...)
方法的代码片段:
internal func drawYLabels(
context: CGContext,
fixedPosition: CGFloat,
positions: [CGPoint],
offset: CGFloat,
textAlign: NSTextAlignment)
{
guard
let yAxis = self.axis as? YAxis
else { return }
let labelFont = yAxis.labelFont
let labelTextColor = yAxis.labelTextColor
let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1
let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1)
for i in stride(from: from, to: to, by: 1)
{
let text = yAxis.getFormattedLabel(i)
ChartUtils.drawText(
context: context,
text: " " + text + " ", // Adding some spaces infront and after the label to make some additional space for the bigger "limit line" labels
point: CGPoint(x: fixedPosition, y: positions[i].y + offset),
align: textAlign,
attributes: [NSAttributedString.Key.font: labelFont, NSAttributedString.Key.foregroundColor: labelTextColor])
}
// This is where we start to draw labels for limit lines
let myTransformer = self.transformer
for line in yAxis.limitLines {
let point = myTransformer!.pixelForValues(x: 0.0, y: line.limit)
let text = (" " + line.label + " ") as NSString // Adding some spaces to the label in order to make some additional space for the label
let size = text.size(withAttributes: [NSAttributedString.Key.font: labelFont, NSAttributedString.Key.foregroundColor: UIColor.darkGray, NSAttributedString.Key.backgroundColor: UIColor.green])
var labelPoint: CGPoint?
// Drawing the triangle in front of the custom label
let trianglePath = UIBezierPath()
if yAxis.axisDependency == .right {
labelPoint = CGPoint(x: fixedPosition + (size.height * 0.3), y: point.y - (size.height / 2))
if textAlign == .center
{
labelPoint!.x -= size.width / 2.0
}
else if textAlign == .right
{
labelPoint!.x -= size.width
}
trianglePath.move(to: CGPoint(x: labelPoint!.x - size.height * 0.375, y: labelPoint!.y + (size.height / 2)))
trianglePath.addLine(to: CGPoint(x: labelPoint!.x, y: labelPoint!.y + (size.height * 0.78)))
trianglePath.addLine(to: CGPoint(x: labelPoint!.x, y: labelPoint!.y + (size.height * 0.22)))
} else {
labelPoint = CGPoint(x: 0.0, y: point.y - (size.height / 2))
trianglePath.move(to: CGPoint(x: labelPoint!.x + size.width * 1.175, y: labelPoint!.y + (size.height / 2)))
trianglePath.addLine(to: CGPoint(x: labelPoint!.x + size.width, y: labelPoint!.y + (size.height * 0.78)))
trianglePath.addLine(to: CGPoint(x: labelPoint!.x + size.width, y: labelPoint!.y + (size.height * 0.22)))
}
NSUIGraphicsPushContext(context)
// Drawing the custom label itself
(text as NSString).draw(at: labelPoint!, withAttributes: [NSAttributedString.Key.font: labelFont, NSAttributedString.Key.foregroundColor: UIColor.darkGray, NSAttributedString.Key.backgroundColor: UIColor.green])
trianglePath.close()
// Drawing the triangle with the same color as the limit line and it's label
line.lineColor.setFill()
trianglePath.fill()
NSUIGraphicsPopContext()
}
}
最终结果如下:screenshot
这个实现并不是最干净的,但至少它对我有用。如果我的话中有些不清楚,请随意提问。