How can I hide 0 values on ios-chart? - ios

I know that it is possible to hide y values when their values are equal to 0 on MPAndroidChart using a custom class for your value formatter (MPAndroidChart: Hide 0 value labels in a stacked bar chart).
Despite this, I am not able to create the same class on Swift 3.0 or get any other way to do this. I tried to "translate" the custom class from Java to Swift 3.0 without success (I can copy the code of what I have tried if you want but it is full of errors).
Is it possible to hide y values when they are equals to 0 on ios-chart library?
P.S: I am using Swift 3.0.
Thanks in advance!

I made it happen on a PieChart in one of my apps just like that :
...
let dataSet = PieChartDataSet(yVals: yVals, label: nil)
// This is where the magic happen
// You set a NSNumberFormatter with an empty zero Symbol
let noZeroFormatter = NumberFormatter()
noZeroFormatter.zeroSymbol = ""
dataSet.valueFormatter = ChartDefaultValueFormatter(formatter: noZeroFormatter)
let chartData = PieChartData(xVals: xVals, dataSet: dataSet)
...

if you want to add % in in your graph as well as hide/remove 0.0 values from graph :
used below lines of code for # Swift 3:-
func updateChartData() {
let chart = PieChartView(frame: mViewOutlet.frame)
// let chart = PieChartView(frame: CGRect(x: 122, y: 235 , width: self.mViewOutlet.frame.size.width, height: self.mViewOutlet.frame.size.height))
// 2. generate chart data entries
let track = ["Present","Leave", "EG/LC", "Halfday", "Absent", "Weeklyoff", "Holidays"]
// let money = [65, 13, 10, 2]
let money = mDaysArray
var entries = [PieChartDataEntry]()
for (index, value) in money.enumerated() {
print("index: \(index) \n value: \(value)")
let entry = PieChartDataEntry()
if value != 0 {
entry.y = Double(value)
}else{
}
entries.append(entry)
// entry.label = track[index] // if we want to remove name label
}
// 3. chart setup
let set = PieChartDataSet( values: entries, label: "Pie Chart")
// this is custom extension method. Download the code for more details.
//4. set chart color
let presentColor = UIColor(red: 80.0/255.0, green: 180.0/255.0, blue: 50.0/255.0, alpha: 1.0)
// let lateColor = UIColor(red: 241.0/255.0, green: 194.0/255.0, blue: 114.0/255.0, alpha: 1.0)
let leaveColor = UIColor(red: 203.0/255.0, green: 68.0/255.0, blue: 242.0/255.0, alpha: 1.0)
let egColor = UIColor(red: 95.0/255.0, green: 180.0/255.0, blue: 239.0/255.0, alpha: 1.0)
let halfdayColor = UIColor(red: 82.0/255.0, green: 64.0/255.0, blue: 152.0/255.0, alpha: 1.0)
let absentColor = UIColor(red: 242.0/255.0, green: 58.0/255.0, blue: 02.0/255.0, alpha: 1.0)
let weekOffColor = UIColor(red: 186.0/255.0, green: 221.0/255.0, blue: 79.0/255.0, alpha: 1.0)
let holidayColor = UIColor(red: 35.0/255.0, green: 215.0/255.0, blue: 179.0/255.0, alpha: 1.0)
let colors: [UIColor] = [presentColor,leaveColor,egColor,halfdayColor,absentColor,weekOffColor,holidayColor]
set.colors = colors
let data = PieChartData(dataSet: set)
let formatter = NumberFormatter()
formatter.numberStyle = .percent
formatter.maximumFractionDigits = 2
formatter.multiplier = 1.0
formatter.percentSymbol = "%"
formatter.zeroSymbol = ""
data.setValueFormatter(DefaultValueFormatter(formatter: formatter))
chart.data = data
chart.noDataText = "No data available"
chart.usePercentValuesEnabled = true
// user interaction
chart.isUserInteractionEnabled = false
let d = Description()
// d.text = "iOSCharts.io"
chart.chartDescription = d
// chart.tintColor = UIColor.black
// chart.centerText = "Pie Chart"
chart.holeRadiusPercent = 0.2
chart.chartDescription?.enabled = false
chart.legend.enabled = false
chart.data?.notifyDataChanged()
chart.notifyDataSetChanged()
chart.setNeedsDisplay()
chart.animate(xAxisDuration: 1.3, yAxisDuration: 1.3)
chart.transparentCircleColor = UIColor.clear
// self.view.addSubview(chart)
self.mPieChartMainView.addSubview(chart)
}

