LineChart avoid plotting of 0 values - swift

I am using https://github.com/danielgindi/Charts library. I am trying to remove 0 values from the chart but not able to find a particular solution any help would be appreciated.
yAxis has the value of type Double
The chart currently displays:
The updated line chart as I want
var dataEntries: [ChartDataEntry] = []
for i in 0..<forX.count {
let dataEntry = ChartDataEntry(x: Double(i), y: forY[i])
print(dataEntry)
dataEntries.append(dataEntry)
}
let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "")
let lineChartData = LineChartData(dataSet: lineChartDataSet)
chart.data = lineChartData

Just don't add it to your dataEntries
for i in 0..<forX.count {
if forY[i] != 0 {
let dataEntry = ChartDataEntry(x: Double(i), y: forY[i])
print(dataEntry)
dataEntries.append(dataEntry)
}
}
edit: you can check this https://github.com/aiwiguna/ExampleCharts

Related

Chart viewport height increase when chart has no data plot on chart

I am using https://github.com/danielgindi/Charts library. When the chart has no data then chart height increased it should be the same as when the chart has data. Chart xAxis labels overlapped with char title. Any help would be appreciated. Code for chart setup
var dataEntries: [ChartDataEntry] = []
axisFormatDelegate = self
chartView.legend.form = .none
let rightAxis = chartView.rightAxis
rightAxis.enabled = false
let yAxis = chartView.leftAxis
let xAxisValue = chartView.xAxis
xAxisValue.valueFormatter = axisFormatDelegate
xAxisValue.axisMinimum = -1
xAxisValue.axisMaximum = Double(forX.count)
xAxisValue.granularity = 1
for i in 0..<forX.count {
if forY[i] != 0 {
let dataEntry = ChartDataEntry(x: Double(i), y: forY[i])
dataEntries.append(dataEntry)
}
}
let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "")
let lineChartData = LineChartData(dataSet: lineChartDataSet)
print("Line chart data: \(lineChartData.dataSets)")
chartView.data = lineChartData
The chart with data:
The chart with no data:
I think it because you set legend.form to .none, it not showing legend but still had space for it
I usually use this to hide legend and to give extra margin in bottom of xAxis label use
chartView.legend.enabled = false
chartView.extraBottomOffset = 10

Add legend text to pie chart Swift Charts

I'm trying to add a legend to my chart, bu its only colours that are coming up without the text. I cant figure out why this is? To create my chart I use:
func configure (dataPoints: [String], values: [Double]) {
chartIMG.noDataText = "Please Insert Some Data!"
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: values[i], y: Double(i))
dataEntries.append(dataEntry)
}
let pieChartDataSet = PieChartDataSet(values: dataEntries, label: "Symptoms")
let pieChartData = PieChartData(dataSet: pieChartDataSet)
chartIMG.data = pieChartData
let noZeroFormatter = NumberFormatter()
noZeroFormatter.zeroSymbol = ""
pieChartDataSet.valueFormatter = DefaultValueFormatter(formatter: noZeroFormatter)
var colors: [UIColor] = []
for i in 0..<dataPoints.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
chartIMG.highlightPerTapEnabled = false
chartIMG.usePercentValuesEnabled = false
chartIMG.drawEntryLabelsEnabled = true
chartIMG.centerText = "%"
let legend = chartIMG.legend
legend.font = UIFont(name: "Arial", size: 11)!
legend.textColor = UIColor.black
legend.form = .circle
chartIMG.animate(xAxisDuration: 2, yAxisDuration: 2)
pieChartDataSet.colors = colors
pieChartDataSet.selectionShift = 0
pieChartDataSet.sliceSpace = 2.5
}
I'm trying to achive something similar to: https://i.stack.imgur.com/eiSnN.png
but cant seem to get the legend to display with the labels. Any idea why this is? I think it may be a simple line of code but I cant seem to find anything that works.
Simple answer if anyone is looking for this help:
let dataEntry1 = PieChartDataEntry(value: Double(i), label: dataPoints[i], data: dataPoints[i] as AnyObject)
Answered here: https://stackoverflow.com/a/42234117/9397533

Allow PieChartView to hide value line for tiny slices in Swift

