2017-02-06 145 views
0

我正在顯示代表學位的每個模塊的執行學生的餅圖。我有的代碼顯示: output如何在JavaFX餅圖中顯示值?

但是我想每個切片的值出現在它內部,我不想要任何花哨的mouselistener的東西只是爲了顯示切片中的數字。

我的代碼如下:

public class PieChartSample extends Application { //TODO make constructor that takes hashmaps as arguments 
static Map<String, Integer> studsabove = new HashMap<String, Integer>(); 
static Map<String, Integer> studsbelow = new HashMap<String, Integer>(); 

@Override 
public void start(Stage primaryStage) throws Exception { 
    primaryStage.setTitle("My First JavaFX App"); 

    ArrayList<PieChart> pielist = new ArrayList<PieChart>(); 
    for(Entry<String, Integer> mod: studsabove.entrySet()){ 
     for(Entry<String, Integer> mod2: studsbelow.entrySet()){ 
      PieChart pieChart = new PieChart(); 
      PieChart.Data above = new PieChart.Data(mod.getKey(), mod.getValue()); 
      PieChart.Data below = new PieChart.Data(mod2.getKey(), mod2.getValue()); 

      pieChart.getData().add(above); 
      pieChart.getData().add(below); 

      pielist.add(pieChart); 
     } 
    } 

    VBox vbox = new VBox(); 
    for (PieChart pie: pielist){ 
     pie.setLabelLineLength(10); //FIXME 
     pie.setLegendSide(Side.LEFT); 
     vbox.getChildren().add(pie); 
    } 
    Scene scene = new Scene(vbox, 400, 200); //TODO: Make pie charts appear horizontally rather than vertically 

    primaryStage.setScene(scene); 
    primaryStage.setHeight(900); 
    primaryStage.setWidth(400); 

    primaryStage.show(); 
} 


public static void main(String[] args) { //TODO: need to figure out how to display the values in the slices of the pie charts 

    PieChartSample.studsabove.put("CE201", 23); 
    PieChartSample.studsbelow.put("CE201", 67); 

    PieChartSample.studsabove.put("CE222", 20); 
    PieChartSample.studsbelow.put("CE222", 80); 


    PieChartSample.studsabove.put("CE233", 6); 
    PieChartSample.studsbelow.put("CE233", 94); 

    PieChartSample.studsabove.put("CE244", 56); 
    PieChartSample.studsbelow.put("CE244", 44); 
    Application.launch(args); 
} 

}

+1

這是建議somethi ng略有不同。 http://stackoverflow.com/questions/35479375/display-additional-values-in-pie-chart – Sedrick

回答

0

您可以擴展PieChart這樣的:

import java.util.HashMap; 
import java.util.Map; 
import javafx.collections.ListChangeListener; 
import javafx.scene.chart.PieChart; 
import javafx.scene.layout.Region; 
import javafx.scene.shape.Arc; 
import javafx.scene.text.Text; 

public class LabeledPieChart extends PieChart { 

    private final Map<Data, Text> _labels = new HashMap<>(); 

    public LabeledPieChart() { 
     super(); 
     this.getData().addListener((ListChangeListener.Change<? extends Data> c) -> { 
      addLabels(); 
     }); 

    } 

    @Override 
    protected void layoutChartChildren(double top, double left, double contentWidth, double contentHeight) { 
     super.layoutChartChildren(top, left, contentWidth, contentHeight); 

     double centerX = contentWidth/2 + left; 
     double centerY = contentHeight/2 + top; 

     layoutLabels(centerX, centerY); 
    } 

    private void addLabels() { 

     for (Text label : _labels.values()) { 
      this.getChartChildren().remove(label); 
     } 
     _labels.clear(); 
     for (Data vData : getData()) { 
      final Text dataText; 
      final double yValue = vData.getPieValue(); 
      dataText = new Text(Double.toString(yValue)); 
      _labels.put(vData, dataText); 
      this.getChartChildren().add(dataText); 
     } 
    } 

    private void layoutLabels(double centerX, double centerY) { 

     double total = 0.0; 
     for (Data d : this.getData()) { 
      total += d.getPieValue(); 
     } 
     double scale = (total != 0) ? 360/total : 0; 

     for (Map.Entry<Data, Text> entry : _labels.entrySet()) { 
      Data vData = entry.getKey(); 
      Text vText = entry.getValue(); 

      Region vNode = (Region) vData.getNode(); 
      Arc arc = (Arc) vNode.getShape(); 

      double start = arc.getStartAngle(); 

      double size = (isClockwise()) ? (-scale * Math.abs(vData.getPieValue())) : (scale * Math.abs(vData.getPieValue())); 
      final double angle = normalizeAngle(start + (size/2)); 
      final double sproutX = calcX(angle, arc.getRadiusX()/2, centerX); 
      final double sproutY = calcY(angle, arc.getRadiusY()/2, centerY); 

      vText.relocate(
        sproutX - vText.getBoundsInLocal().getWidth(), 
        sproutY - vText.getBoundsInLocal().getHeight()); 
     } 

    } 

    private static double normalizeAngle(double angle) { 
     double a = angle % 360; 
     if (a <= -180) { 
      a += 360; 
     } 
     if (a > 180) { 
      a -= 360; 
     } 
     return a; 
    } 

    private static double calcX(double angle, double radius, double centerX) { 
     return (double) (centerX + radius * Math.cos(Math.toRadians(-angle))); 
    } 

    private static double calcY(double angle, double radius, double centerY) { 
     return (double) (centerY + radius * Math.sin(Math.toRadians(-angle))); 
    } 

} 

這裏是一個主類,以供測試:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.chart.PieChart.Data; 
import javafx.scene.layout.AnchorPane; 
import javafx.stage.Stage; 

public class JavaFXApplication28 extends Application { 

    @Override 
    public void start(Stage stage) { 

     stage.setTitle("Imported Fruits"); 
     stage.setWidth(500); 
     stage.setHeight(500); 

     LabeledPieChart chart = new LabeledPieChart(); 
     chart.setTitle("Imported Fruits"); 

     // Add some data 
     addPieChartData(chart, "Grapefruit", 13); 
     addPieChartData(chart, "Oranges", 25); 
     addPieChartData(chart, "Plums", 10); 
     addPieChartData(chart, "Pears", 22); 
     addPieChartData(chart, "Apples", 30); 

     AnchorPane anchor = new AnchorPane(); 
     Scene scene = new Scene(anchor); 
     anchor.getChildren().add(chart); 

     AnchorPane.setBottomAnchor(chart, 0.0); 
     AnchorPane.setTopAnchor(chart, 0.0); 
     AnchorPane.setLeftAnchor(chart, 0.0); 
     AnchorPane.setRightAnchor(chart, 0.0); 

     stage.setScene(scene); 
     stage.show(); 
    } 

    public void addPieChartData(LabeledPieChart pChart, String name, double value) { 
     final Data data = new Data(name, value); 
     pChart.getData().add(data); 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 

}