提问人:RL2000 提问时间:3/18/2023 更新时间:3/18/2023 访问量:70
MacOS 中的图表标记视图不显示
Charts MarkerView in MacOS won't display
问:
这个问题是关于 DanielGindi/Charts 的,但我认为即使你不熟悉这个库,一些渲染知识也可能会有所帮助。NSView
Charts
我在 MacOS 项目中使用,但无法正确显示。我已将 ChartsDemo-iOS 项目复制到 ChartsDemo-macOS,以便在 MacOS 中使用它。但是,当我单击图表中的值时,标记永远不会出现在视图中。Charts
MarkerView
RadarMarkerView
RadarDemoViewController
以下是完整的实现:RadarMarkerViewMac
public class RadarMarkerViewMac: MarkerView {
@IBOutlet var label: NSTextField!
public override func awakeFromNib() {
self.offset.x = -self.frame.size.width / 2.0
self.offset.y = -self.frame.size.height - 7.0
}
public override func refreshContent(entry: ChartDataEntry, highlight: Highlight) {
label.stringValue = String.init(format: "%.3f %%", (entry.y))
_ = self // see note 2
layout() // see note 1
}
}
如果您查看原始的 RadarMarkerView,就会发现只有两个值得注意的变化:
layoutIfNeeded()
更改为 因为 中不存在前一个函数。layout()
NSView
- 我把这条线放在那里,这样我就可以添加一个断点来查看是否正确绘制(当暂停断点时,将鼠标悬停在 ,然后单击眼球按钮查看视图)。
self
self
我发现的奇怪事情是:单击图表会突出显示所选值,但不显示标记。但是,当我在行上放置一个断点,然后使用预览弹出窗口查看时,我看到视图很好......然后,一旦我继续运行应用程序,标记就会在所有后续选择中按应有的方式显示在图表中,即使禁用了断点也是如此。layout()
self
我认为,同样需要注意的是,如果我输入断点并且没有显示预览,则标记将不会显示在图表上。
我认为这与渲染有关,但我无法使应用程序在此处正常运行。你能帮忙吗?NSView
答:
仅复制 是不够的。RadarMarkerView
您需要为 macOS 创建相应的 xib。在 in 中加载来自 xib 的视图,并将其添加为可见区域之外的子视图,以便可以渲染它:RadarDemoViewController
viewDidLoad
let marker = RadarMarkerView.viewFromXib()!
marker.chartView = radarChartView
radarChartView.marker = marker
self.view.addSubview(marker)
marker.frame = NSRect(x: -100, y: -100, width: 64, height: 64)
正如在 MarkerView 中看到的那样,使用了一个属性,它基本上对应于 .nsuiLayer
self.layer
因此,您需要指定希望视图使用图层作为其后备存储。
public required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
wantsLayer = true
}
您可以定义偏移量(取决于视图的大小):
open override func offsetForDrawing(atPoint point: CGPoint) -> CGPoint {
return CGPoint(x: -36, y: -40)
}
在指定视图需要布局阶段才能绘制refreshContent
needsLayout = true
所以完整的看起来像这样:RadarMarkerView
import AppKit
import Charts
public class RadarMarkerView: MarkerView {
@IBOutlet var label: NSTextField!
public required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
wantsLayer = true
}
open override func draw(context: CGContext, point: CGPoint) {
// NSColor.red.setFill()
// NSRect(x: point.x - 32, y: point.y - 32, width: 64, height: 64).fill()
super.draw(context: context, point: point)
}
open override func offsetForDrawing(atPoint point: CGPoint) -> CGPoint {
return CGPoint(x: -36, y: -40)
}
public override func refreshContent(entry: ChartDataEntry, highlight: Highlight) {
label.stringValue = String.init(format: "%d %%", Int(round(entry.y)))
needsLayout = true
}
}
请注意 的覆盖。为了简化调试,可以通过编程方式绘制一个红色矩形(只需取消注释两行即可)。draw(context:point:)
测试
如您所见,然后显示标记。
评论