Ios-charts How to nullify / redraw after installing data

See updates at the bottom (4/30/2015)

I run a pie chart in Swift for iOS using ios-charts and decided to set up a legend. It should be noted that the chart is displayed in the UICollectionView cell. The problem is that the first time the contents of the user legend are not displayed. Instead, I get legendary content created from data.

If I scroll the view behind the scenes and then scroll it back to the screen, the corresponding user legend is displayed. So, I assume that I need to force redraw / relay / redo something after installing my custom legend. I did not understand how to do this. Does anyone have an idea? Am I missing something? Thanks!

Initial Display Chart - Data Generated Legend (Incorrect) Chart on initial display - generated legend

Chart after scrolling and returning to the screen - (correct legend) Chart with proper legend

Here is my code to draw this diagram:

func initChart(pieChart: PieChartView) { numFormatter.maximumFractionDigits = 0 pieChart.backgroundColor = UIColor.whiteColor() pieChart.usePercentValuesEnabled = false pieChart.drawHoleEnabled = true pieChart.holeTransparent = true pieChart.descriptionText = "" pieChart.centerText = "30%\nComplete" pieChart.data = getMyData() // Setting custom legend info, called AFTER setting data pieChart.legend.position = ChartLegend.ChartLegendPosition.LeftOfChartCenter pieChart.legend.colors = [clrGreenDk, clrGold, clrBlue] pieChart.legend.labels = ["Complete","Enrolled","Future"] pieChart.legend.enabled = true } func getMyData() -> ChartData { var xVals = ["Q201","R202","S203","T204","U205", "V206"] var courses: [ChartDataEntry] = [] courses.append(ChartDataEntry(value: 3, xIndex: 0)) courses.append(ChartDataEntry(value: 3, xIndex: 1)) courses.append(ChartDataEntry(value: 4, xIndex: 2)) courses.append(ChartDataEntry(value: 4, xIndex: 3)) courses.append(ChartDataEntry(value: 3, xIndex: 4)) courses.append(ChartDataEntry(value: 3, xIndex: 5)) let dsColors = [clrGreenDk, clrGreenDk, clrBlue, clrBlue, clrGold, clrGold] let pcds = PieChartDataSet(yVals: courses, label: "") pcds.sliceSpace = CGFloat(4) pcds.colors = dsColors pcds.valueFont = labelFont! pcds.valueFormatter = numFormatter pcds.valueTextColor = UIColor.whiteColor() return ChartData(xVals: xVals, dataSet: pcds) } 

Update 4/30/2015

Based on a discussion with the author of MPAndroidChart (which ios diagrams are based on), it seems that there is no point in the life cycle of the chart display where you can redefine the legend in the “first draw”. Basically, a chart is displayed when it is created, no matter what. If you set data on a chart, the chart uses that data to create a legend and then render it. It is not possible to change the legend between the data set point and the chart render point.

setNeedsDisplay ()

Potentially, you can wait for the chart to be rendered, update the legend, and then call chart.setNeedsDisplay () to signal a chart is being redrawn. Unfortunately, there is a problem with this. If you call this method immediately after rendering the chart, it either fails or (more likely) it fails too soon and is actually ignored. In my code, placing this call in viewDidLoad or viewDidAppear had no effect. But...

Building the same chart in Java for Android (using MPAndroidChart) leads to the same problem. With a bit of concern, I noticed that if I call chart.invalidate () after a delay (using Handler.postDelayed ()), it will light up correctly. It turns out a similar approach works for iOS diagrams on iOS.

If you use a GCD to delay the call to setNeedsDisplay (), even a few milliseconds after rendering, it seems like a trick. I added the following code immediately after initializing the chart view in my ViewController (the "cell" is a UICollectionViewCell containing the chart view):

 delay(0.05) { cell.pieChartView.legend.colors = [self.clrGreenDk, self.clrGold, self.clrBlue] cell.pieChartView.legend.labels = ["Complete","Enrolled","Future"] // Re-calc legend dimensions for proper position (Added 5/2/2015) cell.pieChartView.legend.calculateDimensions(cell.pieChartView.labelFont!) cell.pieChartView.setNeedsDisplay() } 

Using the excellent “delay” method from this SO post: https://stackoverflow.com/a/167478/

Obviously this is an unpleasant hack, but it seems to be a trick. I'm not sure that I like the idea of ​​using this hack in production.

For any Android people who stumble on this post:

The following code provides the same effect using MPAndroidChart:

  // Inside onCreate() pie = (PieChart) findViewById(R.id.chart1); configPieChart(pie); new Handler().postDelayed(new Runnable() { @Override public void run() { String[] legLabels = new String[]{"Complete","Enrolled","Future"}; ArrayList<Integer> legColors = new ArrayList<Integer>(); legColors.add(blue); legColors.add(gold); legColors.add(green); pie.getLegend().setPosition(Legend.LegendPosition.LEFT_OF_CHART_CENTER); pie.getLegend().setColors(legColors); pie.getLegend().setLabels(legLabels); pie.invalidate(); } }, 20); 
+6
source share
1 answer

I am the author of ios diagrams, and we are working on functions to configure legend data without these “hacks”.

In the latest commits for ios diagrams, you can already see the extraLabels and extraColors that add additional lines to the legend, and the setLegend function, which allows you to fully customize user data.

It will be added to the Android version soon.

Enjoy :-)

+7
source

Source: https://habr.com/ru/post/986261/


All Articles