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