2014-01-07 38 views
5

私は多くのシリーズの折れ線グラフを持っています。これらのシリーズは、1つ以上のスーパーシリーズにグループ化されています。監視プロセスが積極的にデータを収集していないときを正確に表すために、スーパーシリーズには多くの「中断」があります。各データブレークは実際に新しいシリーズを開始しています。JavaFX 2を削除LineChart凡例項目

私は、この新しいシリーズに新しい色を割り当てるチャート、シリーズの色と一致しないチャートラインのシンボルカラーなど、いくつかの技術的問題をうまく解決することができました。グラフに新しい系列を追加するたびに、凡例に項目が追加されます。

凡例から項目を削除する方法はありますか、デフォルト凡例を非表示にして独自のカスタム凡例枠を追加する必要はありますか?

答えて

12

Don't show the legend

chart.setLegendVisible(false); 

あなたは、その後、独自の伝説を作り、あなたが望むどのようにそれをレンダリングするために、独自のカスタムペインを作成することができます。

Legend legend = (Legend) findNode(chart, Legend.class.getName(), "chart-legend"); 

:伝説のノードを取得するために、問題のチャートでそれを呼び出す

private static Node findNode(final Parent aParent, final String aClassname, final String aStyleName) { 

    if (null != aParent) { 
     final ObservableList<Node> children = aParent.getChildrenUnmodifiable(); 
     if (null != children) { 
      for (final Node child : children) { 

       String className = child.getClass().getName(); 

       if (className.contains("$")) { 
        className = className.substring(0, className.indexOf("$")); 
       } 

       if (0 == aClassname.compareToIgnoreCase(className)) { 
        if ((null == aStyleName) || (0 == aStyleName.length())) { 
         // No aStyleName, just return this: 
         return child; 
        } 
        else { 
         final String styleName = child.getStyleClass().toString(); 
         if (0 == aStyleName.compareToIgnoreCase(styleName)) { 
          return child; 
         } 
        } 
       } 

       if (child instanceof Parent) { 
        final Node node = findNode((Parent) child, aClassname, aStyleName); 

        if (null != node) { 
         return node; 
        } 
       } 
      } 
     } 
    } 

    return null; 
} 

+0

ありがとうございます!それは私が恐れていたものです。 :) – RonSiven

+0

こんにちは@jewelsea、もう1つ質問、あなたが気にしない場合。カスタム凡例を表示するための独自のカスタムペインを作成しました。それはオリジナルとほぼ同じように見えます。私が問題を抱えているのは、ちょうど2つのシリーズがあるときに幅を縮めることです。チャートと凡例はダイアログのVBoxにあり、凡例はVBoxの下部にあるStackPaneにあります。高さは適切に変化する。私に助けてくれる知恵の言葉がもうありますか? – RonSiven

+0

しかし、新しい質問をして、現在のコードを[sscce](http://sscce.org)として追加してください。 – jewelsea

0

あなたは、このメソッドを使用しての種類(および必要に応じてスタイル名)に基づいて、ノードを見つけることができますあなたは子供たちを繰り返して、表示したくないものを取り除くことができます:

for (final Node legendItem : legend.getChildren()) { 

     final Label legendLabel = (Label) legendItem; 

     if (0 == legendLabel.getText().compareToIgnoreCase("the name of the legend I want hidden (or replaced with some other test)")) { 
      legend.getChildren().remove(legendItem); 
      break; 
     } 
    } 

JavaFXには、lookup機能があります。このノードまたは特定のCSSセレクタに基づいて最初のサブノードを検索します。この回答からfindNode関数と同様に機能します。

+0

getChildren()メソッドは凡例クラスには表示されません。メソッドgetchildren()はParentクラスで保護され、Regionで拡張されてLegendクラスに拡張されます。私たちはlegend.getChildrenUnmodifiable()から要素を削除することはできません。 – Kishore

+0

@Kishore Java 8.0.25に対して実行されるLegendのクラス階層は、Object - > Node - > Parent - > Region - > Pane - > TilePane - - >伝説。ペインにはパブリックgetChildrenがあります。 –

+0

@Kishoreはこのように思えました。それは可能にしました。http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/9823085ebf0e –

1

さまざまな提案をいくつか試みても失敗した後、JavaFx Chart(またはそのサブクラス)のデータ系列の表示/非表示を可能にする最良の方法は、そのupdateLegend()メソッドを使用してオーバーライドします。

実際にはとても簡単です。凡例として、チェックボックスを含む凡例として基本HBoxを使用した例を示します。この例では、固定軸タイプ(CategoryAxisとNumberAxis)のLineChartを作成することにしました。サブクラスに軸のジェネリックを残すこともできます。

public class AtopLineChart<X, Y> extends LineChart<String, Number> 
{ 

    /** 
    * @param xAxis 
    * @param yAxis 
    */ 
    public AtopLineChart(final CategoryAxis xAxis, final NumberAxis yAxis) 
    { 
     super(xAxis, yAxis); 
    } 

    /* (non-Javadoc) 
    * @see javafx.scene.chart.LineChart#updateLegend() 
    */ 
    @Override 
    protected void updateLegend() 
    { 
     final HBox legend = new HBox(); 
     legend.setVisible(true); 
     for (final javafx.scene.chart.XYChart.Series<String, Number> series : getData()) 
     { 
     final CheckBox cb = new CheckBox(series.getName()); 
     cb.setUserData(series); 
     cb.setSelected(true); 
     cb.addEventHandler(ActionEvent.ACTION, e -> 
     { 
      final CheckBox box = (CheckBox) e.getSource(); 
      @SuppressWarnings("unchecked") 
      final Series<String, Number> s = (Series<String, Number>) box.getUserData(); 
      s.getNode().setVisible(box.isSelected()); 
     }); 
     legend.getChildren().add(cb); 
     } 
     setLegend(legend); 
    } 
} 

私は、たとえば、伝説読みやすくするために、読者のための運動としてそれを残しておきます、各チェックボックスと周りのボーダーのためのチェックボックスにその色を示すものに、一連の色を結合シリーズ。

もう1つのことは、凡例にどの種類のレイアウトコンテナを使用するかを決めるgetLegendSide()メソッドをチェックするとよいでしょう。つまり、TOPとBOTTOMはHBoxですが、LEFTとRIGHTはVBOXです。あなたの選択。

関連する問題