2015-08-08 47 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