vedere gli aggiornamenti in basso (4/30/2015)iOS classifiche Come invalidare/ridisegnare dopo aver impostato i dati
Sto implementando un grafico a torta a Swift per iOS che utilizzano iOS classifiche, e hanno scelto per personalizzare la legenda. Di nota, il grafico viene visualizzato all'interno di una cella di UICollectionView. Il problema è che al primo display, il contenuto della legenda personalizzata non viene visualizzato. Invece, ottengo il contenuto delle leggende generato dai dati.
Se si scorre la vista fuori dallo schermo, quindi lo si scorre indietro sullo schermo, viene visualizzata la legenda personalizzata corretta. Quindi, sono supposto che io debba forzare un ridisegno/relayout/re-qualcosa dopo aver impostato la mia legenda personalizzata. Non ho capito come farlo. Qualcuno ha un'idea? Mi manca qualcosa? Grazie!
Grafico sulla schermata iniziale - i dati generati (sbagliato) leggenda
Grafico dopo lo scorrimento fuori e indietro sullo schermo - (corretta leggenda)
Ecco il mio codice per disegno questo schema:
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)
}
Aggiornamento 4/30/2015
Sulla base di discussione con l'autore di MPAndroidChart (su cui si basa ios-grafici), sembra non c'è un punto del ciclo di vita del display grafico dove si può ignorare la leggenda sulla "prima disegnare". Fondamentalmente, il grafico è reso quando viene creato, non importa quale. Se si impostano i dati sul grafico, il grafico utilizza tali dati per creare la legenda e quindi esegue il rendering. Non è possibile modificare la legenda tra il punto di impostazione dei dati e il punto di rendering del grafico.
setNeedsDisplay()
Potenzialmente, si può aspettare che il grafico di rendering, aggiornare la legenda, e quindi chiamare chart.setNeedsDisplay() per segnalare la tabella per ridisegnare. Purtroppo, c'è un problema di temporizzazione con questo. Se si chiama questo metodo immediatamente dopo aver eseguito il rendering del grafico, non viene attivato o (più probabilmente) viene attivato troppo presto e viene effettivamente ignorato. Nel mio codice, l'inserimento di questa chiamata in viewDidLoad o viewDidAppear non ha avuto alcun effetto. Tuttavia ...
Costruire lo stesso grafico in Java per Android (utilizzando MPAndroidChart) comporta lo stesso problema. Dopo aver fatto un po 'di casino, ho notato che se avessi chiamato il chart.invalidate() dopo un ritardo (usando Handler.postDelayed()), si sarebbe attivato correttamente. Risulta che un approccio simile funziona per ios-charts su iOS.
Se si utilizza GCD per ritardare la chiamata a setNeedsDisplay(), anche per pochi millisecondi dopo il rendering, sembra che faccia il trucco. Ho aggiunto il seguente codice subito dopo l'inizializzazione vista del grafico nel mio ViewController ("cella" è l'UICollectionViewCell che contiene la vista grafico):
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()
}
Utilizzando il metodo impressionante "ritardo" da questo SO messaggio: https://stackoverflow.com/a/24318861
Ovviamente, questo è un brutto scherzo, ma sembra fare il trucco. Non sono sicuro che mi piaccia l'idea di usare questo trucco nella produzione, però.
Per qualsiasi popolare Android che inciampano su questo post:
Il codice seguente ottiene lo stesso effetto usando 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);
Hai cercato di aggiungere solo pieChart.setNeedsDisplay() alla fine del metodo viewDidLoad()? –
@Shawn Sì, ho provato un po '(da molti punti nel codice), ma nessuna gioia. Il ciclo di vita della visualizzazione del grafico nella libreria MPAndroidCharts, su cui si basa questo, rende il grafico sulla vista init e quando i dati sono impostati. Risolvibile tramite chart.invalidate() (dopo il ritardo), ma questo metodo non si trova nella porta ios-chart. Nessuna soluzione ancora, ma proverò ancora un po 'di cose e aggiornerò la domanda con qualunque cosa io scopra. – MojoTosh