View Javadoc
1   /*
2    * Tethys: GUI Utilities
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.tethys.core.chart;
18  
19  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimalFormatter;
20  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimalParser;
21  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
22  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
23  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
24  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
25  import io.github.tonywasher.joceanus.tethys.api.chart.TethysUIBarChart;
26  import io.github.tonywasher.joceanus.tethys.core.base.TethysUICoreComponent;
27  import io.github.tonywasher.joceanus.tethys.core.chart.TethysUICoreAreaChart.TethysUICoreAreaChartData;
28  import io.github.tonywasher.joceanus.tethys.core.factory.TethysUICoreFactory;
29  
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.LinkedHashMap;
33  import java.util.Map;
34  
35  /**
36   * Bar Chart.
37   * <p>
38   * The EventProvider fires the following events.
39   * <ul>
40   *    <li>TethysUIEvent.PRESSED is fired when a bar is selected
41   * </ul>
42   */
43  public abstract class TethysUICoreBarChart
44          extends TethysUICoreComponent
45          implements TethysUIBarChart {
46      /**
47       * The formatter.
48       */
49      private final OceanusDecimalFormatter theFormatter;
50  
51      /**
52       * The parser.
53       */
54      private final OceanusDecimalParser theParser;
55  
56      /**
57       * The id.
58       */
59      private final Integer theId;
60  
61      /**
62       * The Event Manager.
63       */
64      private final OceanusEventManager<TethysUIEvent> theEventManager;
65  
66      /**
67       * The sectionMap.
68       */
69      private final Map<String, TethysUIBarChartDataSection> theSectionMap;
70  
71      /**
72       * Constructor.
73       *
74       * @param pFactory the Gui Factory
75       */
76      protected TethysUICoreBarChart(final TethysUICoreFactory<?> pFactory) {
77          /* Build standard fields */
78          theId = pFactory.getNextId();
79          theEventManager = new OceanusEventManager<>();
80          theFormatter = pFactory.getDataFormatter().getDecimalFormatter();
81          theParser = pFactory.getDataFormatter().getDecimalParser();
82  
83          /* Create the section map */
84          theSectionMap = new HashMap<>();
85      }
86  
87      @Override
88      public Integer getId() {
89          return theId;
90      }
91  
92      @Override
93      public OceanusEventRegistrar<TethysUIEvent> getEventRegistrar() {
94          return theEventManager.getEventRegistrar();
95      }
96  
97      /**
98       * Obtain the formatter.
99       *
100      * @return the formatter
101      */
102     protected OceanusDecimalFormatter getFormatter() {
103         return theFormatter;
104     }
105 
106     /**
107      * Obtain the parser.
108      *
109      * @return the parser
110      */
111     protected OceanusDecimalParser getParser() {
112         return theParser;
113     }
114 
115     @Override
116     public void updateBarChart(final TethysUIBarChartData pData) {
117         /* reset the existing data  */
118         resetData();
119 
120         /* Iterate through the sections */
121         final Iterator<TethysUIBarChartSeries> myIterator = pData.seriesIterator();
122         while (myIterator.hasNext()) {
123             final TethysUIBarChartSeries myBase = myIterator.next();
124             final String myName = myBase.getName();
125 
126             /* Iterate through the sections */
127             final Iterator<TethysUIBarChartDataSection> mySectIterator = myBase.sectionIterator();
128             while (mySectIterator.hasNext()) {
129                 final TethysUIBarChartDataSection mySection = mySectIterator.next();
130 
131                 /* Add the section */
132                 createSection(myName, mySection);
133             }
134         }
135     }
136 
137     /**
138      * Reset chart data.
139      */
140     protected void resetData() {
141         /* Clear existing data  */
142         theSectionMap.clear();
143     }
144 
145     /**
146      * Add chart section.
147      *
148      * @param pName    the name of the bar
149      * @param pSection the section to add
150      */
151     protected void createSection(final String pName,
152                                  final TethysUIBarChartDataSection pSection) {
153         final String myKey = pName + ":" + pSection.getReference();
154         theSectionMap.put(myKey, pSection);
155     }
156 
157     /**
158      * Obtain tooltip for sectionName.
159      *
160      * @param pName the section name
161      * @return the tooltip
162      */
163     protected String getToolTip(final String pName) {
164         final TethysUIBarChartDataSection mySection = theSectionMap.get(pName);
165         final OceanusMoney myValue = mySection.getValue();
166         return pName + " = " + theFormatter.formatMoney(myValue);
167     }
168 
169     /**
170      * handle selection.
171      *
172      * @param pName the section name
173      */
174     protected void selectSection(final String pName) {
175         final TethysUIBarChartDataSection mySection = theSectionMap.get(pName);
176         theEventManager.fireEvent(TethysUIEvent.PRESSED, mySection);
177     }
178 
179     /**
180      * BarChart Data.
181      */
182     public static final class TethysUICoreBarChartData
183             implements TethysUIBarChartData {
184         /**
185          * The XAxis default label.
186          */
187         static final String XAXIS_LABEL = TethysUICoreAreaChartData.XAXIS_LABEL;
188 
189         /**
190          * The XAxis default label.
191          */
192         static final String YAXIS_LABEL = TethysUICoreAreaChartData.YAXIS_LABEL;
193 
194         /**
195          * The Chart Title.
196          */
197         private final String theTitle;
198 
199         /**
200          * The Chart XAxisLabel.
201          */
202         private String theXAxisLabel;
203 
204         /**
205          * The Chart YAxisLabel.
206          */
207         private String theYAxisLabel;
208 
209         /**
210          * The SeriesMap.
211          */
212         private final Map<String, TethysUIBarChartSeries> theSeriesMap;
213 
214         /**
215          * Constructor.
216          *
217          * @param pTitle the title
218          */
219         TethysUICoreBarChartData(final String pTitle) {
220             this(pTitle, XAXIS_LABEL, YAXIS_LABEL);
221         }
222 
223         /**
224          * Constructor.
225          *
226          * @param pTitle      the title
227          * @param pXAxisLabel the XAxis label
228          * @param pYAxisLabel the YAxis label
229          */
230         private TethysUICoreBarChartData(final String pTitle,
231                                          final String pXAxisLabel,
232                                          final String pYAxisLabel) {
233             /* Store parameters */
234             theTitle = pTitle;
235             theXAxisLabel = pXAxisLabel;
236             theYAxisLabel = pYAxisLabel;
237 
238             /* Create map */
239             theSeriesMap = new LinkedHashMap<>();
240         }
241 
242         @Override
243         public TethysUIBarChartData setXAxisLabel(final String pLabel) {
244             theXAxisLabel = pLabel;
245             return this;
246         }
247 
248         @Override
249         public TethysUIBarChartData setYAxisLabel(final String pLabel) {
250             theYAxisLabel = pLabel;
251             return this;
252         }
253 
254         @Override
255         public String getTitle() {
256             return theTitle;
257         }
258 
259         @Override
260         public String getXAxisLabel() {
261             return theXAxisLabel;
262         }
263 
264         @Override
265         public String getYAxisLabel() {
266             return theYAxisLabel;
267         }
268 
269         @Override
270         public Iterator<TethysUIBarChartSeries> seriesIterator() {
271             return theSeriesMap.values().iterator();
272         }
273 
274         @Override
275         public TethysUIBarChartSeries createSeries(final String pName) {
276             final TethysUIBarChartSeries mySeries = new TethysUICoreBarChartSeries(pName);
277             theSeriesMap.put(pName, mySeries);
278             return mySeries;
279         }
280     }
281 
282     /**
283      * The Series definition.
284      */
285     public static final class TethysUICoreBarChartSeries
286             implements TethysUIBarChartSeries {
287         /**
288          * The name of the series.
289          */
290         private final String theName;
291 
292         /**
293          * The sectionMap of the series.
294          */
295         private final Map<String, TethysUIBarChartDataSection> theSectionMap;
296 
297         /**
298          * Constructor.
299          *
300          * @param pName the name
301          */
302         TethysUICoreBarChartSeries(final String pName) {
303             theName = pName;
304             theSectionMap = new LinkedHashMap<>();
305         }
306 
307         @Override
308         public void addSection(final String pRef,
309                                final OceanusMoney pValue) {
310             addSection(pRef, pValue, theName + ":" + pRef);
311         }
312 
313         @Override
314         public void addSection(final String pRef,
315                                final OceanusMoney pValue,
316                                final Object pSource) {
317             theSectionMap.put(pRef, new TethysUICoreBarChartDataSection(this, pRef, pValue, pSource));
318         }
319 
320         @Override
321         public String getName() {
322             return theName;
323         }
324 
325         @Override
326         public Iterator<TethysUIBarChartDataSection> sectionIterator() {
327             return theSectionMap.values().iterator();
328         }
329     }
330 
331     /**
332      * The Data Section definition.
333      */
334     public static final class TethysUICoreBarChartDataSection
335             implements TethysUIBarChartDataSection {
336         /**
337          * The series of the section.
338          */
339         private final TethysUIBarChartSeries theSeries;
340 
341         /**
342          * The reference of the section.
343          */
344         private final String theRef;
345 
346         /**
347          * The value of the section.
348          */
349         private final OceanusMoney theValue;
350 
351         /**
352          * The source of the section.
353          */
354         private final Object theSource;
355 
356         /**
357          * Constructor.
358          *
359          * @param pSeries the series
360          * @param pRef    the reference
361          * @param pValue  the value
362          * @param pSource the source
363          */
364         TethysUICoreBarChartDataSection(final TethysUIBarChartSeries pSeries,
365                                         final String pRef,
366                                         final OceanusMoney pValue,
367                                         final Object pSource) {
368             theSeries = pSeries;
369             theRef = pRef;
370             theValue = pValue;
371             theSource = pSource;
372         }
373 
374         @Override
375         public TethysUIBarChartSeries getSeries() {
376             return theSeries;
377         }
378 
379         @Override
380         public String getReference() {
381             return theRef;
382         }
383 
384         @Override
385         public OceanusMoney getValue() {
386             return theValue;
387         }
388 
389         @Override
390         public Object getSource() {
391             return theSource;
392         }
393     }
394 }