let data = PieChartData(dataSet: set)
let pFormatter = NumberFormatter()
pFormatter.numberStyle = .none
pFormatter.zeroSymbol = "";
pFormatter.maximumFractionDigits = 1
pFormatter.multiplier = 1
pFormatter.percentSymbol = ""
data.setValueFormatter(DefaultValueFormatter(formatter: pFormatter))

Related

How to change UIView "backgroundColor" and resize it appending text in UITextField (validation)? / Swift 5

Hello everyone!) Need some help!)
I have password validation text field and right now I'm setting UI. In text field I have only four rules. I created validation line which is UIView which has width - 348. The width and color of UIView must change every time if we add one rule to text field. If we have four rules, we must divide validation line by four: 348 / 4 = 87, and create four colors for it like red, orange, yellow and green.
How can I make the UIView available to update the width and color every time I add or subtract one rule in text field, like one lowercased character, digits, one uppercased character, ect...?)
Text field with four rules:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = validationTextField.text else { return true }
guard let textRange = Range(range, in: text) else { return true }
let updatedText = text.replacingCharacters(in: textRange, with: string)
//Minimum eight characters
if updatedText.count >= 8 {
eightCharsLablel.text = "⎷ minimum of 8 characters."
eightCharsLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
textFieldValidLineView.frame.size.width = 0 + 87
} else {
eightCharsLablel.text = "– minimum of 8 characters."
eightCharsLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//Minimum one digit
if updatedText.range(of: #"\d+"#, options: .regularExpression) != nil {
oneDigitLablel.text = "⎷ minimum 1 digit."
oneDigitLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
textFieldValidLineView.frame.size.width = 0 + 87
} else {
oneDigitLablel.text = "– minimum 1 digit."
oneDigitLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//Minimum one lowercased
if updatedText.range(of: #".*[a-z]+.*"#, options: .regularExpression) != nil {
oneLowercasedLablel.text = "⎷ minimum 1 lowercased."
oneLowercasedLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
} else {
oneLowercasedLablel.text = "– minimum 1 lowercased."
oneLowercasedLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//Minimum one uppercased
if updatedText.range(of: #".*[A-Z]+.*"#, options: .regularExpression) != nil {
oneUppercasedLablel.text = "⎷ minimum 1 uppercased."
oneUppercasedLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
} else {
oneUppercasedLablel.text = "– minimum 1 uppercased."
oneUppercasedLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//No whitespaces
if updatedText.range(of: #"\s+"#, options: .regularExpression) != nil {
return false
}
return true
}
Thanks for every answer!)
One way to do this that avoids any size calculations is to use a Horizontal UIStackView for your "ValidationLine".
If we set the stack view .distribution = .fillEqually, and then add a view for each "rule", the layout will happen automatically:
Then, to "grow and color" the "line" we can set the background colors of the arranged subviews based on how many rules have been "met":
Here's a complete example you can try out:
class ViewController: UIViewController, UITextFieldDelegate {
let ruleColors: [UIColor] = [
.red, .orange, .yellow, .green,
]
let validationTextField = UITextField()
let eightCharsLablel = UILabel()
let oneDigitLablel = UILabel()
let oneLowercasedLablel = UILabel()
let oneUppercasedLablel = UILabel()
// horizontal Stack View
let validationLineStackView: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.distribution = .fillEqually
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
// add one view for each rule to the validationLineStackView
// we'll set the background colors when we satisfy rules
for _ in 0..<ruleColors.count {
let v = UIView()
v.backgroundColor = .clear
validationLineStackView.addArrangedSubview(v)
}
// put everything in a vertical stack view for this example
let stackView = UIStackView()
stackView.axis = .vertical
stackView.spacing = 8
stackView.addArrangedSubview(validationTextField)
stackView.addArrangedSubview(validationLineStackView)
stackView.addArrangedSubview(eightCharsLablel)
stackView.addArrangedSubview(oneDigitLablel)
stackView.addArrangedSubview(oneLowercasedLablel)
stackView.addArrangedSubview(oneUppercasedLablel)
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// stack view Top/Leading/Trailing with 20-points "padding"
stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
// we'll use the intrinsic heights for the text field and all labels
// but we need to set the height of the validationLineStackView
validationLineStackView.heightAnchor.constraint(equalToConstant: 8.0),
])
// to make it easier to see the text field
validationTextField.borderStyle = .roundedRect
validationTextField.backgroundColor = .cyan
validationTextField.delegate = self
// initial update
updateRulesProgress("")
}
func updateRulesProgress(_ updatedText: String) {
var numRulesMet: Int = 0
//Minimum eight characters
if updatedText.count >= 8 {
eightCharsLablel.text = "⎷ minimum of 8 characters."
eightCharsLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
// increment our "met" rules counter
numRulesMet += 1
} else {
eightCharsLablel.text = "– minimum of 8 characters."
eightCharsLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//Minimum one digit
if updatedText.range(of: #"\d+"#, options: .regularExpression) != nil {
oneDigitLablel.text = "⎷ minimum 1 digit."
oneDigitLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
// increment our "met" rules counter
numRulesMet += 1
} else {
oneDigitLablel.text = "– minimum 1 digit."
oneDigitLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//Minimum one lowercased
if updatedText.range(of: #".*[a-z]+.*"#, options: .regularExpression) != nil {
oneLowercasedLablel.text = "⎷ minimum 1 lowercased."
oneLowercasedLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
// increment our "met" rules counter
numRulesMet += 1
} else {
oneLowercasedLablel.text = "– minimum 1 lowercased."
oneLowercasedLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
//Minimum one uppercased
if updatedText.range(of: #".*[A-Z]+.*"#, options: .regularExpression) != nil {
oneUppercasedLablel.text = "⎷ minimum 1 uppercased."
oneUppercasedLablel.textColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
// increment our "met" rules counter
numRulesMet += 1
} else {
oneUppercasedLablel.text = "– minimum 1 uppercased."
oneUppercasedLablel.textColor = #colorLiteral(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1)
}
// now update the background colors of the views in the validationLineStackView
for i in 0..<validationLineStackView.arrangedSubviews.count {
if i < numRulesMet {
validationLineStackView.arrangedSubviews[i].backgroundColor = ruleColors[numRulesMet - 1]
} else {
validationLineStackView.arrangedSubviews[i].backgroundColor = .clear
}
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = validationTextField.text else { return true }
guard let textRange = Range(range, in: text) else { return true }
let updatedText = text.replacingCharacters(in: textRange, with: string)
// make this the first IF case, since we'll return without allowing the
// text to change -- so no need to check anything else
//No whitespaces
if updatedText.range(of: #"\s+"#, options: .regularExpression) != nil {
return false
}
// move all the rule IFs to the updateRulesProgress function
updateRulesProgress(updatedText)
return true
}
}

LineChart in IOS using (Charts SDK)

Can we draw the verticle lines in every box in given image by using the IOS Charts SDK?
How we can draw those lines like given image?
Every box contains three lines inside it.
Setup The Chart (Code)
var lineChartView = LineChartView()
lineChartView.leftAxis.enabled = true
lineChartView.xAxis.labelCount = 24
lineChartView.legend.form = .none
let leftAxis = lineChartView.leftAxis
leftAxis.labelTextColor = UIColor(red: 51/255, green: 181/255, blue: 229/255, alpha: 1)
leftAxis.labelCount = 4
leftAxis.drawGridLinesEnabled = true
leftAxis.granularityEnabled = true
leftAxis.yOffset = -8
let rightAxis = lineChartView.rightAxis
rightAxis.labelTextColor = UIColor(red: 51/255, green: 181/255, blue: 229/255, alpha: 1)
rightAxis.labelCount = 4
rightAxis.drawGridLinesEnabled = true
rightAxis.granularityEnabled = true
rightAxis.yOffset = -8
lineChartView.rightAxis.drawLimitLinesBehindDataEnabled = true
lineChartView.leftAxis.drawLimitLinesBehindDataEnabled = true
lineChartView.xAxis.valueFormatter = CustomChartFormatter(xAxisHours: topAxisValues)
lineChartView.rightAxis.valueFormatter = RightCustomChartFormatter(rightAxisHours: rightAxisValues)
lineChartView.leftAxis.valueFormatter = LeftCustomChartFormatter(leftAxisHours: leftAxisValues)
lineChartView.animate(xAxisDuration: 2.5)
Setting the Data (Code)
let set1 = LineChartDataSet(entries: yValues, label: "")
set1.mode = .stepped
set1.drawCirclesEnabled = false
set1.lineWidth = 2
set1.highlightLineWidth = 20
set1.setColor(UIColor.richBlue2 ?? UIColor.blue)
set1.fill = Fill(color: UIColor.blue)
set1.fillAlpha = 0.8
let data = LineChartData(dataSet: set1)
data.setDrawValues(false)
lineChartView.data = data

How to show value of bar on the top of the bar in Charts iOS?

i am using Charts pod.
My problem is that i want to show bar value at the top but also i can't change charts function which goes like label.position = .top because then days name will come at the top.
also i cannot make days label static as it will change for year and month wise also
it will be helpful if anyones know the answer
i want code in swift 5
//here is my code:
let dataSet = BarChartDataSet(entries: enteies,label: "Days")
dataSet.valueColors = [.clear]
dataSet.colors = [#colorLiteral(red: 0.1219139919, green: 0.4706707597, blue: 0.7069483399, alpha: 1)]
let data = BarChartData(dataSets: [dataSet])
barChartView.data = data
barChartView.chartDescription?.text = ""
barChartView.scaleXEnabled = false
barChartView.scaleYEnabled = false
barChartView.highlightPerTapEnabled = true
barChartView.dragEnabled = true
barChartView.fitBars = true
barChartView.drawValueAboveBarEnabled = true
barChartView.animate(yAxisDuration: 0.5)
barChartView.legend.enabled = false
barChartView.legend.drawInside = true
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.xAxis.enabled = true
barChartView.xAxis.axisLineColor = #colorLiteral(red: 0.1215686275, green: 0.4705882353, blue: 0.7058823529, alpha: 1)
barChartView.xAxis.granularityEnabled = false
barChartView.xAxis.granularity = 1
barChartView.xAxis.labelPosition = .bottom
barChartView.leftAxis.axisMinimum = 0
barChartView.leftAxis.granularity = 1
barChartView.leftAxis.granularityEnabled = true
barChartView.leftAxis.drawGridLinesEnabled = false
barChartView.leftAxis.axisLineColor = #colorLiteral(red: 0.1219139919, green: 0.4706707597, blue: 0.7069483399, alpha: 1)
barChartView.rightAxis.enabled = false
barChartView.rightAxis.drawGridLinesEnabled = false
var title = [String]()
for value in insightsVM.graphData{
if insightsVM.graphData.count > 5{
title.append(String(value.title.prefix(3)))
}
else{
title.append(value.title)
}
}
if insightsVM.graphData.count > 7{
barChartView.xAxis.labelCount = 12
}
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:title)
barChartView.drawValueAboveBarEnabled = true
My values were their on the top of bar but what i did wrong was that i was clearing their text color on line: "dataSet.valueColors = [.clear]".

iOS Eureka: How to select first value as default after lazy get

I have a list retrieved from REST API to Eureka's PushRow, but in case none is selected (creating a new object) I want first option to be selected by default after option list is retrieved.
However, PushRow only loads list after it's clicked on.
So is there a way to load PushRow lazy options together with it's section, or should I switch to other type of row (if it support's lazy)
You can use
$0.value // To set default value for PushRow()
Check that value is there before set to $0.value
Here what i used
<<< PushRow<String>(){
$0.tag = String(index)
$0.selectorTitle = checklistFieldNames[index] //
$0.options = ["YES", "NO"]
if question.count == 0{
$0.value = ""
}else {
$0.value = checklistFieldAnswers[0]
}
}.onPresent({ (from, to) in
to.dismissOnChange = false
to.dismissOnSelection = true
to.tableView?.backgroundColor = UIColor(displayP3Red: 244/255, green: 244/255, blue: 244/255, alpha: 1.0)
to.view.backgroundColor = UIColor(displayP3Red: 244/255, green: 244/255, blue: 244/255, alpha: 1.0)
to.selectableRowCellUpdate = { cell, row in
cell.textLabel?.font = UIFont(name: "DTLProkyonT", size: 15)
cell.textLabel?.textColor = UIColor.lightGray
cell.textLabel?.numberOfLines = 0
cell.textLabel?.backgroundColor = UIColor.clear
}
})

iOS Charts - LinechartView issue

I wanted to remove 'description text' view, 'data set' view (square shape view below the graph). I am using iOS Charts library - LineChartView
import Charts
---------------------- class declaration -------------------
#IBOutlet var graphEmotionsView: LineChartView! // Class outlet variable
let paramsList = ["","Anger" , "Disgust", "Fear", "Joy", "Sadness",""]
let paramsListVal = ['give some values']
In viewdidload
//Set graph emotions view befor applying the data
self.graphEmotionsView.backgroundColor = UIColor.lightGrayColor()
//Gestures
self.graphEmotionsView.doubleTapToZoomEnabled = false
self.graphEmotionsView.pinchZoomEnabled = false
//Highlight per tap
self.graphEmotionsView.highlightPerTapEnabled = false
self.graphEmotionsView.highlightPerDragEnabled = false
self.graphEmotionsView.highlightFullBarEnabled = false
//X
self.graphEmotionsView.xAxis.labelPosition = .BottomInside
self.graphEmotionsView.xAxis.labelTextColor = UIColor.whiteColor()
var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
for i in 0 ..< emotionParamsValues.count {
yVals1.append(ChartDataEntry(value: emotionParamsValues[i], xIndex: i+1))
}
print("yValues: \(yVals1)")
let set2: LineChartDataSet = LineChartDataSet()
set2.yVals = yVals1
set2.label = ""
set2.visible = true
// set chart line
set2.mode = .CubicBezier
set2.axisDependency = .Left
set2.lineWidth = 2.5
set2.setColor(UIColor(red: 157/255.0, green: 0/255.0, blue: 38/255.0, alpha: 1.0))
set2.highlightColor = UIColor.whiteColor()
// set custom point
set2.drawCirclesEnabled = true // should be true if you want hollow circles
set2.drawCircleHoleEnabled = true
set2.circleHoleRadius = 5.0
set2.setCircleColor(UIColor(red: 157/255.0, green: 0/255.0, blue: 38/255.0, alpha: 1.0))
// set fill chart
set2.drawFilledEnabled = true
set2.fillAlpha = 240 / 255.0
set2.fillColor = UIColor(red: 237/255.0, green: 26/255.0, blue: 103/255.0, alpha: 0.9)
var dataSets : [LineChartDataSet] = [LineChartDataSet]()
dataSets.append(set2)
dataSets[0].notifyDataSetChanged()
let data: LineChartData = LineChartData(xVals: emotionParamsList, dataSets: dataSets)
data.setValueTextColor(UIColor.whiteColor())
self.graphEmotionsView.data = data
Output I am getting
For fixing the description, try:
chart.description = ""
For disable the legend, try:
chart.legend.enabled = false
Shameless plug - you can find ios charts examples at ioscharts.io

Resources