private void drawRebootSuspectLine(XYChart<Number, ? extends Number> target) { if (target.getData().isEmpty() || target.getData().get(0).getData().isEmpty()) { return; } AnchorPane anchor = (AnchorPane) target .getParent() .getChildrenUnmodifiable() .stream() .filter(n -> n instanceof AnchorPane) .findAny() .get(); ObservableList<Node> anchorChildren = anchor.getChildren(); anchorChildren.clear(); NumberAxis xAxis = (NumberAxis) target.getXAxis(); Axis yAxis = target.getYAxis(); Label chartTitle = (Label) target .getChildrenUnmodifiable() .stream() .filter(n -> n.getStyleClass().contains("chart-title")) .findFirst() .get(); double startX = xAxis.getLayoutX() + 4.0d; double yPos = yAxis.getLayoutY() + chartTitle.getLayoutY() + chartTitle.getHeight(); List<Rectangle> rectList = summaryData .get() .getRebootSuspectList() .stream() .map(d -> d.atZone(ZoneId.systemDefault()).toEpochSecond()) .map( s -> new Rectangle( xAxis.getDisplayPosition(s) + startX, yPos, 4d, yAxis.getHeight())) .peek(r -> ((Rectangle) r).setStyle("-fx-fill: yellow;")) .collect(Collectors.toList()); anchorChildren.addAll(rectList); }
@Override public Iterable<Data<X, Y>> getVisibleData() { final Axis<X> xAxis = getChart().getXAxis(); final double width = xAxis.getWidth(); List<Data<X, Y>> visible = getData() .filtered( new Predicate<Data<X, Y>>() { @Override public boolean test(Data<X, Y> item) { final double p = xAxis.getDisplayPosition(item.getXValue()); return p >= 0 && p <= width; } }); return visible; }
/** * Render image consisting of computation result. This method will be run in background thread, so * it can have a while. Implementation should periodically check if status.isCancelled() and abort * (return null) if so. * * @param xAxis values for x dimension * @param yAxis values for y dimension * @param status status to be checked periodically * @return computation result as two-dimensional array * @throws Exception if computational error occurs */ public BufferedImage renderImage( Axis<Number> xAxis, Axis<Number> yAxis, ImageRendererStatus status) throws Exception { ImageResult result; int width = (int) xAxis.getWidth(); int height = (int) yAxis.getHeight(); double xMin = xAxis.getValueForDisplay(0.0).doubleValue(); double xMax = xAxis.getValueForDisplay(width - 1).doubleValue(); double yMin = yAxis.getValueForDisplay(0.0).doubleValue(); double yMax = yAxis.getValueForDisplay(height - 1).doubleValue(); PreferencesWithAxes<P> pax = new PreferencesWithAxes<P>(getPreferences(), width, height, xMin, xMax, yMin, yMax); CachedImageResult<PreferencesWithAxes<P>> cache = cache_; if (cache != null && cache.preferences.equals(pax)) { result = cache.result; } else { result = compute(pax, status); if (result == null) { return null; } cache_ = new CachedImageResult<PreferencesWithAxes<P>>(pax, result); } BufferedImage image = new BufferedImage(pax.width, pax.height, BufferedImage.TYPE_INT_RGB); if (result == null) { return null; } double max = 0; for (int ix = 0; ix < pax.width; ++ix) { for (int iy = 0; iy < pax.height; ++iy) { max = Math.max(max, result.values[ix][iy].abs()); } } int[] palette = palette_.getPalette(); boolean inverted = inverted_; for (int ix = 0; ix < pax.width; ++ix) { if (status.isCancelled()) { return null; } for (int iy = 0; iy < pax.height; ++iy) { double t = result.values[ix][iy].abs() / max; if (inverted) { t = 1.0 - t; } int value = palette[Math.min((int) Math.floor(t * palette.length), palette.length - 1)]; image.setRGB(ix, iy, value); } } return image; }
/** * This is called when the range has been invalidated and we need to update it. If the axis are * auto ranging then we compile a list of all data that the given axis has to plot and call * invalidateRange() on the axis passing it that data. */ @Override protected void updateAxisRange() { // For candle stick chart we need to override this method as we need to let the axis know that // they need to be able // to cover the whole area occupied by the high to low range not just its center data value final Axis<String> xa = getXAxis(); final Axis<Number> ya = getYAxis(); List<String> xData = null; List<Number> yData = null; if (xa.isAutoRanging()) { xData = new ArrayList<>(); } if (ya.isAutoRanging()) { yData = new ArrayList<>(); } if (xData != null || yData != null) { for (Series<String, Number> series : getData()) { for (Data<String, Number> data : series.getData()) { if (xData != null) { xData.add(data.getXValue()); } if (yData != null) { BarData extras = (BarData) data.getExtraValue(); if (extras != null) { yData.add(extras.getHigh()); yData.add(extras.getLow()); } else { yData.add(data.getYValue()); } } } } if (xData != null) { xa.invalidateRange(xData); } if (yData != null) { ya.invalidateRange(yData); } } }