diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..24bbfc9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: java +jdk: + - oraclejdk8 +install: mvn install -DskipTests=true -Dgpg.skip=true +script: "mvn cobertura:cobertura" +after_success: +- bash <(curl -s https://codecov.io/bash) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7d0d8e7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2021, Yann Richet +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 99a1f1d..cebbfe8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# JMathPlot: interactive 2D and 3D plots # +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.yannrichet/JMathPlot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.yannrichet/JMathPlot) +[![Build Status](https://travis-ci.org/yannrichet/jmathplot.png)](https://travis-ci.org/yannrichet/jmathplot) +[![codecov](https://codecov.io/gh/yannrichet/jmathplot/branch/master/graph/badge.svg)](https://codecov.io/gh/yannrichet/jmathplot) + +# JMathPlot: interactive 2D and 3D plots Provides interactive 2D/3D plot (without openGL) : @@ -54,3 +58,5 @@ Then - create a new PlotPanel instance: `PlotPanel plot = new Plot2DPanel();` - add a plot inside `plot.addLinePlot("my plot", x, y);` - use the PlotPanel as any Swing component (all PlotPanel extends JPanel, in fact) + +![Analytics](https://ga-beacon.appspot.com/UA-109580-20/jmathplot) diff --git a/pom.xml b/pom.xml index c3a5ee2..aab25ce 100644 --- a/pom.xml +++ b/pom.xml @@ -114,6 +114,18 @@ true + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + + html + xml + + + + jmathplot diff --git a/src/main/java/org/math/plot/PlotPanel.java b/src/main/java/org/math/plot/PlotPanel.java index ac169d0..189d8d5 100644 --- a/src/main/java/org/math/plot/PlotPanel.java +++ b/src/main/java/org/math/plot/PlotPanel.java @@ -94,7 +94,7 @@ public void addLegend(String location) { plotLegend = new LegendPanel(this, LegendPanel.INVISIBLE); // add(legends, BorderLayout.NORTH); } else { - System.err.println("Orientation " + location + " is unknonw."); + System.err.println("Orientation " + location + " is unknown."); } } @@ -150,7 +150,7 @@ public void addPlotToolBar(String location) { plotToolBar.setFloatable(false); add(plotToolBar, NORTH); } else { - System.err.println("Location " + location + " is unknonw."); + System.err.println("Location " + location + " is unknown."); } } diff --git a/src/main/java/org/math/plot/components/PlotToolBar.java b/src/main/java/org/math/plot/components/PlotToolBar.java index 19ee39d..1202635 100644 --- a/src/main/java/org/math/plot/components/PlotToolBar.java +++ b/src/main/java/org/math/plot/components/PlotToolBar.java @@ -6,13 +6,14 @@ import javax.swing.*; import javax.swing.filechooser.FileFilter; +import javax.imageio.ImageIO; import org.math.plot.*; import org.math.plot.canvas.*; /** * BSD License - * + * * @author Yann RICHET */ public class PlotToolBar extends JToolBar { @@ -32,7 +33,9 @@ public class PlotToolBar extends JToolBar { protected JButton buttonAdjustBounds; private boolean denySaveSecurity; private JFileChooser pngFileChooser; - /** the currently selected PlotPanel */ + /** + * the currently selected PlotPanel + */ private PlotCanvas plotCanvas; private PlotPanel plotPanel; @@ -56,157 +59,155 @@ public String getDescription() { denySaveSecurity = true; } - buttonGroup = new ButtonGroup(); - - buttonCenter = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/center.png"))); - buttonCenter.setToolTipText("Center axis"); - buttonCenter.setSelected(plotCanvas.ActionMode == PlotCanvas.TRANSLATION); - - buttonZoom = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/zoom.png"))); - buttonZoom.setToolTipText("Zoom"); - buttonZoom.setSelected(plotCanvas.ActionMode == PlotCanvas.ZOOM); - - //buttonEdit = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/edit.png"))); - //buttonEdit.setToolTipText("Edit mode"); - - //buttonViewCoords = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/position.png"))); - //buttonViewCoords.setToolTipText("Highlight coordinates / Highlight plot"); - - buttonSetScales = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/scale.png"))); - buttonSetScales.setToolTipText("Edit axis scales"); - - buttonDatas = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/data.png"))); - buttonDatas.setToolTipText("Get data"); - - buttonSavePNGFile = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/topngfile.png"))); - buttonSavePNGFile.setToolTipText("Save graphics in a .PNG File"); - - buttonReset = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/back.png"))); - buttonReset.setToolTipText("Reset zoom & axis"); + try { + buttonGroup = new ButtonGroup(); - buttonAdjustBounds = new JButton(new ImageIcon(PlotPanel.class.getResource(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png"))); - buttonAdjustBounds.setToolTipText("Auto-update/fix bounds"); + buttonCenter = new JToggleButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/center.png")))); + buttonCenter.setToolTipText("Center axis"); + buttonCenter.setSelected(plotCanvas.ActionMode == PlotCanvas.TRANSLATION); - /*buttonEdit.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plotCanvas.ActionMode = PlotCanvas.EDIT; - } - });*/ + buttonZoom = new JToggleButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/zoom.png")))); + buttonZoom.setToolTipText("Zoom"); + buttonZoom.setSelected(plotCanvas.ActionMode == PlotCanvas.ZOOM); - buttonZoom.setSelected(true); - buttonZoom.addActionListener(new ActionListener() { + //buttonEdit = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/edit.png"))); + //buttonEdit.setToolTipText("Edit mode"); + //buttonViewCoords = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/position.png"))); + //buttonViewCoords.setToolTipText("Highlight coordinates / Highlight plot"); + buttonSetScales = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/scale.png")))); + buttonSetScales.setToolTipText("Edit axis scales"); - public void actionPerformed(ActionEvent e) { - plotCanvas.ActionMode = PlotCanvas.ZOOM; - } - }); + buttonDatas = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/data.png")))); + buttonDatas.setToolTipText("Get data"); - buttonCenter.addActionListener(new ActionListener() { + buttonSavePNGFile = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/topngfile.png")))); + buttonSavePNGFile.setToolTipText("Save graphics in a .PNG File"); - public void actionPerformed(ActionEvent e) { - plotCanvas.ActionMode = PlotCanvas.TRANSLATION; - } - }); + buttonReset = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/back.png"))); + buttonReset.setToolTipText("Reset zoom & axis"); - /*buttonViewCoords.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plotCanvas.setNoteCoords(buttonViewCoords.isSelected()); - } - });*/ + buttonAdjustBounds = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png")))); + buttonAdjustBounds.setToolTipText("Auto-update/fix bounds"); - buttonSetScales.addActionListener(new ActionListener() { + /*buttonEdit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + plotCanvas.ActionMode = PlotCanvas.EDIT; + } + });*/ + buttonZoom.setSelected(true); + buttonZoom.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plotCanvas.displayScalesFrame(); - } - }); + public void actionPerformed(ActionEvent e) { + plotCanvas.ActionMode = PlotCanvas.ZOOM; + } + }); - buttonDatas.addActionListener(new ActionListener() { + buttonCenter.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plotCanvas.displayDataFrame(); - } - }); + public void actionPerformed(ActionEvent e) { + plotCanvas.ActionMode = PlotCanvas.TRANSLATION; + } + }); - buttonSavePNGFile.addActionListener(new ActionListener() { + /*buttonViewCoords.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + plotCanvas.setNoteCoords(buttonViewCoords.isSelected()); + } + });*/ + buttonSetScales.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - choosePNGFile(); - } - }); + public void actionPerformed(ActionEvent e) { + plotCanvas.displayScalesFrame(); + } + }); - buttonReset.addActionListener(new ActionListener() { + buttonDatas.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plotCanvas.resetBase(); - } - }); + public void actionPerformed(ActionEvent e) { + plotCanvas.displayDataFrame(); + } + }); - buttonAdjustBounds.addActionListener(new ActionListener() { + buttonSavePNGFile.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plotCanvas.setAdjustBounds(!plotCanvas.getAdjustBounds()); - ajustBoundsChanged(); - } - }); - - buttonGroup.add(buttonCenter); - buttonGroup.add(buttonZoom); - //buttonGroup.add(buttonEdit); - - add(buttonCenter, null); - add(buttonZoom, null); - add(buttonReset, null); - //add(buttonViewCoords, null); - add(buttonSetScales, null); - if (adjustBoundsVisible) { - add(buttonAdjustBounds, null); - } - //add(buttonEdit, null); - add(buttonSavePNGFile, null); - add(buttonDatas, null); + public void actionPerformed(ActionEvent e) { + choosePNGFile(); + } + }); - if (!denySaveSecurity) { - pngFileChooser.addActionListener(new ActionListener() { + buttonReset.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - saveGraphicFile(); + plotCanvas.resetBase(); } }); - } else { - buttonSavePNGFile.setEnabled(false); - } - //buttonEdit.setEnabled(plotCanvas.getEditable()); + buttonAdjustBounds.addActionListener(new ActionListener() { - //buttonViewCoords.setEnabled(plotCanvas.getNotable()); + public void actionPerformed(ActionEvent e) { + plotCanvas.setAdjustBounds(!plotCanvas.getAdjustBounds()); + ajustBoundsChanged(); + } + }); - // allow mixed (2D/3D) plots managed by one toolbar - if (plotCanvas instanceof Plot3DCanvas) { - if (buttonRotate == null) { - buttonRotate = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/rotation.png"))); - buttonRotate.setToolTipText("Rotate axes"); + buttonGroup.add(buttonCenter); + buttonGroup.add(buttonZoom); + //buttonGroup.add(buttonEdit); + + add(buttonCenter, null); + add(buttonZoom, null); + add(buttonReset, null); + //add(buttonViewCoords, null); + add(buttonSetScales, null); + if (adjustBoundsVisible) { + add(buttonAdjustBounds, null); + } + //add(buttonEdit, null); + add(buttonSavePNGFile, null); + add(buttonDatas, null); - buttonRotate.addActionListener(new ActionListener() { + if (!denySaveSecurity) { + pngFileChooser.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - plotCanvas.ActionMode = Plot3DCanvas.ROTATION; + saveGraphicFile(); } }); - buttonGroup.add(buttonRotate); - add(buttonRotate, null, 2); - buttonRotate.setSelected(plotCanvas.ActionMode == Plot3DCanvas.ROTATION); } else { - buttonRotate.setEnabled(true); + buttonSavePNGFile.setEnabled(false); } - } else { - if (buttonRotate != null) { - // no removal/disabling just disable - if (plotCanvas.ActionMode == Plot3DCanvas.ROTATION) { - plotCanvas.ActionMode = PlotCanvas.ZOOM; + + //buttonEdit.setEnabled(plotCanvas.getEditable()); + //buttonViewCoords.setEnabled(plotCanvas.getNotable()); + // allow mixed (2D/3D) plots managed by one toolbar + if (plotCanvas instanceof Plot3DCanvas) { + if (buttonRotate == null) { + buttonRotate = new JToggleButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/rotation.png")))); + buttonRotate.setToolTipText("Rotate axes"); + + buttonRotate.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + plotCanvas.ActionMode = Plot3DCanvas.ROTATION; + } + }); + buttonGroup.add(buttonRotate); + add(buttonRotate, null, 2); + buttonRotate.setSelected(plotCanvas.ActionMode == Plot3DCanvas.ROTATION); + } else { + buttonRotate.setEnabled(true); + } + } else { + if (buttonRotate != null) { + // no removal/disabling just disable + if (plotCanvas.ActionMode == Plot3DCanvas.ROTATION) { + plotCanvas.ActionMode = PlotCanvas.ZOOM; + } + buttonRotate.setEnabled(false); } - buttonRotate.setEnabled(false); } + } catch (Exception e) { + e.printStackTrace(); } } @@ -237,6 +238,10 @@ public void viewAdjustBounds(boolean visible) { } public void ajustBoundsChanged() { - buttonAdjustBounds.setIcon(new ImageIcon(PlotPanel.class.getResource(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png"))); + try { + buttonAdjustBounds.setIcon(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png")))); + } catch (Exception e) { + e.printStackTrace(); + } } -} \ No newline at end of file +} diff --git a/src/main/java/org/math/plot/icons/adjustbounds.png b/src/main/java/org/math/plot/icons/adjustbounds.png deleted file mode 100644 index 075f531..0000000 Binary files a/src/main/java/org/math/plot/icons/adjustbounds.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/back.png b/src/main/java/org/math/plot/icons/back.png deleted file mode 100644 index 825c6f7..0000000 Binary files a/src/main/java/org/math/plot/icons/back.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/center.png b/src/main/java/org/math/plot/icons/center.png deleted file mode 100644 index 37db0f6..0000000 Binary files a/src/main/java/org/math/plot/icons/center.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/data.png b/src/main/java/org/math/plot/icons/data.png deleted file mode 100644 index b437f5b..0000000 Binary files a/src/main/java/org/math/plot/icons/data.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/edit.png b/src/main/java/org/math/plot/icons/edit.png deleted file mode 100644 index 67f56f1..0000000 Binary files a/src/main/java/org/math/plot/icons/edit.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/noadjustbounds.png b/src/main/java/org/math/plot/icons/noadjustbounds.png deleted file mode 100644 index f7e362a..0000000 Binary files a/src/main/java/org/math/plot/icons/noadjustbounds.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/position.png b/src/main/java/org/math/plot/icons/position.png deleted file mode 100644 index ef53c24..0000000 Binary files a/src/main/java/org/math/plot/icons/position.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/rotation.png b/src/main/java/org/math/plot/icons/rotation.png deleted file mode 100644 index ba7772a..0000000 Binary files a/src/main/java/org/math/plot/icons/rotation.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/scale.png b/src/main/java/org/math/plot/icons/scale.png deleted file mode 100644 index 9f1d555..0000000 Binary files a/src/main/java/org/math/plot/icons/scale.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/toclipboard.png b/src/main/java/org/math/plot/icons/toclipboard.png deleted file mode 100644 index b24a6f6..0000000 Binary files a/src/main/java/org/math/plot/icons/toclipboard.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/tofile.png b/src/main/java/org/math/plot/icons/tofile.png deleted file mode 100644 index 41b3f43..0000000 Binary files a/src/main/java/org/math/plot/icons/tofile.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/topngfile.png b/src/main/java/org/math/plot/icons/topngfile.png deleted file mode 100644 index 7208496..0000000 Binary files a/src/main/java/org/math/plot/icons/topngfile.png and /dev/null differ diff --git a/src/main/java/org/math/plot/icons/zoom.png b/src/main/java/org/math/plot/icons/zoom.png deleted file mode 100644 index 1b0ef4f..0000000 Binary files a/src/main/java/org/math/plot/icons/zoom.png and /dev/null differ diff --git a/src/main/java/org/math/plot/plotObjects/Axis.java b/src/main/java/org/math/plot/plotObjects/Axis.java index 34934fc..17893ec 100644 --- a/src/main/java/org/math/plot/plotObjects/Axis.java +++ b/src/main/java/org/math/plot/plotObjects/Axis.java @@ -238,13 +238,15 @@ public void plot(AbstractDrawer draw) { ); for (int i = 0; i < lightLabels.length; i=i+inc) { - lightLabels[i].plot(draw); + if(lightLabels[i]!=null) + lightLabels[i].plot(draw); } draw.setLineType(AbstractDrawer.DOTTED_LINE); for (int i = 0; i < lightLines.length; i++) { for (int j = base.getAxeScale(index).equalsIgnoreCase(Base.STRINGS) ? 0 : 1; j < lightLines[i].length; j=j+inc) { - lightLines[i][j].plot(draw); + if(lightLines[i][j]!=null) + lightLines[i][j].plot(draw); } } } @@ -633,4 +635,4 @@ public static void main(String[] args) { System.out.println(it.next()); } } -} \ No newline at end of file +} diff --git a/src/main/java/org/math/plot/plots/LinePlot.java b/src/main/java/org/math/plot/plots/LinePlot.java index cf1c309..4bd8690 100644 --- a/src/main/java/org/math/plot/plots/LinePlot.java +++ b/src/main/java/org/math/plot/plots/LinePlot.java @@ -33,9 +33,17 @@ public void plot(AbstractDrawer draw, Color c) { draw.setColor(c); draw.setLineType(AbstractDrawer.CONTINOUS_LINE); for (int i = 0; i < XY.length - 1; i++) + if (!anyNaN(XY[i]) && !anyNaN(XY[i+1])) draw.drawLine(XY[i], XY[i + 1]); } + boolean anyNaN(double[] xy) { + for (int i = 0; i < xy.length; i++) { + if(Double.isNaN(xy[i])) return true; + } + return false; + } + public static void main(String[] args) { Plot2DPanel p2 = new Plot2DPanel(); @@ -44,6 +52,7 @@ public static void main(String[] args) { XYZ[j][0] = 2*Math.PI*(double)j/XYZ.length; XYZ[j][1] = Math.sin(XYZ[j][0]); } + XYZ[50][0] = Double.NaN; p2.addLinePlot("sin" , XYZ); diff --git a/src/main/java/org/math/plot/render/Projection.java b/src/main/java/org/math/plot/render/Projection.java index 5019a19..d3d3e01 100644 --- a/src/main/java/org/math/plot/render/Projection.java +++ b/src/main/java/org/math/plot/render/Projection.java @@ -28,7 +28,9 @@ public void initBaseCoordsProjection(boolean reset) { } for (int i = 0; i < draw.canvas.base.dimension + 1; i++) { // Compute the basis extremity coordinates in the normed-centered screen (ie [-0.5,0.5]x[-0.5,0.5] screen) - double[] ratio = baseCoordsScreenProjectionRatio(draw.canvas.base.baseCoords[i]); + double[] ratio = new double[]{1,1}; + if (draw.canvas.base.baseCoords!=null) + ratio = baseCoordsScreenProjectionRatio(draw.canvas.base.baseCoords[i]); // Compute the basis extremity coordinates in the true screen (ie in px: [0,400]x[0,400]) baseScreenCoords[i][0] = (int) (draw.canvas.getWidth() * (.5 + (borderCoeff * ratio[0] / totalScreenRatio[0]))); baseScreenCoords[i][1] = (int) (draw.canvas.getHeight() * (.5 - (borderCoeff * ratio[1] / totalScreenRatio[1]))); @@ -89,7 +91,8 @@ public int[] screenProjection(double... pC) { if (draw.canvas.base.axesScales[i].equalsIgnoreCase(Base.LOGARITHM)) { normdist_pC_baseCoords = ((FastMath.log(pC[i]) - FastMath.log(draw.canvas.base.baseCoords[0][i])) / (FastMath.log(draw.canvas.base.baseCoords[i + 1][i]) - FastMath.log(draw.canvas.base.baseCoords[0][i]))); } else if (draw.canvas.base.axesScales[i].equalsIgnoreCase(Base.LINEAR) || draw.canvas.base.axesScales[i].equalsIgnoreCase(Base.STRINGS)) { - normdist_pC_baseCoords = ((pC[i] - draw.canvas.base.baseCoords[0][i]) / (draw.canvas.base.baseCoords[i + 1][i] - draw.canvas.base.baseCoords[0][i])); + if(pC!=null && draw.canvas.base.baseCoords!=null && draw.canvas.base.baseCoords[i+1] != null) + normdist_pC_baseCoords = ((pC[i] - draw.canvas.base.baseCoords[0][i]) / (draw.canvas.base.baseCoords[i + 1][i] - draw.canvas.base.baseCoords[0][i])); } sC[0] += normdist_pC_baseCoords * (baseScreenCoords[i + 1][0] - baseScreenCoords[0][0]); sC[1] += normdist_pC_baseCoords * (baseScreenCoords[i + 1][1] - baseScreenCoords[0][1]); diff --git a/src/main/java/org/math/plot/utils/Array.java b/src/main/java/org/math/plot/utils/Array.java index 6a013c2..6dc0eb4 100644 --- a/src/main/java/org/math/plot/utils/Array.java +++ b/src/main/java/org/math/plot/utils/Array.java @@ -448,7 +448,9 @@ public static double[] min(double[][] M) { for (int j = 0; j < min.length; j++) { min[j] = M[0][j]; for (int i = 1; i < M.length; i++) { - min[j] = FastMath.min(min[j], M[i][j]); + if (!Double.isNaN(M[i][j])) { + min[j] = FastMath.min(min[j], M[i][j]); + } } } return min; @@ -473,7 +475,9 @@ public static int max(int... M) { public static double min(double... M) { double min = M[0]; for (int i = 1; i < M.length; i++) { - min = FastMath.min(min, M[i]); + if (!Double.isNaN(M[i])) { + min = FastMath.min(min, M[i]); + } } return min; } @@ -483,7 +487,9 @@ public static double[] max(double[][] M) { for (int j = 0; j < max.length; j++) { max[j] = M[0][j]; for (int i = 1; i < M.length; i++) { - max[j] = FastMath.max(max[j], M[i][j]); + if (!Double.isNaN(M[i][j])) { + max[j] = FastMath.max(max[j], M[i][j]); + } } } return max; @@ -492,7 +498,9 @@ public static double[] max(double[][] M) { public static double max(double... M) { double max = M[0]; for (int i = 1; i < M.length; i++) { - max = FastMath.max(max, M[i]); + if (!Double.isNaN(M[i])) { + max = FastMath.max(max, M[i]); + } } return max; } diff --git a/src/main/java/org/math/plot/utils/Histogram.java b/src/main/java/org/math/plot/utils/Histogram.java index 651f10d..dd47d1b 100644 --- a/src/main/java/org/math/plot/utils/Histogram.java +++ b/src/main/java/org/math/plot/utils/Histogram.java @@ -26,8 +26,10 @@ public static double[] histogram(double[] values, double[] bounds) { double[] h = new double[bounds.length - 1]; for (int i = 0; i < values.length; i++) { for (int j = 0; j < h.length; j++) { - if (((bounds[j + 1] - values[i]) * (bounds[j] - values[i]) < 0) || ((bounds[j] == values[i]))) + if (((bounds[j + 1] - values[i]) * (bounds[j] - values[i]) <= 0) || ((bounds[j] == values[i]))) { h[j]++; + break; + } } } return h;