2

折れ線グラフの凡例のスタイルを更新したいのですが、対応するシリーズクラスのノードでsetStyleを使用しています。

String color = ....
XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
_chart.getData().add(series);

String seriesClass = null;
for(String styleClass : series.getNode().getStyleClass())
{
    if(styleClass.startsWith("series"))
    {
        seriesClass = styleClass;
        break;
    }
}
if(seriesClass != null)
{
    //
    // Customize the style.
    //
    StringBuilder sb = new StringBuilder();
    sb.append("-fx-stroke: ");
    sb.append(color);
    sb.append("; ");
    sb.append("-fx-background-color: ");
    sb.append(color);
    sb.append(", white;");
    if(doted)
    {
        sb.append("-fx-stroke-dash-array: 10 10");
    }
    _styles.put(seriesClass, sb.toString()); 
}

java.util.Set<javafx.scene.Node> nodes = _chart.lookupAll("." + seriesClass);
for(javafx.scene.Node n : nodes)
{
    n.setStyle(style);
}

これはパスのスタイルに影響を与えるだけで、凡例のスタイルは変更されません。チャートノードの子を印刷しましたが、系列の追加呼び出しが戻った後、凡例が完全に作成されていないことがわかります。

Legend@18e8627[styleClass=chart-legend]
    Label@1689c98[styleClass=label chart-legend-item]
    Label@100e4ce[styleClass=label chart-legend-item]
    Label@1adcb5e[styleClass=label chart-legend-item]
    Label@102a8fb[styleClass=label chart-legend-item]

少し後で、子供をもう一度印刷すると、次のようになります。

Legend@9a095[styleClass=chart-legend]
    Label[id=null, styleClass=label chart-legend-item]
        LabelSkin[id=null, styleClass=label chart-legend-item]
            Region@12acafc[styleClass=chart-legend-item-symbol chart-line-symbol series0 default-color0]
            LabeledText@749a47[styleClass=text]
    Label[id=null, styleClass=label chart-legend-item]
        LabelSkin[id=null, styleClass=label chart-legend-item]
            Region@3ca3a4[styleClass=chart-legend-item-symbol chart-line-symbol series1 default-color1]
            LabeledText@11b9972[styleClass=text]
    Label[id=null, styleClass=label chart-legend-item]
        LabelSkin[id=null, styleClass=label chart-legend-item]
            Region@57f433[styleClass=chart-legend-item-symbol chart-line-symbol series2 default-color2]
            LabeledText@6172b5[styleClass=text]
    Label[id=null, styleClass=label chart-legend-item]
        LabelSkin[id=null, styleClass=label chart-legend-item]
            Region@16458ed[styleClass=chart-legend-item-symbol chart-line-symbol series3 default-color3]
            LabeledText@10a68bd[styleClass=text]

今すぐスタイルを更新すると、凡例のスタイルが正しく更新されます。

スタイルの設定に必要なクラスを持つRegionの子がいつ追加されたかを知るにはどうすればよいので、そのノードでsetStyleを使用できますか?

新しいシリーズが追加されたときに凡例のスタイルを更新する他のアイデアはありますか?

4

3 に答える 3

5

私もこの問題に遭遇しました。凡例アイテムがいつ作成されたかを検出して、動的なスタイルを追加できるようにする回避策を考え出しました。

ListChangeListenerをレジェンドの「getChildrenUnmodizable()」ObservableListに追加しました。これにより、レジェンドの子が追加されるたびに、ListChangeListenerが追加されます。このリスナー内から、新しいアイテムが凡例に追加されている(または削除されている)時期を知ることができます。これにより、動的なスタイルの変更を行うことができます。

for (Node n : lineChart.getChildrenUnmodifiable())
        {
            if (n instanceof Legend)
            {
                final Legend legend = (Legend) n;

                // remove the legend
                legend.getChildrenUnmodifiable().addListener(new ListChangeListener<Object>()
                {
                    @Override
                    public void onChanged(Change<?> arg0)
                    {
                        for (Node node : legend.getChildrenUnmodifiable())
                        {
                            if (node instanceof Label)
                            {
                                final Label label = (Label) node;
                                label.getChildrenUnmodifiable().addListener(new ListChangeListener<Object>()
                                {
                                    @Override
                                    public void onChanged(Change<?> arg0)
                                    {
                                        //make style changes here
                                    }

                                });
                            }
                        }
                    }
                });
            }
        }
于 2013-05-01T19:00:09.010 に答える
3

これはどれも私にはうまくいかなかったので、私は別の解決策を見つけました。答えもPlatform.runLaterメソッドもありません。

XYChart.Series<Number,Number> value  //is our serie value.

for(int index = 0; index<value.getData().size(); index++){
    // we're looping for each data point, changing the color of line symbol
    XYChart.Data dataPoint = value.getData().get(index);
    Node lineSymbol = dataPoint.getNode().lookup(".chart-line-symbol");
    lineSymbol.setStyle("-fx-background-color: #0000FF, white;");
}
// and this is for the color of the line
value.getNode().setStyle("-fx-border-style: solid; -fx-stroke: #0000FF; -fx-background-color: #0000FF;");

凡例の色を変更する場合:

for(Node n : chart.getChildrenUnmodifiable()){
   if(n instanceof Legend){
      for(Legend.LegendItem legendItem : ((Legend)n).getItems()){
        legendItem.getSymbol().setStyle("-fx-background-color: #0000ff, white;");
      }
   }
}

これがこれを探している人にもうまくいくことを願っています。

于 2018-02-09T13:20:37.963 に答える
0

これはかなり古いことを知っていますが、おそらく誰かがよりスムーズな解決策を必要としています。Platform.runLater関数を使用するだけです。

int index = 2;
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        myChart.lookupAll(".chart-legend-item-symbol").toArray()[index].setStyle("-fx-border-color: rgba(200,0,0,1)");
}});
于 2016-08-09T14:07:42.760 に答える