< prev index next >

modules/javafx.controls/src/main/java/javafx/scene/chart/AreaChart.java

Print this page




 137 
 138     /**
 139      * Construct a new Area Chart with the given axis and data
 140      *
 141      * @param xAxis The x axis to use
 142      * @param yAxis The y axis to use
 143      * @param data The data to use, this is the actual list used so any changes to it will be reflected in the chart
 144      */
 145     public AreaChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
 146         super(xAxis,yAxis);
 147         setData(data);
 148     }
 149 
 150     // -------------- METHODS ------------------------------------------------------------------------------------------
 151 
 152     private static double doubleValue(Number number) { return doubleValue(number, 0); }
 153     private static double doubleValue(Number number, double nullDefault) {
 154         return (number == null) ? nullDefault : number.doubleValue();
 155     }
 156 
 157        /** @inheritDoc */
 158     @Override protected void updateAxisRange() {
 159         final Axis<X> xa = getXAxis();
 160         final Axis<Y> ya = getYAxis();
 161         List<X> xData = null;
 162         List<Y> yData = null;
 163         if(xa.isAutoRanging()) xData = new ArrayList<X>();
 164         if(ya.isAutoRanging()) yData = new ArrayList<Y>();
 165         if(xData != null || yData != null) {
 166             for(Series<X,Y> series : getData()) {
 167                 for(Data<X,Y> data: series.getData()) {
 168                     if(xData != null) xData.add(data.getXValue());
 169                     if(yData != null) yData.add(data.getYValue());
 170                 }
 171             }
 172             if(xData != null && !(xData.size() == 1 && getXAxis().toNumericValue(xData.get(0)) == 0)) {
 173                 xa.invalidateRange(xData);
 174             }
 175             if(yData != null && !(yData.size() == 1 && getYAxis().toNumericValue(yData.get(0)) == 0)) {
 176                 ya.invalidateRange(yData);
 177             }


 313                             item.getCurrentX())),
 314                             new KeyFrame(Duration.millis(800), actionEvent -> {
 315                                 item.setSeries(null);
 316                                 getPlotChildren().remove(symbol);
 317                                 removeDataItemFromDisplay(series, item);
 318                             },
 319                             new KeyValue(item.currentYProperty(),
 320                             item.getYValue(), Interpolator.EASE_BOTH),
 321                             new KeyValue(item.currentXProperty(),
 322                             item.getXValue(), Interpolator.EASE_BOTH))
 323                 );
 324             }
 325         } else {
 326             item.setSeries(null);
 327             getPlotChildren().remove(symbol);
 328             removeDataItemFromDisplay(series, item);
 329         }
 330         //Note: better animation here, point should move from old position to new position at center point between prev and next symbols
 331     }
 332 
 333     /** @inheritDoc */
 334     @Override protected void dataItemChanged(Data<X, Y> item) {
 335     }
 336 
 337     @Override protected void seriesChanged(ListChangeListener.Change<? extends Series> c) {
 338         // Update style classes for all series lines and symbols
 339         // Note: is there a more efficient way of doing this?
 340         for (int i = 0; i < getDataSize(); i++) {
 341             final Series<X,Y> s = getData().get(i);
 342             Path seriesLine = (Path)((Group)s.getNode()).getChildren().get(1);
 343             Path fillPath = (Path)((Group)s.getNode()).getChildren().get(0);
 344             seriesLine.getStyleClass().setAll("chart-series-area-line", "series" + i, s.defaultColorStyleClass);
 345             fillPath.getStyleClass().setAll("chart-series-area-fill", "series" + i, s.defaultColorStyleClass);
 346             for (int j=0; j < s.getData().size(); j++) {
 347                 final Data<X,Y> item = s.getData().get(j);
 348                 final Node node = item.getNode();
 349                 if(node!=null) node.getStyleClass().setAll("chart-area-symbol", "series" + i, "data" + j, s.defaultColorStyleClass);
 350             }
 351         }
 352     }
 353 


 398                 }
 399             }
 400         }
 401         if (shouldAnimate()) animate(keyFrames.toArray(new KeyFrame[keyFrames.size()]));
 402     }
 403 
 404     @Override protected  void seriesRemoved(final Series<X,Y> series) {
 405         // remove series Y multiplier
 406         seriesYMultiplierMap.remove(series);
 407         // remove all symbol nodes
 408         if (shouldAnimate()) {
 409             Timeline tl = new Timeline(createSeriesRemoveTimeLine(series, 400));
 410             tl.play();
 411         } else {
 412             getPlotChildren().remove(series.getNode());
 413             for (Data<X,Y> d:series.getData()) getPlotChildren().remove(d.getNode());
 414             removeSeriesFromDisplay(series);
 415         }
 416     }
 417 
 418     /** @inheritDoc */
 419     @Override protected void layoutPlotChildren() {
 420         List<LineTo> constructedPath = new ArrayList<>(getDataSize());
 421         for (int seriesIndex=0; seriesIndex < getDataSize(); seriesIndex++) {
 422             Series<X, Y> series = getData().get(seriesIndex);
 423             DoubleProperty seriesYAnimMultiplier = seriesYMultiplierMap.get(series);
 424             double lastX = 0;
 425             final ObservableList<Node> children = ((Group) series.getNode()).getChildren();
 426             ObservableList<PathElement> seriesLine = ((Path) children.get(1)).getElements();
 427             ObservableList<PathElement> fillPath = ((Path) children.get(0)).getElements();
 428             seriesLine.clear();
 429             fillPath.clear();
 430             constructedPath.clear();
 431             for (Iterator<Data<X, Y>> it = getDisplayedDataIterator(series); it.hasNext(); ) {
 432                 Data<X, Y> item = it.next();
 433                 double x = getXAxis().getDisplayPosition(item.getCurrentX());
 434                 double y = getYAxis().getDisplayPosition(
 435                         getYAxis().toRealValue(getYAxis().toNumericValue(item.getCurrentY()) * seriesYAnimMultiplier.getValue()));
 436                 constructedPath.add(new LineTo(x, y));
 437                 if (Double.isNaN(x) || Double.isNaN(y)) {
 438                     continue;




 137 
 138     /**
 139      * Construct a new Area Chart with the given axis and data
 140      *
 141      * @param xAxis The x axis to use
 142      * @param yAxis The y axis to use
 143      * @param data The data to use, this is the actual list used so any changes to it will be reflected in the chart
 144      */
 145     public AreaChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
 146         super(xAxis,yAxis);
 147         setData(data);
 148     }
 149 
 150     // -------------- METHODS ------------------------------------------------------------------------------------------
 151 
 152     private static double doubleValue(Number number) { return doubleValue(number, 0); }
 153     private static double doubleValue(Number number, double nullDefault) {
 154         return (number == null) ? nullDefault : number.doubleValue();
 155     }
 156 
 157        /** {@inheritDoc} */
 158     @Override protected void updateAxisRange() {
 159         final Axis<X> xa = getXAxis();
 160         final Axis<Y> ya = getYAxis();
 161         List<X> xData = null;
 162         List<Y> yData = null;
 163         if(xa.isAutoRanging()) xData = new ArrayList<X>();
 164         if(ya.isAutoRanging()) yData = new ArrayList<Y>();
 165         if(xData != null || yData != null) {
 166             for(Series<X,Y> series : getData()) {
 167                 for(Data<X,Y> data: series.getData()) {
 168                     if(xData != null) xData.add(data.getXValue());
 169                     if(yData != null) yData.add(data.getYValue());
 170                 }
 171             }
 172             if(xData != null && !(xData.size() == 1 && getXAxis().toNumericValue(xData.get(0)) == 0)) {
 173                 xa.invalidateRange(xData);
 174             }
 175             if(yData != null && !(yData.size() == 1 && getYAxis().toNumericValue(yData.get(0)) == 0)) {
 176                 ya.invalidateRange(yData);
 177             }


 313                             item.getCurrentX())),
 314                             new KeyFrame(Duration.millis(800), actionEvent -> {
 315                                 item.setSeries(null);
 316                                 getPlotChildren().remove(symbol);
 317                                 removeDataItemFromDisplay(series, item);
 318                             },
 319                             new KeyValue(item.currentYProperty(),
 320                             item.getYValue(), Interpolator.EASE_BOTH),
 321                             new KeyValue(item.currentXProperty(),
 322                             item.getXValue(), Interpolator.EASE_BOTH))
 323                 );
 324             }
 325         } else {
 326             item.setSeries(null);
 327             getPlotChildren().remove(symbol);
 328             removeDataItemFromDisplay(series, item);
 329         }
 330         //Note: better animation here, point should move from old position to new position at center point between prev and next symbols
 331     }
 332 
 333     /** {@inheritDoc} */
 334     @Override protected void dataItemChanged(Data<X, Y> item) {
 335     }
 336 
 337     @Override protected void seriesChanged(ListChangeListener.Change<? extends Series> c) {
 338         // Update style classes for all series lines and symbols
 339         // Note: is there a more efficient way of doing this?
 340         for (int i = 0; i < getDataSize(); i++) {
 341             final Series<X,Y> s = getData().get(i);
 342             Path seriesLine = (Path)((Group)s.getNode()).getChildren().get(1);
 343             Path fillPath = (Path)((Group)s.getNode()).getChildren().get(0);
 344             seriesLine.getStyleClass().setAll("chart-series-area-line", "series" + i, s.defaultColorStyleClass);
 345             fillPath.getStyleClass().setAll("chart-series-area-fill", "series" + i, s.defaultColorStyleClass);
 346             for (int j=0; j < s.getData().size(); j++) {
 347                 final Data<X,Y> item = s.getData().get(j);
 348                 final Node node = item.getNode();
 349                 if(node!=null) node.getStyleClass().setAll("chart-area-symbol", "series" + i, "data" + j, s.defaultColorStyleClass);
 350             }
 351         }
 352     }
 353 


 398                 }
 399             }
 400         }
 401         if (shouldAnimate()) animate(keyFrames.toArray(new KeyFrame[keyFrames.size()]));
 402     }
 403 
 404     @Override protected  void seriesRemoved(final Series<X,Y> series) {
 405         // remove series Y multiplier
 406         seriesYMultiplierMap.remove(series);
 407         // remove all symbol nodes
 408         if (shouldAnimate()) {
 409             Timeline tl = new Timeline(createSeriesRemoveTimeLine(series, 400));
 410             tl.play();
 411         } else {
 412             getPlotChildren().remove(series.getNode());
 413             for (Data<X,Y> d:series.getData()) getPlotChildren().remove(d.getNode());
 414             removeSeriesFromDisplay(series);
 415         }
 416     }
 417 
 418     /** {@inheritDoc} */
 419     @Override protected void layoutPlotChildren() {
 420         List<LineTo> constructedPath = new ArrayList<>(getDataSize());
 421         for (int seriesIndex=0; seriesIndex < getDataSize(); seriesIndex++) {
 422             Series<X, Y> series = getData().get(seriesIndex);
 423             DoubleProperty seriesYAnimMultiplier = seriesYMultiplierMap.get(series);
 424             double lastX = 0;
 425             final ObservableList<Node> children = ((Group) series.getNode()).getChildren();
 426             ObservableList<PathElement> seriesLine = ((Path) children.get(1)).getElements();
 427             ObservableList<PathElement> fillPath = ((Path) children.get(0)).getElements();
 428             seriesLine.clear();
 429             fillPath.clear();
 430             constructedPath.clear();
 431             for (Iterator<Data<X, Y>> it = getDisplayedDataIterator(series); it.hasNext(); ) {
 432                 Data<X, Y> item = it.next();
 433                 double x = getXAxis().getDisplayPosition(item.getCurrentX());
 434                 double y = getYAxis().getDisplayPosition(
 435                         getYAxis().toRealValue(getYAxis().toNumericValue(item.getCurrentY()) * seriesYAnimMultiplier.getValue()));
 436                 constructedPath.add(new LineTo(x, y));
 437                 if (Double.isNaN(x) || Double.isNaN(y)) {
 438                     continue;


< prev index next >