doughnut chart model added
doughnut chart view added doughnut chart added
This commit is contained in:
parent
99b97fd934
commit
396c22f243
@ -67,6 +67,9 @@
|
||||
94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */; };
|
||||
94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */; };
|
||||
94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */; };
|
||||
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69323C9909000BFB94E /* DoughnutChartModel.swift */; };
|
||||
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69523C990BC00BFB94E /* DoughnutChart.swift */; };
|
||||
C695A69823C990C200BFB94E /* DoughnutChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69723C990C200BFB94E /* DoughnutChartView.swift */; };
|
||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; };
|
||||
D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; };
|
||||
D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */; };
|
||||
@ -307,6 +310,9 @@
|
||||
94C2D9A623872DA90006CF46 /* LabelAttributeColorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeColorModel.swift; sourceTree = "<group>"; };
|
||||
94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeImageModel.swift; sourceTree = "<group>"; };
|
||||
94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeActionModel.swift; sourceTree = "<group>"; };
|
||||
C695A69323C9909000BFB94E /* DoughnutChartModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChartModel.swift; sourceTree = "<group>"; };
|
||||
C695A69523C990BC00BFB94E /* DoughnutChart.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChart.swift; sourceTree = "<group>"; };
|
||||
C695A69723C990C200BFB94E /* DoughnutChartView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChartView.swift; sourceTree = "<group>"; };
|
||||
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = "<group>"; };
|
||||
D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
||||
D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSLayoutConstraintAxis+Extension.swift"; sourceTree = "<group>"; };
|
||||
@ -530,6 +536,7 @@
|
||||
01EB368723609801006832FA /* Molecules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C695A69323C9909000BFB94E /* DoughnutChartModel.swift */,
|
||||
01EB368923609801006832FA /* ListItemModel.swift */,
|
||||
01EB368A23609801006832FA /* MoleculeStackItemModel.swift */,
|
||||
01EB368B23609801006832FA /* MoleculeStackModel.swift */,
|
||||
@ -542,6 +549,14 @@
|
||||
path = Molecules;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0A5D59C323AD488600EFD9E9 /* Protocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0AA33B322398134B0067DD0F /* Primitive Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -580,14 +595,6 @@
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0A5D59C323AD488600EFD9E9 /* Protocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D213347423842FE3008E41B3 /* Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -785,6 +792,8 @@
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
|
||||
017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */,
|
||||
C695A69523C990BC00BFB94E /* DoughnutChart.swift */,
|
||||
C695A69723C990C200BFB94E /* DoughnutChartView.swift */,
|
||||
);
|
||||
path = Molecules;
|
||||
sourceTree = "<group>";
|
||||
@ -1296,6 +1305,7 @@
|
||||
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */,
|
||||
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */,
|
||||
D29DF24D21E6A177003B2FB9 /* MFTextField.m in Sources */,
|
||||
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
|
||||
94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */,
|
||||
017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */,
|
||||
D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */,
|
||||
@ -1396,6 +1406,7 @@
|
||||
D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */,
|
||||
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
|
||||
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */,
|
||||
C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */,
|
||||
D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */,
|
||||
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
||||
D2A514592211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m in Sources */,
|
||||
@ -1404,6 +1415,7 @@
|
||||
0105618D224BBE7700E1557D /* FormValidator.swift in Sources */,
|
||||
01509D912327ECE600EF99AA /* CornerLabels.swift in Sources */,
|
||||
D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */,
|
||||
C695A69823C990C200BFB94E /* DoughnutChartView.swift in Sources */,
|
||||
D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */,
|
||||
946EE1BA237B66D80036751F /* ModelHelper.swift in Sources */,
|
||||
01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */,
|
||||
|
||||
85
MVMCoreUI/Models/Molecules/DoughnutChartModel.swift
Normal file
85
MVMCoreUI/Models/Molecules/DoughnutChartModel.swift
Normal file
@ -0,0 +1,85 @@
|
||||
//
|
||||
// DoughnutChartModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Murugan, Vimal on 10/01/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class DoughnutChartModel: MoleculeProtocol {
|
||||
|
||||
public var backgroundColor: String?
|
||||
public static var identifier: String = "doughnutChart"
|
||||
public var title: LabelModel?
|
||||
public var subtitle: LabelModel?
|
||||
public var sections: [ChartItemModel]
|
||||
public var lineWidth: CGFloat = 30.0
|
||||
public var lineGap: CGFloat = 0.05 //For 3px gap
|
||||
public var spaceRequired = true
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case list
|
||||
case title
|
||||
case subtitle
|
||||
case sections
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.title = try typeContainer.decodeMoleculeIfPresent(codingKey: .title) as? LabelModel
|
||||
self.subtitle = try typeContainer.decodeMoleculeIfPresent(codingKey: .subtitle) as? LabelModel
|
||||
//self.sections = try typeContainer.decodeMolecules(codingKey: .sections) as! [ChartItemModel]
|
||||
|
||||
//TODO: Hasve to check with scott
|
||||
self.sections = []
|
||||
guard var container = try? typeContainer.nestedUnkeyedContainer(forKey: .sections) else {
|
||||
return
|
||||
}
|
||||
var sections = [ChartItemModel]()
|
||||
while !container.isAtEnd {
|
||||
if let element = try container
|
||||
.decodeIfPresent(ChartItemModel.self) {
|
||||
sections.append(element)
|
||||
}
|
||||
}
|
||||
self.sections = sections
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeModelIfPresent(title, forKey: .title)
|
||||
try container.encodeModelIfPresent(subtitle, forKey: .subtitle)
|
||||
try container.encodeModels(sections as [Model], forKey: .sections)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objcMembers public class ChartItemModel: MoleculeProtocol {
|
||||
public var backgroundColor: String?
|
||||
public var label: LabelModel
|
||||
public var percent: CGFloat
|
||||
public var color: String
|
||||
public static var identifier: String = "chartItem"
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case label
|
||||
case percent
|
||||
case color
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.label = try typeContainer.decodeMolecule(codingKey: .label) as! LabelModel
|
||||
self.percent = try typeContainer.decode(CGFloat.self, forKey: .percent)
|
||||
self.color = try typeContainer.decode(String.self, forKey: .color)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeModel(label, forKey: .label)
|
||||
try container.encode(percent, forKey: .percent)
|
||||
try container.encode(color, forKey: .color)
|
||||
}
|
||||
}
|
||||
179
MVMCoreUI/Molecules/DoughnutChart.swift
Normal file
179
MVMCoreUI/Molecules/DoughnutChart.swift
Normal file
@ -0,0 +1,179 @@
|
||||
//
|
||||
// DoughnutChart.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Murugan, Vimal on 07/01/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class DoughnutChart: View, MVMCoreUIViewConstrainingProtocol {
|
||||
|
||||
var containerView = MVMCoreUICommonViewsUtility.commonView()
|
||||
var containerLayer = CALayer()
|
||||
var titleLabel = Label.commonLabelH3(true)
|
||||
var subTitleLabel = Label.commonLabelB2(true)
|
||||
var doughnutChartModel: DoughnutChartModel? {
|
||||
get { return model as? DoughnutChartModel }
|
||||
}
|
||||
var labelContainer = ViewConstrainingView.empty()
|
||||
var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
private var sizeObject = MFStyler.sizeObjectGeneric(forCurrentDevice: 150)!
|
||||
//private var lineSizeObject = MFStyler.sizeObjectGeneric(forCurrentDevice: 30)!
|
||||
|
||||
var height: CGFloat = 150 {
|
||||
didSet {
|
||||
if height != oldValue {
|
||||
sizeObject = MFStyler.sizeObjectGeneric(forCurrentDevice: height)!
|
||||
updateContainer()
|
||||
drawGraph()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
titleLabel.updateView(size)
|
||||
subTitleLabel.updateView(size)
|
||||
updateContainer()
|
||||
drawGraph()
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
titleLabel.reset()
|
||||
subTitleLabel.reset()
|
||||
clearLayers()
|
||||
}
|
||||
|
||||
public func setAsMolecule() {
|
||||
titleLabel.setAsMolecule()
|
||||
subTitleLabel.setAsMolecule()
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
guard containerView.superview == nil else {
|
||||
return
|
||||
}
|
||||
addSubview(containerView)
|
||||
addSubview(labelContainer)
|
||||
|
||||
labelContainer.addSubview(titleLabel)
|
||||
labelContainer.addSubview(subTitleLabel)
|
||||
titleLabel.textAlignment = .center
|
||||
subTitleLabel.textAlignment = .center
|
||||
|
||||
//Make label font size to adjust width if label content is high
|
||||
titleLabel.numberOfLines = 1
|
||||
titleLabel.adjustsFontSizeToFitWidth = true
|
||||
|
||||
containerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
||||
containerView.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||
bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
|
||||
trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
|
||||
containerView.layer.addSublayer(containerLayer)
|
||||
heightConstraint = containerView.heightAnchor.constraint(equalToConstant:
|
||||
sizeObject.getValueBasedOnApplicationWidth())
|
||||
heightConstraint?.isActive = true
|
||||
containerView.widthAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true
|
||||
|
||||
labelContainer.leftPin = labelContainer.leftAnchor.constraint(greaterThanOrEqualTo: containerView.leftAnchor, constant: lineWidth())
|
||||
labelContainer.leftPin?.isActive = true
|
||||
labelContainer.topPin = labelContainer.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor, constant: lineWidth())
|
||||
labelContainer.topPin?.isActive = true
|
||||
labelContainer.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
|
||||
labelContainer.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
|
||||
|
||||
NSLayoutConstraint.constraintPinSubview(titleLabel, pinTop: true, pinBottom: false, pinLeft: true, pinRight: true)
|
||||
NSLayoutConstraint.constraintPinSubview(subTitleLabel, pinTop: false, pinBottom: true, pinLeft: true, pinRight: true)
|
||||
_ = NSLayoutConstraint(pinFirstView: titleLabel, toSecondView: subTitleLabel, withConstant: 0, directionVertical: true)
|
||||
//Rotate view for initial draw
|
||||
containerLayer.transform = CATransform3DMakeRotation(1 * .pi, 0.0, 0.0, 1.0)
|
||||
|
||||
}
|
||||
|
||||
open override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
clearLayers()
|
||||
guard let doughnutChartModel = model as? DoughnutChartModel else {
|
||||
return
|
||||
}
|
||||
titleLabel.setWithModel(doughnutChartModel.title, delegateObject, additionalData)
|
||||
subTitleLabel.setWithModel(doughnutChartModel.subtitle, delegateObject, additionalData)
|
||||
titleLabel.textAlignment = .center
|
||||
subTitleLabel.textAlignment = .center
|
||||
//lineSizeObject = MFStyler.sizeObjectGeneric(forCurrentDevice: doughnutChartModel.lineWidth)!
|
||||
updateLabelContainer()
|
||||
drawGraph()
|
||||
}
|
||||
|
||||
func drawGraph() {
|
||||
clearLayers()
|
||||
let widthHeight = sizeObject.getValueBasedOnApplicationWidth()
|
||||
containerLayer.frame = CGRect(x: 0, y: 0,
|
||||
width: widthHeight,
|
||||
height: widthHeight)
|
||||
if let doughnutChart = doughnutChartModel {
|
||||
var prevPercent: CGFloat = 0.0
|
||||
//If Single item in array. We don't need gap
|
||||
doughnutChartModel?.lineGap = (doughnutChart.sections.count == 1) ? 0.0 : doughnutChart.lineGap
|
||||
for model in doughnutChart.sections {
|
||||
prevPercent += drawBar(model, prevPercent, doughnutChart.spaceRequired, doughnutChart.lineGap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func drawBar(_ chartModel: ChartItemModel, _ prevPercent: CGFloat, _ spaceRequired: Bool, _ lineGap: CGFloat) -> CGFloat {
|
||||
|
||||
let shapeLayer = CAShapeLayer()
|
||||
shapeLayer.frame = containerLayer.frame
|
||||
shapeLayer.lineWidth = lineWidth()
|
||||
//lineSizeObject.getValueBasedOnApplicationWidth()
|
||||
shapeLayer.fillColor = nil
|
||||
shapeLayer.strokeColor = UIColor.mfGet(forHex: chartModel.color).cgColor
|
||||
|
||||
let arcCenter = shapeLayer.position
|
||||
let radius = shapeLayer.bounds.size.width / 2.0 - lineWidth()/2.0
|
||||
//lineSizeObject.getValueBasedOnApplicationWidth() / 2.0
|
||||
let clockwise = true
|
||||
|
||||
let value: CGFloat = chartModel.percent
|
||||
let gap: CGFloat = spaceRequired ? lineGap : 0.0
|
||||
let startAngle = ((prevPercent / 100.0) * 2 * .pi) - (0.5 * .pi)
|
||||
let endAngle = ((value / 100.0) * 2 * .pi) + startAngle - gap
|
||||
let circlePath = UIBezierPath(arcCenter: arcCenter,
|
||||
radius: radius,
|
||||
startAngle: startAngle,
|
||||
endAngle: endAngle,
|
||||
clockwise: clockwise)
|
||||
|
||||
shapeLayer.path = circlePath.cgPath
|
||||
containerLayer.addSublayer(shapeLayer)
|
||||
return value
|
||||
}
|
||||
|
||||
func clearLayers() {
|
||||
containerLayer.sublayers?.forEach({ $0.removeFromSuperlayer() })
|
||||
}
|
||||
|
||||
func updateContainer() {
|
||||
heightConstraint?.constant = sizeObject.getValueBasedOnApplicationWidth()
|
||||
updateLabelContainer()
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
func lineWidth() -> CGFloat {
|
||||
return doughnutChartModel?.lineWidth ?? 30
|
||||
//lineSizeObject.getValueBasedOnApplicationWidth() + 5
|
||||
}
|
||||
|
||||
func updateLabelContainer() {
|
||||
labelContainer.leftPin?.constant = lineWidth()
|
||||
labelContainer.topPin?.constant = lineWidth()
|
||||
labelContainer.setNeedsDisplay()
|
||||
}
|
||||
|
||||
}
|
||||
179
MVMCoreUI/Molecules/DoughnutChartView.swift
Normal file
179
MVMCoreUI/Molecules/DoughnutChartView.swift
Normal file
@ -0,0 +1,179 @@
|
||||
//
|
||||
// DoughnutChartView.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Murugan, Vimal on 26/12/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class DoughnutChartView: View {
|
||||
|
||||
var doughnutChart = DoughnutChart(frame: CGRect.zero)
|
||||
var colorLablesStack = ColorViewLabelsStack()
|
||||
var container = MVMCoreUICommonViewsUtility.commonView()
|
||||
var doughnutChartModel: DoughnutChartModel? {
|
||||
get { return model as? DoughnutChartModel }
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
guard container.superview == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
addSubview(container)
|
||||
doughnutChart.translatesAutoresizingMaskIntoConstraints = false
|
||||
container.addSubview(doughnutChart)
|
||||
colorLablesStack.translatesAutoresizingMaskIntoConstraints = false
|
||||
container.addSubview(colorLablesStack)
|
||||
|
||||
NSLayoutConstraint.constraintPinSubview(container, pinTop: true, pinBottom: true, pinLeft: true, pinRight: true)
|
||||
doughnutChart.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
|
||||
doughnutChart.topAnchor.constraint(equalTo: container.topAnchor, constant: PaddingFour).isActive = true
|
||||
container.bottomAnchor.constraint(greaterThanOrEqualTo: doughnutChart.bottomAnchor).isActive = true
|
||||
|
||||
let containerBottomAnchor = container.bottomAnchor.constraint(equalTo: doughnutChart.bottomAnchor)
|
||||
containerBottomAnchor.priority = UILayoutPriority(rawValue: 200)
|
||||
containerBottomAnchor.isActive = true
|
||||
|
||||
let colorLablesBottomAnchor = container.bottomAnchor.constraint(equalTo: colorLablesStack.bottomAnchor)
|
||||
colorLablesBottomAnchor.priority = UILayoutPriority(rawValue: 204)
|
||||
colorLablesBottomAnchor.isActive = true
|
||||
|
||||
let colorLablesTopAnchor = colorLablesStack.topAnchor.constraint(equalTo: doughnutChart.topAnchor)
|
||||
colorLablesTopAnchor.priority = UILayoutPriority(rawValue: 204)
|
||||
colorLablesTopAnchor.isActive = true
|
||||
|
||||
colorLablesStack.topAnchor.constraint(greaterThanOrEqualTo: doughnutChart.topAnchor).isActive = true
|
||||
container.bottomAnchor.constraint(greaterThanOrEqualTo: colorLablesStack.bottomAnchor).isActive = true
|
||||
container.trailingAnchor.constraint(greaterThanOrEqualTo: colorLablesStack.trailingAnchor).isActive = true
|
||||
|
||||
let centerY = colorLablesStack.centerYAnchor.constraint(equalTo: doughnutChart.centerYAnchor)
|
||||
centerY.priority = .defaultLow
|
||||
centerY.isActive = true
|
||||
|
||||
colorLablesStack.leadingAnchor.constraint(equalTo: doughnutChart.trailingAnchor, constant: PaddingThree).isActive = true
|
||||
colorLablesStack.backgroundColor = UIColor.clear
|
||||
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
doughnutChart.updateView(size)
|
||||
colorLablesStack.updateView(size)
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
colorLablesStack.reset()
|
||||
}
|
||||
|
||||
open override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
doughnutChart.clearLayers()
|
||||
colorLablesStack.removeAllItemViews()
|
||||
doughnutChart.setWithModel(model, delegateObject, additionalData)
|
||||
colorLablesStack.setWithModel(model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
if model == nil {
|
||||
let data = try! JSONSerialization.data(withJSONObject: json!)
|
||||
let decoder = JSONDecoder()
|
||||
let model = try! decoder.decode(DoughnutChartModel.self, from: data)
|
||||
setWithModel(model, delegateObject, additionalData as? [String : AnyHashable])
|
||||
} else {
|
||||
setWithModel(model, delegateObject, additionalData as? [String : AnyHashable])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ColorViewLabelsStack: MoleculeStackView {
|
||||
|
||||
var dougnutChartModel: DoughnutChartModel?
|
||||
|
||||
override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
let previousModel = self.dougnutChartModel
|
||||
removeAllItemViews()
|
||||
guard let dougnutChartModel = model as? DoughnutChartModel else {
|
||||
return
|
||||
}
|
||||
var items: [StackItem]?
|
||||
if previousModel?.sections.count == dougnutChartModel.sections.count {
|
||||
items = stackItems
|
||||
}
|
||||
stackItems = []
|
||||
self.model = MoleculeStackModel(molecules: [])
|
||||
for (index, chartItemModel) in dougnutChartModel.sections.enumerated() {
|
||||
let colorViewWithLabel = items?[index].view as? ColorViewWithLabel ?? ColorViewWithLabel()
|
||||
colorViewWithLabel.setWithModel(chartItemModel, delegateObject, additionalData)
|
||||
addView(colorViewWithLabel, lastItem: index == dougnutChartModel.sections.count - 1)
|
||||
}
|
||||
self.dougnutChartModel = dougnutChartModel
|
||||
restack()
|
||||
}
|
||||
}
|
||||
|
||||
class ColorViewWithLabel: View, MVMCoreUIViewConstrainingProtocol {
|
||||
|
||||
var label = Label.commonLabelB2(true)
|
||||
var colorView = MVMCoreUICommonViewsUtility.commonView()
|
||||
private var sizeObject = MFStyler.sizeObjectGeneric(forCurrentDevice: 8)!
|
||||
var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
override func setupView() {
|
||||
super.setupView()
|
||||
guard colorView.superview == nil else {
|
||||
return
|
||||
}
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(colorView)
|
||||
addSubview(label)
|
||||
|
||||
heightConstraint = colorView.heightAnchor.constraint(equalToConstant: sizeObject.getValueBasedOnApplicationWidth())
|
||||
heightConstraint?.isActive = true
|
||||
colorView.widthAnchor.constraint(equalTo: colorView.heightAnchor).isActive = true
|
||||
colorView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
||||
colorView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
|
||||
|
||||
label.leadingAnchor.constraint(equalTo: colorView.trailingAnchor, constant: PaddingOne).isActive = true
|
||||
label.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||
trailingAnchor.constraint(greaterThanOrEqualTo: label.trailingAnchor).isActive = true
|
||||
bottomAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
|
||||
|
||||
}
|
||||
|
||||
override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
label.updateView(size)
|
||||
heightConstraint?.constant = sizeObject.getValueBased(onSize: size)
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
override func reset() {
|
||||
super.reset()
|
||||
label.reset()
|
||||
}
|
||||
|
||||
func setAsMolecule() {
|
||||
label.setAsMolecule()
|
||||
}
|
||||
|
||||
override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let chartItemModel = model as? ChartItemModel else {
|
||||
return
|
||||
}
|
||||
label.setWithModel(chartItemModel.label, delegateObject, additionalData)
|
||||
colorView.backgroundColor = UIColor.mfGet(forHex: chartItemModel.color)
|
||||
}
|
||||
|
||||
override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
Label.setUILabel(label, withJSON: json?.optionalDictionaryForKey("label"), delegate: delegateObject, additionalData: additionalData)
|
||||
colorView.backgroundColor = UIColor.mfGet(forHex: json?.optionalStringForKey("color") ?? "#000000")
|
||||
}
|
||||
|
||||
}
|
||||
@ -68,7 +68,8 @@
|
||||
@"dropDownListItem": DropDownFilterTableViewCell.class,
|
||||
@"headlineBodyButton": HeadlineBodyButton.class,
|
||||
@"eyebrowHeadlineBodyLink": EyebrowHeadlineBodyLink.class,
|
||||
@"stackItem": StackItem.class
|
||||
@"stackItem": StackItem.class,
|
||||
@"doughnutChart": DoughnutChartView.class
|
||||
} mutableCopy];
|
||||
});
|
||||
return mapping;
|
||||
|
||||
@ -29,5 +29,6 @@ import Foundation
|
||||
ModelRegistry.register(LabelAttributeUnderlineModel.self)
|
||||
ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
|
||||
ModelRegistry.register(LabelAttributeActionModel.self)
|
||||
ModelRegistry.register(DoughnutChartModel.self)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user