Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Code to Address Implementation and Design Smells #885

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
Expand All @@ -20,77 +18,26 @@ public class DemoChartsUtil {
private static final String DEMO_CHARTS_PACKAGE = "org.knowm.xchart.demo.charts";

public static List<ExampleChart<Chart<Styler, Series>>> getAllDemoCharts() {

List<ExampleChart<Chart<Styler, Series>>> demoCharts = null;
String packagePath = DEMO_CHARTS_PACKAGE.replace(".", "/");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource(packagePath);

if (url != null) {
try {
demoCharts = getAllDemoCharts(url);
demoCharts = URLClassUtil.getAllDemoCharts(url);
} catch (Exception e) {
e.printStackTrace();
}
}

return demoCharts;
}

@SuppressWarnings("unchecked")
private static List<ExampleChart<Chart<Styler, Series>>> getAllDemoCharts(URL url)
throws Exception {

List<ExampleChart<Chart<Styler, Series>>> demoCharts = new ArrayList<>();

List<Class<?>> classes = getAllAssignedClasses(url);
// sort
Collections.sort(
classes,
new Comparator<Class<?>>() {

@Override
public int compare(Class<?> c1, Class<?> c2) {
return c1.getName().compareTo(c2.getName());
}
});

for (Class<?> c : classes) {
demoCharts.add(((ExampleChart<Chart<Styler, Series>>) c.newInstance()));
}
return demoCharts;
}

private static List<Class<?>> getAllAssignedClasses(URL url)
throws ClassNotFoundException, IOException {

List<Class<?>> classes = null;

String type = url.getProtocol();
if ("file".equals(type)) {
classes = getClassesByFile(new File(url.getFile()), DEMO_CHARTS_PACKAGE);
} else if ("jar".equals(type)) {
classes = getClassesByJar(url.getPath());
}
List<Class<?>> allAssignedClasses = new ArrayList<>();
if (classes != null) {
for (Class<?> c : classes) {
if (ExampleChart.class.isAssignableFrom(c) && !ExampleChart.class.equals(c)) {
allAssignedClasses.add(c);
}
}
}
return allAssignedClasses;
}

private static List<Class<?>> getClassesByFile(File dir, String pk)
throws ClassNotFoundException {

public static List<Class<?>> getClassesByFile(File dir, String pk) throws ClassNotFoundException {
List<Class<?>> classes = new ArrayList<>();
if (!dir.exists()) {
return classes;
}

String fileName = "";
for (File f : dir.listFiles()) {
fileName = f.getName();
Expand All @@ -101,14 +48,12 @@ private static List<Class<?>> getClassesByFile(File dir, String pk)
Class.forName(pk + "." + fileName.substring(0, fileName.length() - ".class".length())));
}
}

return classes;
}

