Skip to content
Snippets Groups Projects
Commit 389b49eb authored by Tim Molter's avatar Tim Molter
Browse files

finished new and improved auto-decimal fomatter

parent 39e20206
Branches
No related tags found
No related merge requests found
...@@ -33,6 +33,7 @@ import com.xeiam.xchart.demo.charts.ExampleChart; ...@@ -33,6 +33,7 @@ import com.xeiam.xchart.demo.charts.ExampleChart;
* <li>ChartType.Scatter * <li>ChartType.Scatter
* <li>Series data as a Set * <li>Series data as a Set
* <li>Setting marker size * <li>Setting marker size
* <li>Formatting of negative numbers with large magnitude but small differences
*/ */
public class ScatterChart01 implements ExampleChart { public class ScatterChart01 implements ExampleChart {
...@@ -52,7 +53,7 @@ public class ScatterChart01 implements ExampleChart { ...@@ -52,7 +53,7 @@ public class ScatterChart01 implements ExampleChart {
int size = 1000; int size = 1000;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
xData.add(random.nextGaussian()); xData.add(random.nextGaussian());
yData.add(random.nextGaussian()); yData.add(-100 + random.nextGaussian());
} }
// Create Chart // Create Chart
......
...@@ -33,6 +33,7 @@ import com.xeiam.xchart.demo.charts.ExampleChart; ...@@ -33,6 +33,7 @@ import com.xeiam.xchart.demo.charts.ExampleChart;
* <li>Scatter chart * <li>Scatter chart
* <li>Logarithmic X-Axis * <li>Logarithmic X-Axis
* <li>Place legend at Inside-NW position * <li>Place legend at Inside-NW position
* <li>Formatting of number with large magnitude but small differences
* *
* @author timmolter * @author timmolter
*/ */
......
...@@ -1097,9 +1097,9 @@ public class StyleManager { ...@@ -1097,9 +1097,9 @@ public class StyleManager {
* *
* @param pattern - the pattern describing the decimal format * @param pattern - the pattern describing the decimal format
*/ */
public void setDecimalPattern(String normalDecimalPattern) { public void setDecimalPattern(String decimalPattern) {
this.decimalPattern = normalDecimalPattern; this.decimalPattern = decimalPattern;
} }
public String getDecimalPattern() { public String getDecimalPattern() {
......
...@@ -108,8 +108,6 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { ...@@ -108,8 +108,6 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator {
NumberFormatter numberFormatter = null; NumberFormatter numberFormatter = null;
DateFormatter dateFormatter = null; DateFormatter dateFormatter = null;
String pattern = numberFormatter.getFormatPattern(minValue, maxValue);
if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) {
numberFormatter = new NumberFormatter(styleManager); numberFormatter = new NumberFormatter(styleManager);
} }
...@@ -120,7 +118,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { ...@@ -120,7 +118,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator {
for (Object category : categories) { for (Object category : categories) {
if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) {
tickLabels.add(numberFormatter.formatNumber((Double) category, pattern)); tickLabels.add(numberFormatter.formatNumber((Double) category, minValue, maxValue));
} }
else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) {
long span = (long) Math.abs(maxValue - minValue); // in data space long span = (long) Math.abs(maxValue - minValue); // in data space
...@@ -141,8 +139,6 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { ...@@ -141,8 +139,6 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator {
NumberFormatter numberFormatter = null; NumberFormatter numberFormatter = null;
DateFormatter dateFormatter = null; DateFormatter dateFormatter = null;
String pattern = numberFormatter.getFormatPattern(minValue, maxValue);
if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) {
numberFormatter = new NumberFormatter(styleManager); numberFormatter = new NumberFormatter(styleManager);
} }
...@@ -153,7 +149,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { ...@@ -153,7 +149,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator {
for (double tickPosition = firstPosition; tickPosition <= maxValue; tickPosition = tickPosition + gridStep) { for (double tickPosition = firstPosition; tickPosition <= maxValue; tickPosition = tickPosition + gridStep) {
if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) {
tickLabels.add(numberFormatter.formatNumber(tickPosition, pattern)); tickLabels.add(numberFormatter.formatNumber(tickPosition, minValue, maxValue));
} }
else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) {
long span = (long) Math.abs(maxValue - minValue); // in data space long span = (long) Math.abs(maxValue - minValue); // in data space
......
...@@ -46,11 +46,9 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator { ...@@ -46,11 +46,9 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator {
private void calculate() { private void calculate() {
String pattern = numberFormatter.getFormatPattern(minValue, maxValue);
// a check if all axis data are the exact same values // a check if all axis data are the exact same values
if (minValue == maxValue) { if (minValue == maxValue) {
tickLabels.add(numberFormatter.formatNumber(maxValue, pattern)); tickLabels.add(numberFormatter.formatNumber(maxValue, minValue, maxValue));
tickLocations.add(workingSpace / 2.0); tickLocations.add(workingSpace / 2.0);
return; return;
} }
...@@ -113,7 +111,7 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator { ...@@ -113,7 +111,7 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator {
// only add labels for the decades // only add labels for the decades
if (Math.abs(Math.log10(j) % 1) < 0.00000001) { if (Math.abs(Math.log10(j) % 1) < 0.00000001) {
tickLabels.add(numberFormatter.formatNumber(j, pattern)); tickLabels.add(numberFormatter.formatLogNumber(j));
} }
else { else {
tickLabels.add(null); tickLabels.add(null);
......
...@@ -48,11 +48,9 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { ...@@ -48,11 +48,9 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator {
private void calculate() { private void calculate() {
String pattern = numberFormatter.getFormatPattern(minValue, maxValue);
// a check if all axis data are the exact same values // a check if all axis data are the exact same values
if (minValue == maxValue) { if (minValue == maxValue) {
tickLabels.add(numberFormatter.formatNumber(maxValue, pattern)); tickLabels.add(numberFormatter.formatNumber(maxValue, minValue, maxValue));
tickLocations.add(workingSpace / 2.0); tickLocations.add(workingSpace / 2.0);
return; return;
} }
...@@ -69,7 +67,7 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { ...@@ -69,7 +67,7 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator {
// generate all tickLabels and tickLocations from the first to last position // generate all tickLabels and tickLocations from the first to last position
for (BigDecimal tickPosition = firstPosition; tickPosition.compareTo(BigDecimal.valueOf(maxValue + gridStep.doubleValue() * 0.2)) <= 0; tickPosition = tickPosition.add(gridStep)) { for (BigDecimal tickPosition = firstPosition; tickPosition.compareTo(BigDecimal.valueOf(maxValue + gridStep.doubleValue() * 0.2)) <= 0; tickPosition = tickPosition.add(gridStep)) {
tickLabels.add(numberFormatter.formatNumber(tickPosition.doubleValue(), pattern)); tickLabels.add(numberFormatter.formatNumber(tickPosition.doubleValue(), minValue, maxValue));
// here we convert tickPosition finally to plot space, i.e. pixels // here we convert tickPosition finally to plot space, i.e. pixels
double tickLabelPosition = margin + ((tickPosition.doubleValue() - minValue) / (maxValue - minValue) * tickSpace); double tickLabelPosition = margin + ((tickPosition.doubleValue() - minValue) / (maxValue - minValue) * tickSpace);
tickLocations.add(tickLabelPosition); tickLocations.add(tickLabelPosition);
......
...@@ -35,36 +35,43 @@ public class NumberFormatter { ...@@ -35,36 +35,43 @@ public class NumberFormatter {
this.styleManager = styleManager; this.styleManager = styleManager;
} }
public String getFormatPattern(double min, double max) { public String getFormatPattern(double value, double min, double max) {
System.out.println("value: " + value);
System.out.println("min: " + min); System.out.println("min: " + min);
System.out.println("max: " + max); System.out.println("max: " + max);
double difference = max - min; double difference = max - min;
int placeOfDifference = (int) Math.floor(Math.log(difference) / Math.log(10)) + 1; int placeOfDifference;
int placeOfSmallest = (int) Math.floor(Math.log(Math.min(Math.abs(min), Math.abs(max))) / Math.log(10)) + 1; if (difference == 0.0) {
placeOfDifference = 0;
}
else {
placeOfDifference = (int) Math.floor(Math.log(difference) / Math.log(10));
}
int placeOfValue = (int) Math.floor(Math.log(value) / Math.log(10));
System.out.println("difference: " + difference); System.out.println("difference: " + difference);
System.out.println("placeOfDifference: " + placeOfDifference); System.out.println("placeOfDifference: " + placeOfDifference);
System.out.println("placeOfSmallest: " + placeOfSmallest); System.out.println("placeOfValue: " + placeOfValue);
if (placeOfDifference <= 4 && placeOfDifference >= -4) { if (placeOfDifference <= 4 && placeOfDifference >= -4) {
System.out.println("getNormalDecimalPattern"); System.out.println("getNormalDecimalPattern");
return getNormalDecimalPattern(placeOfSmallest, placeOfDifference); return getNormalDecimalPattern(placeOfValue, placeOfDifference);
} }
else { else {
System.out.println("getScientificDecimalPattern"); System.out.println("getScientificDecimalPattern");
return getScientificDecimalPattern(placeOfSmallest, placeOfDifference); return getScientificDecimalPattern(placeOfValue, placeOfDifference);
} }
} }
private String getNormalDecimalPattern(int placeOfMin, int placeOfDifference) { private String getNormalDecimalPattern(int placeOfValue, int placeOfDifference) {
int maxNumPlaces = 15; int maxNumPlaces = 15;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = maxNumPlaces - 1; i >= -1 * maxNumPlaces; i--) { for (int i = maxNumPlaces - 1; i >= -1 * maxNumPlaces; i--) {
if (i < placeOfMin && i >= placeOfDifference - 2) { if (i < placeOfValue && i >= placeOfDifference) {
sb.append("0"); sb.append("0");
} }
else { else {
...@@ -81,10 +88,10 @@ public class NumberFormatter { ...@@ -81,10 +88,10 @@ public class NumberFormatter {
return sb.toString(); return sb.toString();
} }
private String getScientificDecimalPattern(int placeOfMin, int placeOfDifference) { private String getScientificDecimalPattern(int placeOfValue, int placeOfDifference) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = placeOfMin; i >= 0; i--) { for (int i = placeOfValue; i >= 0; i--) {
sb.append("0"); sb.append("0");
if (i == placeOfDifference) { if (i == placeOfDifference) {
sb.append("."); sb.append(".");
...@@ -101,12 +108,48 @@ public class NumberFormatter { ...@@ -101,12 +108,48 @@ public class NumberFormatter {
* @param value * @param value
* @return * @return
*/ */
public String formatNumber(double value, String pattern) { public String formatNumber(double value, double min, double max) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(styleManager.getLocale());
String decimalPattern;
if (styleManager.getDatePattern() == null) {
decimalPattern = getFormatPattern(value, min, max);
}
else {
decimalPattern = styleManager.getDecimalPattern();
}
DecimalFormat normalFormat = (DecimalFormat) numberFormat;
normalFormat.applyPattern(decimalPattern);
return normalFormat.format(value);
}
/**
* Format a log number value for log Axes which show only decade tick labels. if the override patterns are null, it uses defaults
*
* @param value
* @return
*/
public String formatLogNumber(double value) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(styleManager.getLocale()); NumberFormat numberFormat = NumberFormat.getNumberInstance(styleManager.getLocale());
String decimalPattern;
if (styleManager.getDatePattern() == null) {
decimalPattern = "0E0";
}
else {
decimalPattern = styleManager.getDatePattern();
}
DecimalFormat normalFormat = (DecimalFormat) numberFormat; DecimalFormat normalFormat = (DecimalFormat) numberFormat;
normalFormat.applyPattern(styleManager.getDecimalPattern() == null ? pattern : styleManager.getDecimalPattern()); normalFormat.applyPattern(decimalPattern);
return normalFormat.format(value); return normalFormat.format(value);
} }
......
/**
* Copyright 2011 - 2014 Xeiam LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.xeiam.xchart;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;
import com.xeiam.xchart.internal.chartpart.NumberFormatter;
/**
* @author timmolter
*/
public class NumberFormatterTest2 {
@Test
public void testNumberFormatting() {
StyleManager styleManager = new StyleManager();
NumberFormatter numberFormatter = new NumberFormatter(styleManager);
String pattern = numberFormatter.getFormatPattern(1000000, 1000010);
System.out.println(pattern);
assertThat(pattern, equalTo("00000.00E0"));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment