From 64c503bba7e01f960960ee08a4ac88e88647a797 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 2 Sep 2024 09:16:05 +0200 Subject: [PATCH] Showcase axis formatting #233 --- .../chartjs/model/ChartAxisFormatTest.java | 113 ++++++++++++++++++ .../BarChartAxisTickCallback.png | Bin 0 -> 12395 bytes .../screenshotReferences/BarChartFormat.png | Bin 0 -> 12149 bytes 3 files changed, 113 insertions(+) create mode 100644 chartjs-java-model/src/test/java/software/xdev/chartjs/model/ChartAxisFormatTest.java create mode 100644 chartjs-java-model/src/test/resources/screenshotReferences/BarChartAxisTickCallback.png create mode 100644 chartjs-java-model/src/test/resources/screenshotReferences/BarChartFormat.png diff --git a/chartjs-java-model/src/test/java/software/xdev/chartjs/model/ChartAxisFormatTest.java b/chartjs-java-model/src/test/java/software/xdev/chartjs/model/ChartAxisFormatTest.java new file mode 100644 index 0000000..cb84843 --- /dev/null +++ b/chartjs-java-model/src/test/java/software/xdev/chartjs/model/ChartAxisFormatTest.java @@ -0,0 +1,113 @@ +/* + * Copyright © 2023 XDEV Software (https://xdev.software) + * + * 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 software.xdev.chartjs.model; + +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; + +import software.xdev.chartjs.model.charts.BarChart; +import software.xdev.chartjs.model.color.Color; +import software.xdev.chartjs.model.data.BarData; +import software.xdev.chartjs.model.dataset.BarDataset; +import software.xdev.chartjs.model.javascript.JavaScriptFunction; +import software.xdev.chartjs.model.options.BarOptions; +import software.xdev.chartjs.model.options.scale.Scales; +import software.xdev.chartjs.model.options.scale.cartesian.linear.LinearScaleOptions; +import software.xdev.chartjs.model.options.scale.cartesian.linear.LinearTickOptions; + + +@SuppressWarnings("java:S2699") // Done in custom method +class ChartAxisFormatTest extends AbstractChartTest +{ + @Test + void axisTickCallback() + { + this.createScreenshotAndCompare( + new BarChart(data(), options(l -> l.setCallback(new JavaScriptFunction("(label) => `$${label}`")))), + this.getWebContainer(), + "AxisTickCallback"); + } + + @Test + void format() + { + this.createScreenshotAndCompare( + new BarChart(data(), options(l -> l.setFormat(new CurrencyFormatOptions("currency", "USD")))), + this.getWebContainer(), + "Format"); + } + + public static class CurrencyFormatOptions + { + private String style; + private String currency; + + public CurrencyFormatOptions() + { + } + + public CurrencyFormatOptions(final String style, final String currency) + { + this.style = style; + this.currency = currency; + } + + public String getStyle() + { + return this.style; + } + + public void setStyle(final String style) + { + this.style = style; + } + + public String getCurrency() + { + return this.currency; + } + + public void setCurrency(final String currency) + { + this.currency = currency; + } + } + + static BarData data() + { + final BarDataset dataset1 = new BarDataset() + .setData(65) + .addBackgroundColors(Color.RED); + + return new BarData() + .addLabels("First") + .addDataset(dataset1); + } + + static BarOptions options(final Consumer configureTickOptions) + { + final LinearTickOptions linearTickOptions = new LinearTickOptions(); + configureTickOptions.accept(linearTickOptions); + + final BarOptions options = new BarOptions().setAnimation(false); + options + .getScales() + .addScale(Scales.ScaleAxis.Y, new LinearScaleOptions() + .setTicks(linearTickOptions)); + return options; + } +} diff --git a/chartjs-java-model/src/test/resources/screenshotReferences/BarChartAxisTickCallback.png b/chartjs-java-model/src/test/resources/screenshotReferences/BarChartAxisTickCallback.png new file mode 100644 index 0000000000000000000000000000000000000000..b91cad3188113963c7fdf89d12b760d2b6002316 GIT binary patch literal 12395 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 literal 0 HcmV?d00001 diff --git a/chartjs-java-model/src/test/resources/screenshotReferences/BarChartFormat.png b/chartjs-java-model/src/test/resources/screenshotReferences/BarChartFormat.png new file mode 100644 index 0000000000000000000000000000000000000000..416cae3de0e918d294d0925d8395b53ed50a6e20 GIT binary patch literal 12149 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 literal 0 HcmV?d00001