1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
// DataRenderer.swift
// Charts
//
// 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 CoreGraphics
@objc(ChartDataRendererBase)
open class DataRenderer: Renderer
{
/// An array of accessibility elements that are presented to the ChartViewBase accessibility methods.
///
/// Note that the order of elements in this array determines the order in which they are presented and navigated by
/// Accessibility clients such as VoiceOver.
///
/// Renderers should ensure that the order of elements makes sense to a client presenting an audio-only interface to a user.
/// Subclasses should populate this array in drawData() or drawDataSet() to make the chart accessible.
@objc final var accessibleChartElements: [NSUIAccessibilityElement] = []
@objc public let animator: Animator
@objc public init(animator: Animator, viewPortHandler: ViewPortHandler)
{
self.animator = animator
super.init(viewPortHandler: viewPortHandler)
}
@objc open func drawData(context: CGContext)
{
fatalError("drawData() cannot be called on DataRenderer")
}
@objc open func drawValues(context: CGContext)
{
fatalError("drawValues() cannot be called on DataRenderer")
}
@objc open func drawExtras(context: CGContext)
{
fatalError("drawExtras() cannot be called on DataRenderer")
}
/// Draws all highlight indicators for the values that are currently highlighted.
///
/// - Parameters:
/// - indices: the highlighted values
@objc open func drawHighlighted(context: CGContext, indices: [Highlight])
{
fatalError("drawHighlighted() cannot be called on DataRenderer")
}
/// An opportunity for initializing internal buffers used for rendering with a new size.
/// Since this might do memory allocations, it should only be called if necessary.
@objc open func initBuffers() { }
@objc open func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool
{
guard let data = dataProvider?.data else { return false }
return data.entryCount < Int(CGFloat(dataProvider?.maxVisibleCount ?? 0) * viewPortHandler.scaleX)
}
/// Creates an ```NSUIAccessibilityElement``` that acts as the first and primary header describing a chart view.
///
/// - Parameters:
/// - chart: The chartView object being described
/// - data: A non optional data source about the chart
/// - defaultDescription: A simple string describing the type/design of Chart.
/// - Returns: A header ```NSUIAccessibilityElement``` that can be added to accessibleChartElements.
@objc internal func createAccessibleHeader(usingChart chart: ChartViewBase,
andData data: ChartData,
withDefaultDescription defaultDescription: String = "Chart") -> NSUIAccessibilityElement
{
let chartDescriptionText = chart.chartDescription?.text ?? defaultDescription
let dataSetDescriptions = data.dataSets.map { $0.label ?? "" }
let dataSetDescriptionText = dataSetDescriptions.joined(separator: ", ")
let dataSetCount = data.dataSets.count
let
element = NSUIAccessibilityElement(accessibilityContainer: chart)
element.accessibilityLabel = chartDescriptionText + ". \(dataSetCount) dataset\(dataSetCount == 1 ? "" : "s"). \(dataSetDescriptionText)"
element.accessibilityFrame = chart.bounds
element.isHeader = true
return element
}
}