doughnut chart model added

doughnut chart view added
doughnut chart added
This commit is contained in:
Murugan, Vimal 2020-01-11 16:06:25 +05:30
parent 99b97fd934
commit 396c22f243
6 changed files with 466 additions and 9 deletions

View File

@ -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 */,

View 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)
}
}

View 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()
}
}

View 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")
}
}

View File

@ -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;

View File

@ -29,5 +29,6 @@ import Foundation
ModelRegistry.register(LabelAttributeUnderlineModel.self)
ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
ModelRegistry.register(LabelAttributeActionModel.self)
ModelRegistry.register(DoughnutChartModel.self)
}
}