2016-07-27 8 views
2

Ich schreibe ein javafx Programm, das eine BubbleChart für die Analyse von Unternehmen anzeigen soll. Auf der Y-Achse des Vorjahres werden die Umsätze angezeigt und auf der X-Achse die Anzahl der Marktsegmente, in denen das Unternehmen tätig ist. Der Radius der Blase hängt davon ab, welche Art von Marktsegmenten betreibt das Unternehmen inWie Blase Größe in BubbleChart ändern javafx

Ich weiß, dass ich eine „Blase“ durch Schreiben machen kann.

new XYChart.Data<Number,Number>(nbrOfMarketSegments, latestYearRevenue, radiusOfBubble); 

Das Problem ist, dass die y-Achse maximal ist 100 (Millionen EUR) und die x-Achse maximal 20, was die "Blasen" wie im Bild sehr flach macht (seit radiusOfBubble Nummer ist groß im Vergleich zu der maximalen Anzahl von Marktsegmenten und klein im Vergleich zu den maximalen Einnahmen. Meine Frage ist Gibt es eine Möglichkeit, die Blasen mehr kreisförmig zu machen, selbst wenn die x-Achse und die y-Achse so unterschiedliche Spannen haben?

BubbleChart

Antwort

3

JavaFX-Diagramme sind ein böser Code. Anpassung ist nur möglich, wenn Sie genau die Code-Basis dahinter kennen, die irgendwie gegen das gute Prinzip der Informationsverbergung ist. Das Umgehen von Blasen in einer BubbleChart ist eine dieser Anpassungen.

Die einfachste Sache, die Sie tun können, ist die Unterklasse BubbleChart und erstellen Sie Ihre eigenen runden Blasen.

Dinge, die nicht funktionieren:

Der Ort, an dem der Datenknoten erstellt wird (Methode createBubble) sind privat, so dass Sie es nicht außer Kraft setzen können Circle s statt zu erstellen. (Abgesehen davon - selbst wenn Sie einen benutzerdefinierten Datenknoten hätten, würde es nicht funktionieren, da der Layout-Code in BubbleChart alle Datenknoten ignoriert, die nicht vom Typ Ellipse sind, also würden Sie runde Blasen haben, aber alle auf Position (0/0) ...).

Die nächste Sache, die in den Sinn kommt, besteht darin, die Position zu überschreiben, an der die Achsen der Ellipse festgelegt sind. Aber nein, der gesamte Layout-Code ist eine einzige Methode - es gibt keine layoutNode(Node) -Methode, die für jeden Knoten aufgerufen wird und die Sie überschreiben können, um Ihren benutzerdefinierten Layout-Code hinzuzufügen.

Lösung:

So müssen Sie die Methode überschreiben layoutPlotChildren, rufen Sie die Implementierung Basis und dann die Y-Radius aller danach Knoten ändern:

public class CircularBubbleChart<X, Y> extends BubbleChart<X, Y> { 

    public CircularBubbleChart(Axis<X> xAxis, Axis<Y> yAxis) { 
     super(xAxis, yAxis); 
    } 

    public CircularBubbleChart(Axis<X> xAxis, Axis<Y> yAxis, ObservableList<Series<X, Y>> data) { 
     super(xAxis, yAxis, data); 
    } 

    @Override 
    protected void layoutPlotChildren() { 
     super.layoutPlotChildren(); 
     getData().stream().flatMap(series -> series.getData().stream()) 
      .map(Data::getNode) 
      .map(StackPane.class::cast) 
      .map(StackPane::getShape) 
      .map(Ellipse.class::cast) 
      .forEach(ellipse -> ellipse.setRadiusY(ellipse.getRadiusX())); 
    } 
} 

Die Verwendung ist einfach: Just Änderung die Codeerstellungscodezeile von ... = new BubbleChart() zu ... = new CircularBubbleChart(). Alles andere bleibt gleich.

Hinweis: Dieser Code ändert den Y-Radius so, dass er gleich dem X-Radius ist, also wird der Blasenradius in Einheiten der X-Achse liegen. Natürlich können Sie auch das Gegenteil erreichen, um einen Blasenradius in Einheiten der Y-Achse zu erhalten.

+0

Danke! Das ist sehr hilfreich! – ekstroom

Verwandte Themen