/** * ****************************************************************************************** * Draws the chart * * @param axisChart * @param iAxisChartDataSet * @throws PropertyException * ******************************************************************************************* */ static void render(AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet) throws PropertyException { Graphics2D g2d = axisChart.getGraphics2D(); LineChartProperties lineChartProperties = (LineChartProperties) iAxisChartDataSet.getChartTypeProperties(); lineChartProperties.validate(iAxisChartDataSet); // DataAxisProperties dataAxisProperties= (DataAxisProperties) // axisChart.getAxisProperties().getYAxisProperties(); IDataSeries iDataSeries = (IDataSeries) axisChart.getIAxisDataSeries(); // ---cache the computed values float[][] yAxisCoordinates = new float[iAxisChartDataSet.getNumberOfDataSets()] [iAxisChartDataSet.getNumberOfDataItems()]; // ---need this for image map calculation float xMapCoordinate = axisChart.getXAxis().getTickStart(); // LOOP for (int j = 0; j < iAxisChartDataSet.getNumberOfDataItems(); j++) { // LOOP for (int i = 0; i < yAxisCoordinates.length; i++) { if (iAxisChartDataSet.getValue(i, j) != Double.NaN) { yAxisCoordinates[i][j] = axisChart .getYAxis() .computeAxisCoordinate( axisChart.getYAxis().getOrigin(), iAxisChartDataSet.getValue(i, j), axisChart.getYAxis().getScaleCalculator().getMinValue()); // ---if we are generating an ImageMap, store the image coordinates if (axisChart.getGenerateImageMapFlag()) { String label; if (axisChart.getXAxis().getAxisLabelsGroup() != null) { label = axisChart.getXAxis().getAxisLabelsGroup().getTextTag(j).getText(); } else { label = null; } axisChart .getImageMap() .addImageMapArea( new CircleMapArea( xMapCoordinate, yAxisCoordinates[i][j], iAxisChartDataSet.getValue(i, j), label, iAxisChartDataSet.getLegendLabel(i))); } } else { yAxisCoordinates[i][j] = Float.NaN; } } xMapCoordinate += axisChart.getXAxis().getScalePixelWidth(); } AffineTransform originalTransform = null; double[] cornerXOffset = null; double[] cornerYOffset = null; // ---check if there are any points to display if (lineChartProperties.getShapes() != null) { // ---when centering the shapes on the points, need x and y offset to do this cornerXOffset = new double[iAxisChartDataSet.getNumberOfDataSets()]; cornerYOffset = new double[iAxisChartDataSet.getNumberOfDataSets()]; // ---get the original transform so can reset it. originalTransform = g2d.getTransform(); Rectangle2D rectangle; // LOOP // ---pre-compute the dimensions of each Shape so do not do it in loop. for (int i = 0; i < iAxisChartDataSet.getNumberOfDataSets(); i++) { if (lineChartProperties.getShapes()[i] != null) { rectangle = lineChartProperties.getShapes()[i].getBounds2D(); cornerXOffset[i] = rectangle.getWidth() / 2; cornerYOffset[i] = rectangle.getHeight() / 2; } } } // ---init for first segment Line2D.Float line = new Line2D.Float( axisChart.getXAxis().getTickStart(), yAxisCoordinates[0][0], axisChart.getXAxis().getTickStart(), yAxisCoordinates[0][0]); // ---make sure not plotting a chart with only one data point. if (yAxisCoordinates[0].length > 1) { line.y2 = yAxisCoordinates[0][1]; } // LOOP // ---draw each line to the image for (int i = 0; i < yAxisCoordinates.length; i++) { line.x1 = axisChart.getXAxis().getTickStart(); line.y1 = yAxisCoordinates[i][0]; line.x2 = line.x1; // LOOP for (int j = 1; j < yAxisCoordinates[0].length; j++) { // ---if current point on line should be drawn if (!Float.isNaN(yAxisCoordinates[i][j])) { // ---if the previous point was not drawn, no line if (Float.isNaN(yAxisCoordinates[i][j - 1])) { line.x2 += axisChart.getXAxis().getScalePixelWidth(); line.x1 = line.x2; line.y1 = yAxisCoordinates[i][j]; line.y2 = yAxisCoordinates[i][j]; continue; } line.x2 += axisChart.getXAxis().getScalePixelWidth(); line.y2 = yAxisCoordinates[i][j]; g2d.setPaint(iAxisChartDataSet.getPaint(i)); g2d.setStroke(lineChartProperties.getLineStrokes()[i]); g2d.draw(line); // ---plot the Point if (lineChartProperties.getShapes()[i] != null) { // ---translate the Shape into position. g2d.translate(line.x1 - cornerXOffset[i], line.y1 - cornerYOffset[i]); g2d.setPaint(iAxisChartDataSet.getPaint(i)); g2d.fill(lineChartProperties.getShapes()[i]); // ---translate back to the original position g2d.setTransform(originalTransform); } line.x1 = line.x2; line.y1 = line.y2; } else { if ((!Float.isNaN(yAxisCoordinates[i][j - 1])) && (lineChartProperties.getShapes()[i] != null)) { // ---translate the Shape into position. g2d.translate(line.x1 - cornerXOffset[i], line.y1 - cornerYOffset[i]); g2d.setPaint(iAxisChartDataSet.getPaint(i)); g2d.fill(lineChartProperties.getShapes()[i]); // ---translate back to the original position g2d.setTransform(originalTransform); } line.x2 += axisChart.getXAxis().getScalePixelWidth(); line.x1 = line.x2; } } // ---put the last shape on the line if ((!Float.isNaN(yAxisCoordinates[i][yAxisCoordinates[i].length - 1])) && (lineChartProperties.getShapes()[i] != null)) { // ---translate the Shape into position. g2d.translate(line.x2 - cornerXOffset[i], line.y2 - cornerYOffset[i]); g2d.setPaint(iAxisChartDataSet.getPaint(i)); g2d.fill(lineChartProperties.getShapes()[i]); // ---translate back to the original position g2d.setTransform(originalTransform); } } }
/** * Add axis * * @param name new axis name */ @Override public final void addAxis(String name) { boolean encontrado = false; for (AxisChart categoria : axes) { if (categoria.getName().equals(name)) { encontrado = true; break; } } if (!encontrado) { axes.add(new AxisChart((name))); } XYSeriesCollection dataset = new XYSeriesCollection(); NumberAxis ejeOrdenada = new NumberAxis(name); ejeOrdenada.setLabelPaint(scene2awtColor(javafx.scene.paint.Color.web(strTickColor))); ejeOrdenada.setTickLabelPaint(scene2awtColor(javafx.scene.paint.Color.web(strTickColor))); ejeOrdenada.setLabelFont(ejeOrdenada.getLabelFont().deriveFont(fontSize)); ejeOrdenada.setTickLabelFont(ejeOrdenada.getLabelFont().deriveFont(fontSize)); int i = datasetList.size(); datasetList.add(dataset); AxesList.add(ejeOrdenada); plot.setDataset(i, dataset); plot.setRangeAxis(i, ejeOrdenada); plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_LEFT); plot.mapDatasetToRangeAxis(i, i); XYItemRenderer renderer = new XYLineAndShapeRenderer(true, true); if (i == 0) { plot.setRenderer(renderer); } else { plot.setRenderer(i, renderer); } final LegendAxis le; final int indiceLeyenda = legendFrame.getChildren().size(); legendFrame.getChildren().add(le = new LegendAxis(name)); le.setOnMouseClicked( (MouseEvent t) -> { if (le.selected && t.getClickCount() == 2) { setOrdinateRange(AxesList.get(indiceLeyenda)); } }); le.setOnMouseEntered( (MouseEvent t) -> { le.setStyle("-fx-background-color:blue"); le.selected = true; AxesList.get(indiceLeyenda) .setLabelPaint(scene2awtColor(javafx.scene.paint.Color.web("blue"))); AxesList.get(indiceLeyenda) .setTickLabelPaint(scene2awtColor(javafx.scene.paint.Color.web("blue"))); }); le.setOnMouseExited( (MouseEvent t) -> { le.setStyle("-fx-background-color:" + strBackgroundColor); le.selected = false; AxesList.get(indiceLeyenda) .setLabelPaint(scene2awtColor(javafx.scene.paint.Color.web(strTickColor))); AxesList.get(indiceLeyenda) .setTickLabelPaint(scene2awtColor(javafx.scene.paint.Color.web(strTickColor))); }); }
/** * ****************************************************************************************** * Draws the chart * * @param axisChart * @param iAxisChartDataSet * ******************************************************************************************* */ static void render(AxisChart axisChart, IAxisChartDataSet iAxisChartDataSet) { // ---hopefully eliminate support requests asking about this... if (axisChart.getImageMap() != null) { // todo should we do a point image map? throw new ImageMapNotSupportedException( "HTML client-side image maps are not supported on Area Charts."); } // AreaChartProperties areaChartProperties=(AreaChartProperties) // iAxisChartDataSet.getChartTypeProperties(); float xPosition = axisChart.getXAxis().getTickStart(); GeneralPath generalPaths[] = new GeneralPath[iAxisChartDataSet.getNumberOfDataSets()]; // ---AreaCharts can not be drawn on a horizontal axis so y-axis will always be the data axis DataAxisProperties dataAxisProperties = (DataAxisProperties) axisChart.getAxisProperties().getYAxisProperties(); // LOOP // ---initial postion of each line must be set with call to moveTo() // ---Do this here so every point does not have to check....if( i == 0 )... in loop for (int i = 0; i < generalPaths.length; i++) { generalPaths[i] = new GeneralPath(); generalPaths[i].moveTo(xPosition, axisChart.getYAxis().getZeroLineCoordinate()); generalPaths[i].lineTo( xPosition, axisChart .getYAxis() .computeAxisCoordinate( axisChart.getYAxis().getOrigin(), iAxisChartDataSet.getValue(i, 0), axisChart.getYAxis().getScaleCalculator().getMinValue())); } // LOOP for (int j = 1; j < iAxisChartDataSet.getNumberOfDataItems(); j++) { xPosition += axisChart.getXAxis().getScalePixelWidth(); // LOOP for (int i = 0; i < generalPaths.length; i++) { generalPaths[i].lineTo( xPosition, axisChart .getYAxis() .computeAxisCoordinate( axisChart.getYAxis().getOrigin(), iAxisChartDataSet.getValue(i, j), axisChart.getYAxis().getScaleCalculator().getMinValue())); } } Area[] areas = new Area[generalPaths.length]; // LOOP // ---close the path. Do this here so do not have to check if last every pass through above // loop. for (int i = 0; i < generalPaths.length; i++) { generalPaths[i].lineTo(xPosition, axisChart.getYAxis().getZeroLineCoordinate()); generalPaths[i].closePath(); areas[i] = new Area(generalPaths[i]); } Graphics2D g2d = axisChart.getGraphics2D(); // LOOP // ---draw each path to the image for (int i = 0; i < areas.length; i++) { g2d.setPaint(iAxisChartDataSet.getPaint(i)); g2d.fill(areas[i]); } }
/** * @param name Chart name * @param parent Skeleton parent * @param axes Configuration of axes * @param abcissaName Abcissa name */ public SwingChart(String name, final Skeleton parent, List<AxisChart> axes, String abcissaName) { this.skeleton = parent; this.axes = axes; this.name = name; this.abcissaFormat = NumberFormat.getInstance(Locale.getDefault()); this.ordinateFormat = NumberFormat.getInstance(Locale.getDefault()); plot = new XYPlot(); plot.setBackgroundPaint(scene2awtColor(javafx.scene.paint.Color.web(strChartBackgroundColor))); plot.setDomainGridlinePaint(scene2awtColor(javafx.scene.paint.Color.web(strGridlineColor))); plot.setRangeGridlinePaint(scene2awtColor(javafx.scene.paint.Color.web(strGridlineColor))); plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0)); abcissaAxis = new NumberAxis(abcissaName); ((NumberAxis) abcissaAxis).setAutoRangeIncludesZero(false); abcissaAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 12)); abcissaAxis.setLabelFont(new Font("SansSerif", Font.PLAIN, 12)); abcissaAxis.setLabelPaint(scene2awtColor(javafx.scene.paint.Color.web(strTickColor))); abcissaAxis.setTickLabelPaint(scene2awtColor(javafx.scene.paint.Color.web(strTickColor))); abcissaAxis.setAutoRange(true); abcissaAxis.setLowerMargin(0.0); abcissaAxis.setUpperMargin(0.0); abcissaAxis.setTickLabelsVisible(true); abcissaAxis.setLabelFont(abcissaAxis.getLabelFont().deriveFont(fontSize)); abcissaAxis.setTickLabelFont(abcissaAxis.getLabelFont().deriveFont(fontSize)); plot.setDomainAxis(abcissaAxis); for (int i = 0; i < axes.size(); i++) { AxisChart categoria = axes.get(i); addAxis(categoria.getName()); for (int j = 0; j < categoria.configSerieList.size(); j++) { SimpleSeriesConfiguration cs = categoria.configSerieList.get(j); addSeries(categoria.getName(), cs); } } chart = new JFreeChart("", new Font("SansSerif", Font.BOLD, 16), plot, false); chart.setBackgroundPaint(scene2awtColor(javafx.scene.paint.Color.web(strBackgroundColor))); chartPanel = new ChartPanel(chart); chartPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(4, 4, 4, 4), BorderFactory.createLineBorder( scene2awtColor(javafx.scene.paint.Color.web(strBackgroundColor))))); chartPanel.getInputMap().put(KeyStroke.getKeyStroke("ESCAPE"), "escape"); chartPanel .getActionMap() .put( "escape", new AbstractAction() { @Override public void actionPerformed(java.awt.event.ActionEvent e) { for (int i = 0; i < plot.getDatasetCount(); i++) { XYDataset test = plot.getDataset(i); XYItemRenderer r = plot.getRenderer(i); r.removeAnnotations(); } } }); chartPanel.addChartMouseListener( cml = new ChartMouseListener() { @Override public void chartMouseClicked(ChartMouseEvent event) {} @Override public void chartMouseMoved(ChartMouseEvent event) { try { XYItemEntity xyitem = (XYItemEntity) event.getEntity(); // get clicked entity XYDataset dataset = (XYDataset) xyitem.getDataset(); // get data set double x = dataset.getXValue(xyitem.getSeriesIndex(), xyitem.getItem()); double y = dataset.getYValue(xyitem.getSeriesIndex(), xyitem.getItem()); final XYPlot plot = chart.getXYPlot(); for (int i = 0; i < plot.getDatasetCount(); i++) { XYDataset test = plot.getDataset(i); XYItemRenderer r = plot.getRenderer(i); r.removeAnnotations(); if (test == dataset) { NumberAxis ejeOrdenada = AxesList.get(i); double y_max = ejeOrdenada.getUpperBound(); double y_min = ejeOrdenada.getLowerBound(); double x_max = abcissaAxis.getUpperBound(); double x_min = abcissaAxis.getLowerBound(); double angulo; if (y > (y_max + y_min) / 2 && x > (x_max + x_min) / 2) { angulo = 3.0 * Math.PI / 4.0; } else if (y > (y_max + y_min) / 2 && x < (x_max + x_min) / 2) { angulo = 1.0 * Math.PI / 4.0; } else if (y < (y_max + y_min) / 2 && x < (x_max + x_min) / 2) { angulo = 7.0 * Math.PI / 4.0; } else { angulo = 5.0 * Math.PI / 4.0; } CircleDrawer cd = new CircleDrawer( (Color) r.getSeriesPaint(xyitem.getSeriesIndex()), new BasicStroke(2.0f), null); // XYAnnotation bestBid = new // XYDrawableAnnotation(dataset.getXValue(xyitem.getSeriesIndex(), // xyitem.getItem()), dataset.getYValue(xyitem.getSeriesIndex(), // xyitem.getItem()), 11, 11, cd); String txt = "X:" + abcissaFormat.format(x) + ", Y:" + ordinateFormat.format(y); XYPointerAnnotation anotacion = new XYPointerAnnotation( txt, dataset.getXValue(xyitem.getSeriesIndex(), xyitem.getItem()), dataset.getYValue(xyitem.getSeriesIndex(), xyitem.getItem()), angulo); anotacion.setTipRadius(10.0); anotacion.setBaseRadius(35.0); anotacion.setFont(new Font("SansSerif", Font.PLAIN, 10)); if (Long.parseLong((strChartBackgroundColor.replace("#", "")), 16) > 0xffffff / 2) { anotacion.setPaint(Color.black); anotacion.setArrowPaint(Color.black); } else { anotacion.setPaint(Color.white); anotacion.setArrowPaint(Color.white); } // bestBid.setPaint((Color) r.getSeriesPaint(xyitem.getSeriesIndex())); r.addAnnotation(anotacion); } } // LabelValorVariable.setSize(LabelValorVariable.getPreferredSize()); } catch (NullPointerException | ClassCastException ex) { } } }); chartPanel.setPopupMenu(null); chartPanel.setBackground(scene2awtColor(javafx.scene.paint.Color.web(strBackgroundColor))); SwingNode sn = new SwingNode(); sn.setContent(chartPanel); chartFrame = new VBox(); chartFrame.getChildren().addAll(sn, legendFrame); VBox.setVgrow(sn, Priority.ALWAYS); VBox.setVgrow(legendFrame, Priority.NEVER); chartFrame .getStylesheets() .addAll(SwingChart.class.getResource("overlay-chart.css").toExternalForm()); legendFrame.setStyle("marco: " + strBackgroundColor + ";-fx-background-color: marco;"); MenuItem mi; mi = new MenuItem("Print"); mi.setOnAction( (ActionEvent t) -> { print(chartFrame); }); contextMenuList.add(mi); sn.setOnMouseClicked( (MouseEvent t) -> { if (menu != null) { menu.hide(); } if (t.getClickCount() == 2) { backgroundEdition(); } }); mi = new MenuItem("Copy to clipboard"); mi.setOnAction( (ActionEvent t) -> { copyClipboard(chartFrame); }); contextMenuList.add(mi); mi = new MenuItem("Export values"); mi.setOnAction( (ActionEvent t) -> { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Export to file"); fileChooser .getExtensionFilters() .addAll(new FileChooser.ExtensionFilter("Comma Separated Values", "*.csv")); Window w = null; try { w = parent.getScene().getWindow(); } catch (NullPointerException e) { } File file = fileChooser.showSaveDialog(w); if (file != null) { export(file); } }); contextMenuList.add(mi); chartFrame.setOnContextMenuRequested( (ContextMenuEvent t) -> { if (menu != null) { menu.hide(); } menu = new ContextMenu(); menu.getItems().addAll(contextMenuList); menu.show(chartFrame, t.getScreenX(), t.getScreenY()); }); }