@SuppressWarnings("resource")
private static List<Class<?>> getClassesByJar(String jarPath)
public static List<Class<?>> getClassesByJar(String jarPath)
throws IOException, ClassNotFoundException {

List<Class<?>> classes = new ArrayList<>();
String[] jarInfo = jarPath.split("!");
String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
Expand Down
58 changes: 58 additions & 0 deletions xchart-demo/src/main/java/org/knowm/xchart/demo/URLClassUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.knowm.xchart.demo;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.knowm.xchart.demo.charts.ExampleChart;
import org.knowm.xchart.internal.chartpart.Chart;
import org.knowm.xchart.internal.series.Series;
import org.knowm.xchart.style.Styler;

public class URLClassUtil {

private static final String DEMO_CHARTS_PACKAGE = "org.knowm.xchart.demo.charts";

@SuppressWarnings("unchecked")
public static List<ExampleChart<Chart<Styler, Series>>> getAllDemoCharts(URL url)
throws Exception {
List<ExampleChart<Chart<Styler, Series>>> demoCharts = new ArrayList<>();
List<Class<?>> classes = getAllAssignedClasses(url);
// sort
Collections.sort(
classes,
new Comparator<Class<?>>() {
@Override
public int compare(Class<?> c1, Class<?> c2) {
return c1.getName().compareTo(c2.getName());
}
});
for (Class<?> c : classes) {
demoCharts.add(((ExampleChart<Chart<Styler, Series>>) c.newInstance()));
}
return demoCharts;
}

public static List<Class<?>> getAllAssignedClasses(URL url)
throws ClassNotFoundException, IOException {
List<Class<?>> classes = null;
String type = url.getProtocol();
if ("file".equals(type)) {
classes = DemoChartsUtil.getClassesByFile(new File(url.getFile()), DEMO_CHARTS_PACKAGE);
} else if ("jar".equals(type)) {
classes = DemoChartsUtil.getClassesByJar(url.getPath());
}
List<Class<?>> allAssignedClasses = new ArrayList<>();
if (classes != null) {
for (Class<?> c : classes) {
if (ExampleChart.class.isAssignableFrom(c) && !ExampleChart.class.equals(c)) {
allAssignedClasses.add(c);
}
}
}
return allAssignedClasses;
}
}
13 changes: 0 additions & 13 deletions xchart/src/main/java/org/knowm/xchart/CategoryChart.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,6 @@ public CategoryChart(int width, int height, ChartTheme chartTheme) {
this(width, height, chartTheme.newInstance(chartTheme));
}

/**
* Constructor
*
* @param chartBuilder
*/
public CategoryChart(CategoryChartBuilder chartBuilder) {

this(chartBuilder.width, chartBuilder.height, chartBuilder.chartTheme);
setTitle(chartBuilder.title);
setXAxisTitle(chartBuilder.xAxisTitle);
setYAxisTitle(chartBuilder.yAxisTitle);
}

/**
* Add a series for a Category type chart using using double arrays
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public CategoryChartBuilder yAxisTitle(String yAxisTitle) {
*/
@Override
public CategoryChart build() {

return new CategoryChart(this);
// Pass the configured properties to CategoryChart during creation
CategoryChart chart = new CategoryChart(this.width, this.height, this.chartTheme);
chart.setTitle(this.title);
chart.setXAxisTitle(this.xAxisTitle);
chart.setYAxisTitle(this.yAxisTitle);
return chart;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,10 @@ public double getChartValue(double screenPoint) {

minVal = isLog ? Math.log10(minVal) : minVal;
maxVal = isLog ? Math.log10(maxVal) : maxVal;
double value = ((screenPoint - margin - startOffset) * (maxVal - minVal) / tickSpace) + minVal;
double adjustedScreenPoint = screenPoint - margin - startOffset;
double valueRange = maxVal - minVal;
double normalizedValue = (adjustedScreenPoint * valueRange) / tickSpace;
double value = normalizedValue + minVal;
value = isLog ? Math.pow(10, value) : value;
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,25 +331,12 @@ private void prepareForPaint() {
}
}
// infinity checks
if (xAxis.getMin() == Double.POSITIVE_INFINITY || xAxis.getMax() == Double.POSITIVE_INFINITY) {
throw new IllegalArgumentException(
"Series data (accounting for error bars too) cannot be equal to Double.POSITIVE_INFINITY!!!");
}
checkAxisForPositiveInfinity(xAxis);
for (Axis<ST, S> ya : yAxisMap.values()) {
if (ya.getMin() == Double.POSITIVE_INFINITY || ya.getMax() == Double.POSITIVE_INFINITY) {
throw new IllegalArgumentException(
"Series data (accounting for error bars too) cannot be equal to Double.POSITIVE_INFINITY!!!");
}
if (ya.getMin() == Double.NEGATIVE_INFINITY || ya.getMax() == Double.NEGATIVE_INFINITY) {
throw new IllegalArgumentException(
"Series data (accounting for error bars too) cannot be equal to Double.NEGATIVE_INFINITY!!!");
}
}

if (xAxis.getMin() == Double.NEGATIVE_INFINITY || xAxis.getMax() == Double.NEGATIVE_INFINITY) {
throw new IllegalArgumentException(
"Series data (accounting for error bars too) cannot be equal to Double.NEGATIVE_INFINITY!!!");
checkAxisForPositiveInfinity(ya);
checkAxisForNegativeInfinity(ya);
}
checkAxisForNegativeInfinity(xAxis);
}

/**
Expand Down Expand Up @@ -529,4 +516,18 @@ Axis<ST, S> getRightMainYAxis() {

return rightMainYAxis;
}

private void checkAxisForPositiveInfinity(Axis<ST, S> axis) {
if (axis.getMin() == Double.POSITIVE_INFINITY || axis.getMax() == Double.POSITIVE_INFINITY) {
throw new IllegalArgumentException(
"Series data (accounting for error bars too) cannot be equal to Double.POSITIVE_INFINITY!!!");
}
}

private void checkAxisForNegativeInfinity(Axis<ST, S> axis) {
if (axis.getMin() == Double.NEGATIVE_INFINITY || axis.getMax() == Double.NEGATIVE_INFINITY) {
throw new IllegalArgumentException(
"Series data (accounting for error bars too) cannot be equal to Double.NEGATIVE_INFINITY!!!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.text.Format;
Expand Down Expand Up @@ -159,6 +161,28 @@ public void setYAxisGroupTitle(int yAxisGroup, String yAxisTitle) {
yAxisGroupTitleMap.put(yAxisGroup, yAxisTitle);
}

public Rectangle2D getBoundsHint() {

if (this.getStyler().isChartTitleVisible() && this.getTitle().length() > 0) {

TextLayout textLayout =
new TextLayout(
this.getTitle(),
this.getStyler().getChartTitleFont(),
new FontRenderContext(null, true, false));
Rectangle2D rectangle = textLayout.getBounds();
double width = 2 * this.getStyler().getChartTitlePadding() + rectangle.getWidth();
double height = 2 * this.getStyler().getChartTitlePadding() + rectangle.getHeight();

return new Rectangle2D.Double(
Double.NaN, Double.NaN, width, height); // Double.NaN indicates not sure yet.
} else {
return new Rectangle2D
.Double(); // Constructs a new Rectangle2D, initialized to location (0, 0) and size (0,
// 0).
}
}

public void addAnnotation(Annotation annotation) {

annotations.add(annotation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,35 +99,13 @@ public void paint(Graphics2D g) {
*
* @return a Rectangle2D defining the height of the chart title including the chart title padding
*/
private Rectangle2D getBoundsHint() {

if (chart.getStyler().isChartTitleVisible() && chart.getTitle().length() > 0) {

TextLayout textLayout =
new TextLayout(
chart.getTitle(),
chart.getStyler().getChartTitleFont(),
new FontRenderContext(null, true, false));
Rectangle2D rectangle = textLayout.getBounds();
double width = 2 * chart.getStyler().getChartTitlePadding() + rectangle.getWidth();
double height = 2 * chart.getStyler().getChartTitlePadding() + rectangle.getHeight();

return new Rectangle2D.Double(
Double.NaN, Double.NaN, width, height); // Double.NaN indicates not sure yet.
} else {
return new Rectangle2D
.Double(); // Constructs a new Rectangle2D, initialized to location (0, 0) and size (0,
// 0).
}
}

@Override
public Rectangle2D getBounds() {

if (bounds
== null) { // was not drawn fully yet, just need the height hint. The Plot object will be
// asking for it.
bounds = getBoundsHint();
bounds = chart.getBoundsHint();
}
return bounds;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ public void paint(Graphics2D g) {
// or 2. nothing should be drawn or 3. the zoom area
// should be drawn

if (resetButton.visible && (x1 == -1 || x2 == -1)) { //
if (isResetButtonVisibleAndInvalidXCoordinates(x1, x2)) { //
resetButton.paint(g);
} else if (x1 == -1 || x2 == -1) {
} else if (isEitherXInvalid(x1, x2)) {
return;
} else {
g.setColor(xyChart.getStyler().getZoomSelectionColor());
Expand Down Expand Up @@ -241,4 +241,16 @@ private boolean isOverlapping() {
}
return isOverlapping;
}

private boolean isResetButtonVisible() {
return resetButton.visible;
}

private boolean isEitherXInvalid(int x1, int x2) {
return x1 == -1 || x2 == -1;
}

private boolean isResetButtonVisibleAndInvalidXCoordinates(int x1, int x2) {
return isResetButtonVisible() && isEitherXInvalid(x1, x2);
}
}
12 changes: 1 addition & 11 deletions xchart/src/test/java/org/knowm/xchart/CategoryChartTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.knowm.xchart.custom.CustomGraphic;
import org.knowm.xchart.custom.CustomTheme;
import org.knowm.xchart.internal.series.Series;
import org.knowm.xchart.style.Styler;

public class CategoryChartTest {

Expand All @@ -25,20 +24,11 @@ void setUp() {

@Test
void constructor() {
CategoryChartBuilder builder =
new CategoryChartBuilder()
.width(800)
.height(600)
.theme(Styler.ChartTheme.GGPlot2)
.title("CategoryChart")
.xAxisTitle("x-axis")
.yAxisTitle("y-axis");

assertAll(
() -> assertDoesNotThrow(() -> new CategoryChart(800, 600)),
() -> assertDoesNotThrow(() -> new CategoryChart(800, 600, new CustomTheme())),
() -> assertDoesNotThrow(() -> new CategoryChart(800, 600, XChart)),
() -> assertDoesNotThrow(() -> new CategoryChart(builder)));
() -> assertDoesNotThrow(() -> new CategoryChart(800, 600, XChart)));
}

@Test
Expand Down
Loading