LineChart plot data not filling its UIView - ios

So I'm using the library iOS-Charts for creating a calendar. The calendar shows plots of each day for each month. So for 1 year I have 12 UIViews plotted with data from each corresponding month. So for January there are 31 points in the line chart (since it's 31 days in January), in February I have 28 plots and so on. However, the UIView does not get completely filled with the LineChart.
So for February it looks like 3 points are missing, since the plot is not stretching the entire UIView. I've tried everything I can think of, setting autoresizingMask for the UIView, or the lineChart (which is a LineChartView), as well as setting the UIView.contentMode for both. Nothing helps.
I set the xRange of the LineChartView to be the amount of points I want, which depends on the number of days in the month. I then proceed to create the pageView (which are UIView's used to plot the LineChart on). Anyone know what I'm missing here? Below are my settings for each individual LineCharts.
// Create and set LineChart
var lineChart = LineChartView()
lineChart.descriptionText = ""
lineChart.delegate = self
lineChart.noDataTextDescription = "You need to provide data for the chart."
lineChart.drawGridBackgroundEnabled = false
lineChart.userInteractionEnabled = false
lineChart.xAxis.drawAxisLineEnabled = false
lineChart.xAxis.drawGridLinesEnabled = false
lineChart.xAxis.drawLabelsEnabled = false
lineChart.drawBordersEnabled = false
lineChart.leftAxis.enabled = false
lineChart.rightAxis.enabled = false
lineChart.legend.enabled = false
lineChart.contentMode = .ScaleAspectFill
lineChart.autoresizingMask = UIViewAutoresizing.FlexibleWidth

From your screenshot, I am guessing the xIndex count in your LineChartData is the same. Your last data point 5496 on Feb view is aligned perfectly with 2457 on March view, which indicates the share the same x values count on xAxis.
Based on your description, you should have 12 LineChartData objects, and each line chart data has its own xValues and dataSets, which means 12 xValues and 12 dataSets. You need to debug on xAxis renderer to see if I am correct.
If not resolved, then you need to provide your chart data code. I don't think it's a bug, it's some kinds of mistakes you made while creating chart data.

Related

highlightValue not working in chart with CombinedChartView :: Display marker programmatically is not working :: ChartIssue :: iOS Swift :: DanielGindi

Here is what i am doing!
chart.highlightValue(x: timeStampValue, dataSetIndex: totalCount)
==> In the above line,
timeStampValue is x axis value which i have set while filling up the array.
totalCount is total count of array of data which i am displaying in chart.
What i need to achieve is
When chart screen comes up, i need to display marker by default and for that, i am using "highlightValue" method of chart which is not working.
Please let me know the solution to show marker by default programatically.
NOTE: I am using marker whose UI is custom which is working fine when i tap manually at point in chart:
let marker = CustomMarkerView.viewFromXib()!
marker.chartView = chart
chart.marker = marker
chart.drawMarkers = true
Library used : https://github.com/danielgindi/Charts
Chart Data set :
let data = CombinedChartData()
data.lineData = LineChartData(dataSets:[viewModel.lineChartDataSet, viewModel.emptylineChartDataSet])
data.lineData.highlightEnabled = true
viewModel.lineChartDataSet.highlightColor = AssetsColor.highlightedColor.color
viewModel.lineChartDataSet.drawHorizontalHighlightIndicatorEnabled = false
viewModel.lineChartDataSet.highlightLineDashPhase = 2
viewModel.lineChartDataSet.highlightLineDashLengths = [5, 2.5]
you are using the wrong value for dataSetIndex param
based on your code, the datasets only contains 2 data
data.lineData = LineChartData(dataSets:[viewModel.lineChartDataSet, viewModel.emptylineChartDataSet])
dataSetIndex is not data count, in linechart dataset represent a line that has many data (x,y), so dataSetIndex is more like which line
so your code should be something like this
chart.highlightValue(x: timeStampValue, dataSetIndex: 0)
chart.highlightValue(x: timeStampValue, dataSetIndex: 0, dataIndex: 0)
When i added 1 more parameter which is dataIndex as 0 and it worked.
Here, dataSetIndex is set to 0 because it is CombinedChartView where i have merged 2 data set.

Hide data labels of a HIChart's Pie chart using Swift 5.0

I am creating Pie chart using HICharts library in iOS-Swift 5.0
I don't want data labels. Only wants legends at bottom. So I tried to hide it by using below code.
let plotoptions = HIPlotOptions() //Line 1
plotoptions.pie = HIPie() //Line 2
plotoptions.pie.allowPointSelect = NSNumber(value: true) //Line 3
plotoptions.pie.cursor = "pointer" //Line 4
plotoptions.pie.dataLabels = HIDataLabels() //Line 5
plotoptions.pie.dataLabels.enabled = NSNumber(value: false) //Line 6
plotoptions.pie.showInLegend = true //Line 7
But I am getting an error -
1. Cannot assign value of type 'HIDataLabels' to type '[HIDataLabelsOptionsObject]?' at line number 5
2. Value of type '[HIDataLabelsOptionsObject]?' has no member 'enabled' at line number 6
I have referred https://www.highcharts.com/ios/demo/pie-legend which is written in Objective C.
Edit: There were some changes in the latest HICharts API (8.0.0) that remove HIDataLabelsOptionsObject(), see updated answer in code below.
Here is how I got this to work. It turns out you don't need the allowPointSelect, cursor, or showInLegend flags (though you would probably want to keep the showInLegend flag, because you want a legend on your chart) to get this to work. I don't really know what allowPointSelect or cursor do, because you can still tap on the chart and see the details.
plotoptions.pie = HIPie()
let dataLabel = HIDataLabels() // Older versions of API - HIDataLabelsOptionsObject()
dataLabel.enabled = false
plotoptions.pie.dataLabels = [dataLabel]

CorePlot x axis labels

OK, my final issue with getting my bar chart setup is how to print the X axis labels. I tried this:
if let axis = graph.axisSet as? CPTXYAxisSet, xAxis = axis.xAxis {
let dateLabels = self!.dates!.map {
CPTAxisLabel(text: NSDateFormatter.localizedStringFromDate($0, dateStyle: .ShortStyle, timeStyle: .NoStyle), textStyle: nil)
}
xAxis.axisLabels = Set(dateLabels)
}
I'm getting nothing displayed though. I looked at DatePlot sample but I don't want to do what it's doing as it incorrectly assumes that a day is 86,400 seconds long, and that will break multiple times. Also, my date offsets are in months, so that makes it even worse. Can't I just somehow provide the already formatted date string?
Seems strange to me that "axisLabels" would be a set, since a set is not ordered.
Each axis label has a tickLocation. Set the tick location to the bar location for that label in the same units used in the plot space and datasource. Since the label tick location is not related to its position in the array, we can use an unordered collection like a set.

Records are slight shifted on date plot created using coreplot library

Here is a necessary code snippets,
X axis label formatter,
NSDateFormatter dateFormatter = new NSDateFormatter();
dateFormatter.DateFormat = "dd/MM";
var timeFormatter = new CPTTimeFormatter(dateFormatter);
timeFormatter.ReferenceDate = NSDate.FromTimeIntervalSinceNow(0);
x.LabelFormatter = timeFormatter;
Delegate method of getting records,
public override NSNumber NumberForPlot(CPTPlot plot, CPTPlotField forFieldEnum, nuint index)
{
if (forFieldEnum == CPTPlotField.ScatterPlotFieldX)
return new NSNumber((index + 1) * 86400);
Debug.WriteLine("{0}", Data[(int)index].Rate);
return Data[(int)index].Rate;
}
See attached screenshot for result looks like. You can see that markers are not aligned to X axis. First data point should display on “01/01” but it is displaying just before it. Same for all other points.
Let me know if anybody wish to look at any other part of code. I just need direction or clue what could lead to this record shifting. I have already looked at sample code provided in coreplot but didn't get any clue on this.
Edit:
Ranges are as below,
plotSpace.XRange = new CPTPlotRange(NSNumber.FromDouble(0).NSDecimalValue, NSNumber.FromDouble(86400 * 9).NSDecimalValue);
plotSpace.YRange = new CPTPlotRange(NSNumber.FromDouble(-1).NSDecimalValue, NSNumber.FromDouble(9).NSDecimalValue);
Also tried,
var space = graph.DefaultPlotSpace as CPTXYPlotSpace;
space.ScaleToFitPlots(new CPTPlot [] { dataSourceLinePlot });
Edit: Graph setup code
The problem is with the ReferenceDate for the time formatter. It is being initialized with the current date and time, so the offset will vary throughout the day depending on when the setup code runs. There are several ways to make an NSDate object that corresponds to a fixed time of day. The most straightforward is by using NSDateComponents.
Several of the Core Plot example apps, including the "Date Plot" demo in the Plot Gallery app, use this technique to generate reference dates.
Also, the automatic axis labeling policy doesn't work well with dates. It's picking tick locations that fall on "nice" numbers of seconds between ticks, but that doesn't correspond to even numbers of days. You should use the fixed interval policy (the default) or one of the ones that let you provide the tick locations directly.

iOS-charts slow down my app

I'm using ios-chart to present a calendar I've built. I'm currently using LineChart to plot my data, and I plot 1 point for each day of the year in one chart. So I have 365 points plotted in one chart. And it takes like 1 second to draw it. This isn't a huge issue, except that I have my calendar as a TableViewCell, which will result in a very hacky scroll once the TableViewCell is scrolled outside the ContentView and then scrolled back again (so the cell gets redrawn). It feels weird that it takes so long to draw around 400 points, even on an iPhone 6. I might be doing something wrong here?
My setup code for the chart:
lineChart.descriptionText = ""
lineChart.drawGridBackgroundEnabled = false
lineChart.userInteractionEnabled = false
lineChart.xAxis.drawAxisLineEnabled = false
lineChart.xAxis.drawGridLinesEnabled = false
lineChart.xAxis.drawLabelsEnabled = false
lineChart.drawBordersEnabled = false
lineChart.leftAxis.enabled = false
lineChart.rightAxis.enabled = false
lineChart.legend.enabled = false
lineChart.contentMode = .ScaleAspectFill
var xVals = [String]()
var dataSet = LineChartDataSet(yVals: [ChartDataEntry]())
for (index, value) in enumerate(plotData){
dataSet.addEntry(ChartDataEntry(value: Float(value), xIndex: index))
xVals.append("\(index)")
}
dataSet.setColor(Colors.whiteColor())
dataSet.lineWidth = 1.0
dataSet.circleRadius = 0.0
dataSet.drawCirclesEnabled = false
dataSet.drawValuesEnabled = false
dataSet.drawFilledEnabled = true
dataSet.fillColor = Colors.whiteColor()
dataSet.fillAlpha = 0.1
dataSet.valueTextColor = Colors.whiteColor()
lineChart.data = LineChartData(xVals: xVals, dataSet: dataSet)
The code above is done each time a cell is created (or reused). Any ideas?
The issue was in data that was being setup each time I reused the cell. Data creation should obviously not be in a cell, but somewhere else. Should be solved once I move my data initiation somewhere else.

Resources