2015-04-30 12 views
6

widoczny Aktualizacje na dole (4/30/2015)iOS wykresy Jak unieważnić/przerysować po ustawieniu dane

Jestem wykonawczych wykresu kołowego w Swift dla iOS iOS z wykorzystaniem wykresów i wybrali aby dostosować legendę. Warto zauważyć, że wykres jest wyświetlany w komórce z UICollectionView. Problem polega na tym, że na pierwszym wyświetleniu zawartość niestandardowej legendy nie jest wyświetlana. Zamiast tego otrzymuję treść legendy wygenerowaną z danych.

Po przewinięciu widoku poza ekranem, a następnie przewinięciu go z powrotem na ekran, wyświetlana jest odpowiednia niestandardowa legenda. Tak więc jestem zgadując, że muszę wymusić przerysowanie/przekaz/ponowne coś po ustawieniu mojej niestandardowej legendy. Nie wiem, jak to zrobić. Czy ktoś ma pomysł? Czy całkowicie mi czegoś brakuje? Dzięki!

Wykres na ekranie początkowym - dane generowane (źle) legenda Chart on initial display - generated legend

Wykres po przewinięciu off i powrót na ekran - (właściwa legenda) Chart with proper legend

Oto mój kod rysowanie tego wykresu:

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) 
} 

Aktualizacja 4/30/2015

Na podstawie dyskusji z autorem MPAndroidChart (na którym opiera się iOS wykresy), wydaje się, że nie ma sensu w cyklu wyświetlania wykresu, gdzie można zastąpić legendę o „pierwszy rysować". Zasadniczo wykres jest renderowany, gdy jest tworzony, bez względu na wszystko. Jeśli ustawisz dane na wykresie, wykres użyje tych danych do utworzenia legendy, a następnie wyświetli. Nie można zmienić legendy między punktem nastawiania danych a punktem renderowania wykresu.

setNeedsDisplay()

potencjalnie może odczekać na wykresie, aby uczynić zaktualizować legendy, a następnie wywołać chart.setNeedsDisplay() sygnalizuje wykres odświeżenia. Niestety, jest z tym problem z synchronizacją. Jeśli wywołasz tę metodę natychmiast po renderowaniu wykresu, nie uruchamia się lub (bardziej prawdopodobne) wystrzeliwuje zbyt szybko i jest skutecznie ignorowana. W moim kodzie umieszczenie tego wywołania w viewDidLoad lub viewDidAppear nie przyniosło żadnego efektu. Jednak ...

Tworzenie tego samego wykresu w Javie dla systemu Android (przy użyciu MPAndroidChart) powoduje ten sam problem. Po trochę pogawędek, zauważyłem, że jeśli zadzwoniłem do chart.invalidate() po opóźnieniu (używając Handler.postDelayed()), to wystrzeliłoby poprawnie. Okazuje się, że podobne podejście działa w przypadku ios-chartów na iOS.

Jeśli ktoś używa GCD do opóźnienia wywołania setNeedsDisplay(), nawet na kilka milisekund po renderowaniu, wydaje się, że to wystarczy. Dodałem następujący kod natychmiast po uruchomieniu widoku wykresu w moim ViewController („komórki” to UICollectionViewCell zawierający widok wykresu):

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() 
} 

Korzystanie awesome „opóźnienie” metodę z tym SO post: https://stackoverflow.com/a/24318861

Oczywiście, jest to paskudny hack, ale wydaje się, że to wystarczy. Nie jestem pewien, czy podoba mi się pomysł wykorzystania tego hacka w produkcji.

Dla każdego Android ludzi, którzy obrażają się na tym stanowisku:

Poniższy kod daje ten sam efekt przy użyciu 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); 
+2

Czy chciał tylko dodać pieChart.setNeedsDisplay() na końcu metody viewDidLoad()? –

+0

@Shawn Tak, spróbowałem (z wielu punktów w kodzie), ale bez radości. Cykl życia wykresu w bibliotece MPAndroidCharts, na którym jest oparty, renderuje wykres na widoku init i kiedy dane są ustawione. Rozwiązanie przez chart.invalidate() (po opóźnieniu), ale ta metoda nie znajduje się w porcie ios-chart. Nie ma jeszcze rozwiązania, ale spróbuję jeszcze kilku rzeczy i zaktualizuję pytanie, czego się dowiem. – MojoTosh

Odpowiedz

7

ja jestem autorem iOS wykresów, a my praca nad funkcjami dostosowywania danych legendy, bez tych "hacków".

W ostatni zobowiązuje się do iOS wykresy, można już zobaczyć extraLabels i extraColors właściwości dodatkowe wiersze do legendy, a setLegend funkcję, która pozwala na ustawienie niestandardowych danych całkowicie.

To wkrótce zostanie dodane do wersji Android.

Enjoy :-)

+0

jakieś wiadomości o tym problemie? –

+0

Rozwiązany dawno temu ... –

+0

@ daniel.gindi Fellow Israeli here! Dzięki za stworzenie tej niesamowitej biblioteki! Czy mógłbyś, proszę, przyjrzeć się mojemu pytaniu? http://stackoverflow.com/questions/43463040/show-only-last-n-bars-ios-charts – MarksCode

Powiązane problemy