Хорошо, поэтому после некоторой работы с визуализатором оси Y мне удалось добиться этого вида и поведения.
Таким образом, чтобы получить этот вид, вам необходимо:
- Отключить метку линии ограничения по умолчанию, вызвав
setDrawLabelsEnabled()
с параметром, установленным в false
- Внести изменения в YAxisRenderer.swift.Ключ должен слегка переделать
internal func drawYLabels(...)
, чтобы нарисовать дополнительные метки для каждой линии ограничения.См. Код ниже. Добавьте смещения по осям X и Y (обеим) следующим образом:
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()
}
}
Окончательный результат выглядит следующим образом: снимок экрана
Эта реализация не является самой чистойно по крайней мере это сработало для меня.Не стесняйтесь задавать вопросы, если что-то неясно в моих словах.