2013-08-02 16 views
5

JavaFX Grafiklerini Kullanma, Yığılmış alan grafiğinin y eksenini, pozitif bir sıfırın üstte olacak şekilde ve pozitif sayılar y ekseninde aşağı doğru çalışacak şekilde tersine çevirmem gerekir. Aşağıda, elde etmeye çalıştığım şeyin bir örneği var.Ters y eksenine sahip grafik

Inverted Y-Axis with positive numbers

en iyi (okuyun: En kısa geliştirme zamanı ve yüksek kod yeniden kullanımını) nedir JavaFX bunu başarmak için bir yol? negatif sayılar veri dönüştürme

GÜNCELLEME

bir seçenek değildir. "El değmemiş" pozitif sayılarla çalışacak cevapları arıyorum.

cevap

2

Eksi işaretiyle normal ekseni kullanabilirsiniz, ancak eksi işaretini kesecek TickLabelFormatter ekleyin.

final NumberAxis yAxis = new NumberAxis(-25, 0, 5); 

    yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) { 
     @Override 
     public String toString(Number value) { 
      // note we are printing minus value 
      return String.format("%7.1f", -value.doubleValue()); 
     } 
    }); 

    series1.getData().add(new XYChart.Data("Jan", -1)); 
    series1.getData().add(new XYChart.Data("Feb", -5)); 
    series1.getData().add(new XYChart.Data("Mar", -20)); 
+0

Kullanarak şunları yapabilirsiniz: Tüm verilerimi grafiklerde kullanmadan önce negatif sayılara dönüştürmemi mi öneriyorsunuz? – mawcsco

+0

evet. Elbette ki en iyi yol değil, ama daha hızlı ve daha sonra inversiyon işlevselliği ile grafiği genişletiyor. Verilerin doğrudan güncellenmesini önlemek için, 'XYChart.Data' sınıfını inversiyon mantığıyla genişletebilir veya grafiğe ters numaralar ekleyeceğiniz bir yardımcı program yöntemi ekleyebilirsiniz. –

0

Değil kolay seçenek eksende inverse() operasyonu sağlamaktır. JRE sınıfları yokken oldukça karmaşıktır.

bu yaklaşım konusunda bazı ipuçları:

1) uzatmak ValueAxis veya Eksen (NumberAxis

2) eksen sınıfına mantıksal bir alan ve inverse() yöntem ekleyin) maalesef kesindir

public void inverse() { 
    inversed = !inversed; // boolean property 
    invalidateRange(); 
    requestAxisLayout(); 
} 

3) ValueAxis'i genişletirseniz - üst sınıf tarafından uygulanan ofseti telafi etmeniz gerekir (ve eksenin boyutunun değiştiği kodu durdurun)

@Override 
public Long getValueForDisplay(double displayPosition) { 
    if (inversed) 
     return super.getValueForDisplay(offset - displayPosition); 
    else 
     return super.getValueForDisplay(displayPosition); 
} 

@Override 
public double getDisplayPosition(Long value) { 
    if (inversed) 
     return offset - super.getDisplayPosition(value); 
    else 
     return super.getDisplayPosition(value); 
} 

4) (en çirkin parça) Axis sınıfı tarafından bastırılan etiket işaretlerini kaldırın - orijinal uygulama, varsayılan kene sırasına bağlıdır. Yansıma yoluyla kilidini açacak başka bir yol bulamadım. Yani bu çok kırılgan.

@Override 
protected void layoutChildren() { 
    final Side side = getSide(); 
    boolean isHorisontal = null == side || side.isHorizontal(); 
    this.offset = isHorisontal ? getWidth() : getHeight(); 
    super.layoutChildren(); 
    if (inversed) { 
     double prevEnd = isHorisontal ? offset + getTickLabelGap() : 0; 
     for (TickMark m : getTickMarks()) { 
      double position = m.getPosition(); 
      try { 
       final Text textNode = (Text) textNodeField.get(m); 
       final Bounds bounds = textNode.getLayoutBounds(); 
       if (0 <= position && position <= offset) 
        if (isHorisontal) { 
         textNode.setVisible(position < prevEnd); 
         prevEnd = position - (bounds.getWidth() + getTickLabelGap()); 
        } else { 
         textNode.setVisible(position > prevEnd); 
         prevEnd = position + (bounds.getHeight() + getTickLabelGap()); 
        } 
      } catch (IllegalAccessException ignored) { 
      } 
     } 
    } 
} 

Y ekseni Bu örnekte this is how it looks like

0

kullanımlar özellikleri LOWERBOUNDve eksenin UPPERBOUND olarak ters çevrilir. LowerBound'un upperBound'tan daha yüksek olması gerekir. Fxml:

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<HBox   
    prefHeight="600.0" 
    prefWidth="800.0" 
    xmlns:fx="http://javafx.com/fxml/1">  

    <javafx.scene.chart.LineChart 
     fx:id="chart" > 
     <xAxis > 
      <javafx.scene.chart.NumberAxis 
       label="X Axis" 
       lowerBound="0.01" 
       upperBound="100" 
       tickUnit="10" 
       autoRanging="false" /> 
     </xAxis> 
     <yAxis> 
      <javafx.scene.chart.NumberAxis 
        label="Y Axis" 
        lowerBound="100" 
        upperBound="0.001" 
        tickUnit="10" 
        autoRanging="false" 
       /> 
     </yAxis> 
    </javafx.scene.chart.LineChart>    
</Hbox>