2015-08-08 46 views
-1
  • 我試圖使用應用於LineChart顯示醫療數據從不同的信道來的多個線型圖JavaFX的單帆布

    • 我是否需要開發自己的圖表組件或LineChart可用於此場景?

http://simetronsac.com/images/dx/eeg-24/eeg6.gif

===================更新... 擴展線型圖和而額外增加以滿足y值而改變Y軸以CategoryAxis:

import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 

import javafx.beans.NamedArg; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Node; 
import javafx.scene.chart.Axis; 
import javafx.scene.chart.LineChart; 
import javafx.scene.shape.LineTo; 
import javafx.scene.shape.MoveTo; 
import javafx.scene.shape.Path; 
import javafx.scene.shape.PathElement; 

public class StackedLineChart<X,Y> extends LineChart<X,Y> { 

    private double swimlaneHeight = 50; 

    private double currentYoffset = 0; 

    public static class ExtraData { 

     public float channelPower; 

     public ExtraData(float channelPower) { 
      super(); 
      this.channelPower = channelPower; 
     } 
     public float getChannelPower() { 
      return channelPower; 
     } 
     public void setChannelPower(float channelPower) { 
      this.channelPower = channelPower; 
     } 

    } 

    public StackedLineChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis) { 
     this(xAxis, yAxis, FXCollections.<Series<X, Y>>observableArrayList()); 
    } 

    public StackedLineChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) { 
     super(xAxis, yAxis); 
     setData(data); 
    } 

    public double getSwimlaneHeight() { 
     return swimlaneHeight; 
    } 

    public void setSwimlaneHeight(double swimlaneHeight) { 
     this.swimlaneHeight = swimlaneHeight; 
    } 

    private static float getChannelPower(Object obj) { 
     return ((ExtraData) obj).getChannelPower(); 
    } 

    final int getDataSize() { 
     final ObservableList<Series<X,Y>> data = getData(); 
     return (data!=null) ? data.size() : 0; 
    } 

    /** @inheritDoc */ 
    @Override protected void layoutPlotChildren() { 

     List<LineTo> constructedPath = new ArrayList<>(getDataSize()); 
     currentYoffset = 0; 
     for (int seriesIndex=0; seriesIndex < getDataSize(); seriesIndex++) {    
      Series<X,Y> series = getData().get(seriesIndex);    
      if(series.getNode() instanceof Path) { 
       final ObservableList<PathElement> seriesLine = ((Path)series.getNode()).getElements(); 
       seriesLine.clear(); 
       constructedPath.clear(); 
       for (Iterator<Data<X, Y>> it = getDisplayedDataIterator(series); it.hasNext();) { 
        Data<X, Y> item = it.next(); 

        double yCat = getYAxis().getDisplayPosition(item.getYValue());      
        double x = getXAxis().getDisplayPosition(item.getXValue());     
        double y = getChannelPower(item.getExtraValue()) + yCat; 

        if (Double.isNaN(x) || Double.isNaN(y)) {      
         continue;     
        } 

        constructedPath.add(new LineTo(x, y)); 

        Node symbol = item.getNode(); 
        if (symbol != null) { 
         final double w = symbol.prefWidth(-1); 
         final double h = symbol.prefHeight(-1); 
         symbol.resizeRelocate(x-(w/2), y-(h/2),w,h); 
        } 
       } 

       if (!constructedPath.isEmpty()) { 
        LineTo first = constructedPath.get(0); 
        seriesLine.add(new MoveTo(first.getX(), first.getY())); 
        seriesLine.addAll(constructedPath); 
       } 
      } 
      currentYoffset+= this.getSwimlaneHeight(); 
     } 
    }  

    @Override protected void updateAxisRange() { 
     final Axis<X> xa = getXAxis(); 
     final Axis<Y> ya = getYAxis(); 
     List<X> xData = null; 
     List<Y> yData = null; 
     if(xa.isAutoRanging()) xData = new ArrayList<X>(); 
     if(ya.isAutoRanging()) yData = new ArrayList<Y>(); 
     if(xData != null || yData != null) { 
      for(Series<X,Y> series : getData()) { 
       for(Data<X,Y> data: series.getData()) { 
        if(xData != null) xData.add(data.getXValue()); 
        if(yData != null) yData.add(data.getYValue()); 
       } 
      } 

      // RT-32838 No need to invalidate range if there is one data item - whose value is zero. 
      if(xData != null) xa.invalidateRange(xData); 
      if(yData != null) ya.invalidateRange(yData); 


     } 
    } 

} 
+0

即:某個時間點的y軸可以向上/向下移動嗎?所以系列可以繪製在不同的相對y軸上...不確定... – egovconcepts

+0

y軸上沒有數值。只需在每個系列中的每個點上添加一個金額,具體取決於您在圖表上的位置。從你的時間尺度來看,javaFX圖表速度不夠快。 – brian

+0

yes會嘗試(抵消y值),至於渲染性能我不確定javafx如何在內部呈現圖表(將查看源代碼),但是基於「畫布」的圖表應該更快!對? – egovconcepts

回答

0

你想要的是一堆圖表,而不是單個圖表中的各種線條。所以是的,你必須開發你自己的圖表組件。

+0

我認爲很容易改變每個數據系列的Y值因爲我的所有系列都有相同數據量和相同比例......它只是將線條向下移動Y值,而不是創建30個圖表(性能和高度問題)... – egovconcepts

+0

嗯,你說這樣做比寫這個問題要快得多。那就試試吧。 – Roland

+0

得到第二個意見......你知道......但無論如何它沒有;工作...... – egovconcepts