001/* =========================================================== 002 * Orson Charts : a 3D chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C)opyright 2013-2022, by David Gilbert. All rights reserved. 006 * 007 * https://github.com/jfree/orson-charts 008 * 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as published by 011 * the Free Software Foundation, either version 3 of the License, or 012 * (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 021 * 022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 023 * Other names may be trademarks of their respective owners.] 024 * 025 * If you do not wish to be bound by the terms of the GPL, an alternative 026 * commercial license can be purchased. For details, please see visit the 027 * Orson Charts home page: 028 * 029 * http://www.object-refinery.com/orsoncharts/index.html 030 * 031 */ 032 033package org.jfree.chart3d.label; 034 035import java.io.Serializable; 036import java.util.Formatter; 037 038import org.jfree.chart3d.data.DataUtils; 039import org.jfree.chart3d.data.category.CategoryDataset3D; 040import org.jfree.chart3d.internal.Args; 041 042/** 043 * A default implementation of the {@link CategoryLabelGenerator} interface. 044 * The implementation uses a {@link java.util.Formatter} instance to generate 045 * the labels. Three values are passed to the formatter: (1) the key for 046 * the series, row or column, (2) the count for the number of 047 * non-{@code null} items in the series, row or column (as an 048 * {@code Integer}) and (3) the total of the non-{@code null} values 049 * (as a {@code Double}). 050 * <br><br> 051 * NOTE: This class is serializable, but the serialization format is subject 052 * to change in future releases and should not be relied upon for persisting 053 * instances of this class. 054 * 055 * @since 1.2 056 */ 057@SuppressWarnings("serial") 058public class StandardCategoryLabelGenerator<S extends Comparable<S>, R extends Comparable<R>, C extends Comparable<C>> 059 implements CategoryLabelGenerator<S, R, C>, Serializable { 060 061 /** 062 * A template string that will show the series, row or column key only. 063 * 064 * @since 1.2 065 */ 066 public static final String KEY_ONLY_TEMPLATE = "%s"; 067 068 /** 069 * A template string that will show the key followed by the data total 070 * (for the series, row or column) in brackets, with zero decimal places. 071 */ 072 public static final String TOTAL_TEMPLATE = "%s (%3$,.0f)"; 073 074 /** 075 * A template string that will show the key followed by the data total 076 * (for the series, row or column) in brackets, with two decimal places. 077 */ 078 public static final String TOTAL_TEMPLATE_2DP = "%s (%3$,.2f)"; 079 080 /** 081 * The default template string (used in the default constructor, it is 082 * equivalent to {@link #KEY_ONLY_TEMPLATE}). 083 * 084 * @since 1.2 085 */ 086 public static final String DEFAULT_TEMPLATE = KEY_ONLY_TEMPLATE; 087 088 /** The template. */ 089 private String template; 090 091 /** 092 * The default constructor. 093 */ 094 public StandardCategoryLabelGenerator() { 095 this(DEFAULT_TEMPLATE); 096 } 097 098 /** 099 * Creates a new instance with the specified template string (which will 100 * be passed to a {@code java.util.Formatter} instance when generating 101 * labels). See the class description for an explanation of the values 102 * that are available for use in the template string. 103 * 104 * @param template the template ({@code null} not permitted). 105 */ 106 public StandardCategoryLabelGenerator(String template) { 107 Args.nullNotPermitted(template, "template"); 108 this.template = template; 109 } 110 111 /** 112 * Generates the label for one series in a category chart. 113 * 114 * @param dataset the dataset ({@code null} not permitted). 115 * @param seriesKey the key ({@code null} not permitted). 116 * 117 * @return The label (never {@code null} for this implementation). 118 */ 119 @Override 120 public String generateSeriesLabel(CategoryDataset3D<S, R, C> dataset, 121 S seriesKey) { 122 Args.nullNotPermitted(dataset, "dataset"); 123 Args.nullNotPermitted(seriesKey, "seriesKey"); 124 Formatter formatter = new Formatter(new StringBuilder()); 125 int count = DataUtils.count(dataset, seriesKey); 126 double total = DataUtils.total(dataset, seriesKey); 127 formatter.format(this.template, seriesKey, count, total); 128 String result = formatter.toString(); 129 formatter.close(); 130 return result; 131 } 132 133 /** 134 * Generates a label for one row in a {@link CategoryDataset3D}. 135 * 136 * @param dataset the dataset ({@code null} not permitted). 137 * @param rowKey the key ({@code null} not permitted). 138 * 139 * @return The row label (possibly {@code null}). 140 */ 141 @Override 142 public String generateRowLabel(CategoryDataset3D<S, R, C> dataset, 143 R rowKey) { 144 Args.nullNotPermitted(dataset, "dataset"); 145 Args.nullNotPermitted(rowKey, "rowKey"); 146 Formatter formatter = new Formatter(new StringBuilder()); 147 int count = DataUtils.countForRow(dataset, rowKey); 148 double total = DataUtils.totalForRow(dataset, rowKey); 149 formatter.format(this.template, rowKey, count, total); 150 String result = formatter.toString(); 151 formatter.close(); 152 return result; 153 } 154 155 /** 156 * Generates a label for one column in a {@link CategoryDataset3D}. 157 * 158 * @param dataset the dataset ({@code null} not permitted). 159 * @param columnKey the key ({@code null} not permitted). 160 * 161 * @return The column label (possibly {@code null}). 162 */ 163 @Override 164 public String generateColumnLabel(CategoryDataset3D<S, R, C> dataset, 165 C columnKey) { 166 Args.nullNotPermitted(dataset, "dataset"); 167 Args.nullNotPermitted(columnKey, "columnKey"); 168 Formatter formatter = new Formatter(new StringBuilder()); 169 int count = DataUtils.countForColumn(dataset, columnKey); 170 double total = DataUtils.totalForColumn(dataset, columnKey); 171 formatter.format(this.template, columnKey, count, total); 172 String result = formatter.toString(); 173 formatter.close(); 174 return result; 175 } 176 177 /** 178 * Tests this label generator for equality with an arbitrary object. 179 * 180 * @param obj the object ({@code null} permitted). 181 * 182 * @return A boolean. 183 */ 184 @Override 185 public boolean equals(Object obj) { 186 if (obj == this) { 187 return true; 188 } 189 if (!(obj instanceof StandardCategoryLabelGenerator)) { 190 return false; 191 } 192 StandardCategoryLabelGenerator that 193 = (StandardCategoryLabelGenerator) obj; 194 if (!this.template.equals(that.template)) { 195 return false; 196 } 197 return true; 198 } 199 200 @Override 201 public int hashCode() { 202 return this.template.hashCode(); 203 } 204 205}