diff --git a/ChartsDemo-macOS/ChartsDemo-macOS.xcodeproj/project.pbxproj b/ChartsDemo-macOS/ChartsDemo-macOS.xcodeproj/project.pbxproj index 10e89b3554..d0faaa9a4f 100644 --- a/ChartsDemo-macOS/ChartsDemo-macOS.xcodeproj/project.pbxproj +++ b/ChartsDemo-macOS/ChartsDemo-macOS.xcodeproj/project.pbxproj @@ -16,6 +16,9 @@ 65B3F6421C73B4F5000983D0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B3F6411C73B4F5000983D0 /* AppDelegate.swift */; }; 65B3F6461C73B4F5000983D0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65B3F6451C73B4F5000983D0 /* Assets.xcassets */; }; 65B3F6491C73B4F5000983D0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65B3F6471C73B4F5000983D0 /* Main.storyboard */; }; + 9406FF8D29C4AF1800AC466A /* RadarMarkerViewMac.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9406FF8C29C4AF1800AC466A /* RadarMarkerViewMac.swift */; }; + 9406FF9129C4AF5900AC466A /* RadarMarkerViewMac.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9406FF9029C4AF5900AC466A /* RadarMarkerViewMac.xib */; }; + 9406FF9429C4B1C300AC466A /* radar_marker@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9406FF9329C4B1C300AC466A /* radar_marker@3x.png */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -68,6 +71,9 @@ 65B3F6451C73B4F5000983D0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 65B3F6481C73B4F5000983D0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 65B3F64A1C73B4F5000983D0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9406FF8C29C4AF1800AC466A /* RadarMarkerViewMac.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadarMarkerViewMac.swift; sourceTree = ""; }; + 9406FF9029C4AF5900AC466A /* RadarMarkerViewMac.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RadarMarkerViewMac.xib; sourceTree = ""; }; + 9406FF9329C4B1C300AC466A /* radar_marker@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "radar_marker@3x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -98,6 +104,7 @@ 5B9A0C3B1C83AB2100ED8ED8 /* LineDemoViewController.swift */, 5B9A0C3D1C83AB2B00ED8ED8 /* RadarDemoViewController.swift */, 5B9A0C3F1C83AB3400ED8ED8 /* PieDemoViewController.swift */, + 9406FF9229C4B1C300AC466A /* Resources */, ); path = Demos; sourceTree = ""; @@ -123,6 +130,8 @@ 65B3F6401C73B4F5000983D0 /* ChartsDemo-macOS */ = { isa = PBXGroup; children = ( + 9406FF8B29C4AEE800AC466A /* Components */, + 9406FF8929C4AEC900AC466A /* XIBs */, 5B9A0C381C83AB0600ED8ED8 /* Demos */, 65B3F6411C73B4F5000983D0 /* AppDelegate.swift */, 65B3F6451C73B4F5000983D0 /* Assets.xcassets */, @@ -132,6 +141,31 @@ path = "ChartsDemo-macOS"; sourceTree = ""; }; + 9406FF8929C4AEC900AC466A /* XIBs */ = { + isa = PBXGroup; + children = ( + 9406FF9029C4AF5900AC466A /* RadarMarkerViewMac.xib */, + ); + path = XIBs; + sourceTree = ""; + }; + 9406FF8B29C4AEE800AC466A /* Components */ = { + isa = PBXGroup; + children = ( + 9406FF8C29C4AF1800AC466A /* RadarMarkerViewMac.swift */, + ); + path = Components; + sourceTree = ""; + }; + 9406FF9229C4B1C300AC466A /* Resources */ = { + isa = PBXGroup; + children = ( + 9406FF9329C4B1C300AC466A /* radar_marker@3x.png */, + ); + name = Resources; + path = "ChartsDemo-macOS/Resources"; + sourceTree = SOURCE_ROOT; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -217,8 +251,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9406FF9429C4B1C300AC466A /* radar_marker@3x.png in Resources */, 65B3F6461C73B4F5000983D0 /* Assets.xcassets in Resources */, 65B3F6491C73B4F5000983D0 /* Main.storyboard in Resources */, + 9406FF9129C4AF5900AC466A /* RadarMarkerViewMac.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -232,6 +268,7 @@ 65B3F6421C73B4F5000983D0 /* AppDelegate.swift in Sources */, 5B9A0C3E1C83AB2B00ED8ED8 /* RadarDemoViewController.swift in Sources */, 5B9A0C3A1C83AB1800ED8ED8 /* BarDemoViewController.swift in Sources */, + 9406FF8D29C4AF1800AC466A /* RadarMarkerViewMac.swift in Sources */, 5B9A0C401C83AB3400ED8ED8 /* PieDemoViewController.swift in Sources */, 5B9A0C3C1C83AB2100ED8ED8 /* LineDemoViewController.swift in Sources */, ); diff --git a/ChartsDemo-macOS/ChartsDemo-macOS/Components/RadarMarkerViewMac.swift b/ChartsDemo-macOS/ChartsDemo-macOS/Components/RadarMarkerViewMac.swift new file mode 100644 index 0000000000..6d2fa7fa42 --- /dev/null +++ b/ChartsDemo-macOS/ChartsDemo-macOS/Components/RadarMarkerViewMac.swift @@ -0,0 +1,30 @@ +// +// RadarMarkerViewMac.swift +// ChartsDemo-OSX +// +// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda +// A port of MPAndroidChart for iOS +// Licensed under Apache License 2.0 +// +// https://github.com/danielgindi/Charts +// + +import Foundation +import Charts +#if canImport(AppKit) + import AppKit +#endif + +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: "%.1f %%", (entry.y * 100)) + needsLayout = true + } +} diff --git a/ChartsDemo-macOS/ChartsDemo-macOS/Demos/RadarDemoViewController.swift b/ChartsDemo-macOS/ChartsDemo-macOS/Demos/RadarDemoViewController.swift index 3eecf73224..c9558bd486 100644 --- a/ChartsDemo-macOS/ChartsDemo-macOS/Demos/RadarDemoViewController.swift +++ b/ChartsDemo-macOS/ChartsDemo-macOS/Demos/RadarDemoViewController.swift @@ -38,6 +38,9 @@ open class RadarDemoViewController: NSViewController self.radarChartView.data = data self.radarChartView.chartDescription.text = "Radarchart Demo" + let marker = RadarMarkerViewMac.viewFromXib()! + marker.chartView = radarChartView + radarChartView.marker = marker } override open func viewWillAppear() diff --git a/ChartsDemo-macOS/ChartsDemo-macOS/Resources/radar_marker@3x.png b/ChartsDemo-macOS/ChartsDemo-macOS/Resources/radar_marker@3x.png new file mode 100644 index 0000000000..a84b93b539 Binary files /dev/null and b/ChartsDemo-macOS/ChartsDemo-macOS/Resources/radar_marker@3x.png differ diff --git a/ChartsDemo-macOS/ChartsDemo-macOS/XIBs/RadarMarkerViewMac.xib b/ChartsDemo-macOS/ChartsDemo-macOS/XIBs/RadarMarkerViewMac.xib new file mode 100644 index 0000000000..2d2964c418 --- /dev/null +++ b/ChartsDemo-macOS/ChartsDemo-macOS/XIBs/RadarMarkerViewMac.xib @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Charts/Components/MarkerView.swift b/Source/Charts/Components/MarkerView.swift index d80ad535b3..3001ea5539 100644 --- a/Source/Charts/Components/MarkerView.swift +++ b/Source/Charts/Components/MarkerView.swift @@ -21,7 +21,11 @@ open class MarkerView: NSUIView, Marker { open var offset: CGPoint = CGPoint() - @objc open weak var chartView: ChartViewBase? + @objc open weak var chartView: ChartViewBase? { + didSet { + didAddToChart(chartView) + } + } open func offsetForDrawing(atPoint point: CGPoint) -> CGPoint { @@ -72,14 +76,16 @@ open class MarkerView: NSUIView, Marker } @objc - open class func viewFromXib(in bundle: Bundle = .main) -> MarkerView? + open class func viewFromXib(in bundle: Bundle = .main) -> Self? { #if !os(OSX) return bundle.loadNibNamed( String(describing: self), owner: nil, - options: nil)?[0] as? MarkerView + options: nil)? + .compactMap { $0 as? Self } + .first #else var loadedObjects: NSArray? = NSArray() @@ -87,13 +93,39 @@ open class MarkerView: NSUIView, Marker if bundle.loadNibNamed( NSNib.Name(String(describing: self)), owner: nil, - topLevelObjects: &loadedObjects) + topLevelObjects: &loadedObjects), + let view = loadedObjects?.compactMap({ $0 as? Self }).first { - return loadedObjects?[0] as? MarkerView + view.wantsLayer = true + return view } return nil #endif } + @objc + open func didAddToChart(_ chartView: ChartViewBase?) { + #if os(OSX) + removeFromSuperview() + + // Need to add MarkerView to a view in order to allow it to render out of visible area + guard let chartView else { return } + + var parentView: NSView = chartView + while let grandparentView = parentView.superview { + parentView = grandparentView + } + parentView.addSubview(self) + + // Constrain MarkerView to off-screen, since it's only being used to render in `draw()` function + // and not to display directly as NSView + translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + leadingAnchor.constraint(equalTo: parentView.trailingAnchor, constant: 100.0), + topAnchor.constraint(equalTo: parentView.bottomAnchor, constant: 100.0) + ]) + + #endif + } }