I'm building a pie chart by chart iOS framework. I'm able to hide the value and label when the the slice is tiny but I can't hide the value line for tiny slice.
If I add this code on setDataCount()
set.valueLineWidth = 0.0
It will hide all the value line. How to hide it by the size of slice?
#IBOutlet weak var myChart: PieChartView!
var valueColors = [UIColor]()
var dataEntries = [PieChartDataEntry]()
var record = [Record]()
var category = [String]()
var categoryTotal : [Double] = []
var categoryArray : [String] = []
func setDataCount() {
var totalValue = 0.0
for a in categoryTotal {
totalValue += a
}
UserDefaults.standard.set(totalValue, forKey: "totalValue")
valueAndColor()
let set = PieChartDataSet(values: dataEntries, label: nil)
set.colors = valueColors
set.valueLinePart1OffsetPercentage = 0.8
set.valueLinePart1Length = 0.2
set.valueLinePart2Length = 0.4
set.xValuePosition = .outsideSlice
set.yValuePosition = .outsideSlice
set.selectionShift = 0.0
let data = PieChartData(dataSet: set)
let Formatter:ChartFormatter = ChartFormatter()
data.setValueFormatter(Formatter)
data.setValueFont(.systemFont(ofSize: 11, weight: .light))
data.setValueTextColor(.black)
myChart.data = data
myChart.highlightValues(nil)
}
func valueAndColor(){
for i in 0..<categoryArray.count{
let dataEntry = PieChartDataEntry(value: categoryTotal[i], label: categoryArray[i % categoryArray.count])
dataEntries.append(dataEntry)
//I'm using this code to hide the label
let value = categoryTotal[i]
let total = UserDefaults.standard.double(forKey: "totalValue")
var valueToUse = value/total * 100
valueToUse = Double(round(10*valueToUse)/10)
let minNumber = 10.0
if(valueToUse < minNumber) {
dataEntries[i].label = ""
}else{
dataEntries[i].label = categoryArray[i % categoryArray.count]
}
if categoryArray[i] == "吃喝" {
valueColors.append(UIColor.yellow)
}...
}
I'm using this code to hide the value %
public class ChartFormatter: NSObject, IValueFormatter{
public func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
let total = UserDefaults.standard.double(forKey: "totalValue")
var valueToUse = value/total * 100
valueToUse = Double(round(10*valueToUse)/10)
let minNumber = 10.0
if(valueToUse < minNumber) {
return ""
}
else {
let pFormatter = NumberFormatter()
pFormatter.numberStyle = .percent
pFormatter.maximumFractionDigits = 1
pFormatter.multiplier = 1
pFormatter.percentSymbol = " %"
let hideValue = pFormatter.string(from: NSNumber(value: value))
return String(hideValue ?? "0")
}
}
}
Inside the file PieChartRenderer change from this:
if dataSet.valueLineColor != nil
{
context.setStrokeColor(dataSet.valueLineColor!.cgColor)
context.setLineWidth(dataSet.valueLineWidth)
context.move(to: CGPoint(x: pt0.x, y: pt0.y))
context.addLine(to: CGPoint(x: pt1.x, y: pt1.y))
context.addLine(to: CGPoint(x: pt2.x, y: pt2.y))
context.drawPath(using: CGPathDrawingMode.stroke)
}
to this:
if dataSet.valueLineColor != nil
{
if(valueText == "") {
context.setStrokeColor(UIColor.clear.cgColor)
}
else {
context.setStrokeColor(dataSet.valueLineColor!.cgColor)
}
context.setLineWidth(dataSet.valueLineWidth)
context.move(to: CGPoint(x: pt0.x, y: pt0.y))
context.addLine(to: CGPoint(x: pt1.x, y: pt1.y))
context.addLine(to: CGPoint(x: pt2.x, y: pt2.y))
context.drawPath(using: CGPathDrawingMode.stroke)
}
The change basically checks if the valueText is the empty string, and if so it changes the linecolor to a clear color.

Only the first label is added to the BarChart

I want to create bar chart. I am using Charts library and this is my code on viewDidLoad()
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]
xAxis.valueFormatter = IndexAxisValueFormatter(values:months)
My problem is that only the first bar has a label 'Jan' on the X axis.
This is the setData code
func setDataCount(count: Int, range: Double){
let barWidth = 8.5
let spaceForBar = 10.0;
var yVals = [BarChartDataEntry]()
yVals.append(BarChartDataEntry(x: Double(0) * spaceForBar, y: 9.1))
yVals.append(BarChartDataEntry(x: Double(1) * spaceForBar, y: 5.4))
yVals.append(BarChartDataEntry(x: Double(2) * spaceForBar, y: 3.9))
var set1 : BarChartDataSet!
if let count = barChartView.data?.dataSetCount, count > 0{
set1 = barChartView.data?.dataSets[0] as! BarChartDataSet
set1.values = yVals
barChartView.data?.notifyDataChanged()
barChartView.notifyDataSetChanged()
}else{
set1 = BarChartDataSet(values: yVals, label: "")
var dataSets = [BarChartDataSet]()
dataSets.append(set1)
let data = BarChartData(dataSets: dataSets)
data.barWidth = barWidth;
barChartView.data = data
}
}
For Above Issue your adding only 3 dataEntry into DataSet so its showing only 3 bars follow below dynamic code
var dataEntries: [BarChartDataEntry] = []
//This soud be dynamic not static
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: "Units Sold")
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
barChartView.data = chartData
Hope you can understand whats the problem with Bar chart dataset.
Let me know if you required any help on above code.

Charts3.0 - Can not show all the xAxis label if more than 8 value - Swift

I had create a bar chart which had the 9 categories label for the xAxis:
["Foods", "House Loan", "Insurance", "Petrol", "Saving", "Train", "Others", "Books & Magazine", "Car park"]
But in the charts it just show:
Foods, Insurance, Saving, Others and Car park
Any one know how to solve it?
Here the source code for setting xAxis
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let value = values[i] as Double
let dataEntry = BarChartDataEntry(x: Double(i), y:value)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Total Amount")
var colors: [UIColor] = []
for _ in 0..<dataPoints.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
chartDataSet.colors = colors
chartDataSet.colors = ChartColorTemplates.joyful()
barChartView.chartDescription?.text = ""
barChartView.xAxis.labelPosition = .bottom
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.xAxis.granularityEnabled = true
barChartView.xAxis.granularity = 1.0
barChartView.xAxis.decimals = 0
let chartData = BarChartData()
chartData.addDataSet(chartDataSet)
barChartView.data = chartData
barChartView.xAxis.valueFormatter = self
let format = NumberFormatter()
format.numberStyle = .decimal
let formatter = DefaultValueFormatter(formatter: format)
chartData.setValueFormatter(formatter)
barChartView.animate(xAxisDuration: TimeInterval(1))
}
Just need to set the label count.
barChartView.xAxis.labelCount = dataPoints.count