簡體   English   中英

在JavaFX圖表中添加一行

[英]Adding a line in a JavaFX chart

我在JavaFX中的定義位置添加一行時遇到問題。 該行必須是一個常量行,如下所示: 如何在JavaFX圖表中添加值標記?

我的問題是,我的布局定義有點復雜。 看一看:

圖表

重要的部分是頂部的那個。 我希望在y = 60線上有這條線。 RadioBoxes的左側部分是VBox。 帶有(Scatter-)圖表的部分是StackPane(因為我希望它填充寬度的其余部分)。 StackPane內部是圖表和組。 該集團唯一的子女就是這條線。

我認為問題在於,StackPane將集團的中心放在圖表上方。 但是我無法得到布局的組合,其中1.拉伸圖表2.將線條設置在圖表3上方。不會使線條居中

我嘗試了很多組合,但我不能按照我想要的方式得到它。 有人有想法嗎?!

遺憾的是,XYCharts不支持ValueMarkers(可能是應該在層次結構中的位置)(使用具有常量值的數據)是一種在某些情況下可能(或不可)接受/可能的黑客攻擊。

更清潔的出路是支持此類標記的自定義圖表。 一個自定義ScatterChart像:

public class ScatterXChart<X, Y> extends ScatterChart<X, Y> {

    // data defining horizontal markers, xValues are ignored
    private ObservableList<Data<X, Y>> horizontalMarkers;

    public ScatterXChart(Axis<X> xAxis, Axis<Y> yAxis) {
        super(xAxis, yAxis);
        // a list that notifies on change of the yValue property
        horizontalMarkers = FXCollections.observableArrayList(d -> new Observable[] {d.YValueProperty()});
        // listen to list changes and re-plot
        horizontalMarkers.addListener((InvalidationListener)observable -> layoutPlotChildren());
    }

    /**
     * Add horizontal value marker. The marker's Y value is used to plot a
     * horizontal line across the plot area, its X value is ignored.
     * 
     * @param marker must not be null.
     */
    public void addHorizontalValueMarker(Data<X, Y> marker) {
        Objects.requireNonNull(marker, "the marker must not be null");
        if (horizontalMarkers.contains(marker)) return;
        Line line = new Line();
        marker.setNode(line );
        getPlotChildren().add(line);
        horizontalMarkers.add(marker);
    }

    /**
     * Remove horizontal value marker.
     * 
     * @param horizontalMarker must not be null
     */
    public void removeHorizontalValueMarker(Data<X, Y> marker) {
        Objects.requireNonNull(marker, "the marker must not be null");
        if (marker.getNode() != null) {
            getPlotChildren().remove(marker.getNode());
            marker.setNode(null);
        }
        horizontalMarkers.remove(marker);
    }

    /**
     * Overridden to layout the value markers.
     */
    @Override
    protected void layoutPlotChildren() {
        super.layoutPlotChildren();
        for (Data<X, Y> horizontalMarker : horizontalMarkers) {
            double lower = ((ValueAxis) getXAxis()).getLowerBound();
            X lowerX = getXAxis().toRealValue(lower);
            double upper = ((ValueAxis) getXAxis()).getUpperBound();
            X upperX = getXAxis().toRealValue(upper);
            Line line = (Line) horizontalMarker.getNode();
            line.setStartX(getXAxis().getDisplayPosition(lowerX));
            line.setEndX(getXAxis().getDisplayPosition(upperX));
            line.setStartY(getYAxis().getDisplayPosition(horizontalMarker.getYValue()));
            line.setEndY(line.getStartY());

        }
    }
}

測試圖表的片段(在oracle的教程中插入到在線示例中):

// instantiate chart
NumberAxis xAxis = new NumberAxis(0, 10, 1);
NumberAxis yAxis = new NumberAxis(-100, 500, 100);        
ScatterXChart<Number,Number> sc = new ScatterXChart<>(xAxis,yAxis);
// .. fill with some data
...
// ui to add/change/remove a value marker
Data<Number, Number> horizontalMarker = new Data<>(0, 110);
Button add = new Button("Add Marker");  
add.setOnAction(e -> sc.addHorizontalValueMarker(horizontalMarker));
Slider move = new Slider(yAxis.getLowerBound(), yAxis.getUpperBound(), 0);
move.setShowTickLabels(true);
move.valueProperty().bindBidirectional(horizontalMarker.YValueProperty());
Button remove = new Button("Remove Marker");
remove.setOnAction(e -> sc.removeHorizontalValueMarker(horizontalMarker));

附錄:

雖然我不建議在相關的問題的方法 (添加標記線,以圖表的父和外部管理其位置/長度), 可以在可調整大小的容器中使用它。 使它成功的關鍵因素:

  • 聽取圖表的大小/位置變化並適當更新線條
  • 將標記的托管屬性設置為false

在代碼中(updateShift是原始中計算yShift / lineX的部分):

Pane pane = new StackPane(chart);
chart.widthProperty().addListener(o -> updateShift(chart));
chart.heightProperty().addListener(o -> updateShift(chart));
valueMarker.setManaged(false);
pane.getChildren().add(valueMarker);

為什么不在圖表中添加該行? 我有圖表,我顯示100,99,95和50百分位數,我解決這個問題的方法是為每個百分位數的正確y值添加一條線。

要做到這一點,只需添加一個有兩個點的線,一個在y = 60 x = 70(最左邊的x軸值),另一個在y = 60和x = 120(最右邊的x軸)值)。

這樣做的好處是你不必手動對齊水平線,缺點是這條水平線也將成為圖例的一部分。 但是,看到你沒有一個應該沒問題的傳奇。

如果您決定添加圖例,請務必正確命名水平線,l

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM