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.javafx.chart;
18  
19  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
20  import javafx.collections.ObservableList;
21  import javafx.scene.Node;
22  import javafx.scene.chart.CategoryAxis;
23  import javafx.scene.chart.NumberAxis;
24  import javafx.scene.chart.StackedBarChart;
25  import javafx.scene.chart.XYChart.Data;
26  import javafx.scene.chart.XYChart.Series;
27  import javafx.scene.control.Tooltip;
28  import javafx.scene.input.MouseEvent;
29  import javafx.util.StringConverter;
30  import io.github.tonywasher.joceanus.tethys.core.chart.TethysUICoreBarChart;
31  import io.github.tonywasher.joceanus.tethys.core.factory.TethysUICoreFactory;
32  import io.github.tonywasher.joceanus.tethys.javafx.base.TethysUIFXNode;
33  
34  import java.util.HashMap;
35  import java.util.Map;
36  
37  /**
38   * javaFX barChart.
39   */
40  public class TethysUIFXBarChart
41          extends TethysUICoreBarChart {
42      /**
43       * The Node.
44       */
45      private final TethysUIFXNode theNode;
46  
47      /**
48       * The chart.
49       */
50      private final StackedBarChart<String, Number> theChart;
51  
52      /**
53       * The series map.
54       */
55      private final Map<String, Series<String, Number>> theSeries;
56  
57      /**
58       * Constructor.
59       *
60       * @param pFactory the Gui Factory
61       */
62      TethysUIFXBarChart(final TethysUICoreFactory<?> pFactory) {
63          /* initialise underlying class */
64          super(pFactory);
65  
66          /* Create chart */
67          final CategoryAxis myXAxis = new CategoryAxis();
68          final NumberAxis myYAxis = new NumberAxis();
69          myYAxis.setTickLabelFormatter(new StringConverter<>() {
70              @Override
71              public String toString(final Number pValue) {
72                  return getFormatter().formatMoney(new OceanusMoney(pValue.toString()));
73              }
74  
75              @Override
76              public Number fromString(final String pValue) {
77                  return null;
78              }
79          });
80          theChart = new StackedBarChart<>(myXAxis, myYAxis);
81  
82          /* Create the map */
83          theSeries = new HashMap<>();
84  
85          /* Create Node */
86          theNode = new TethysUIFXNode(theChart);
87      }
88  
89      @Override
90      public TethysUIFXNode getNode() {
91          return theNode;
92      }
93  
94      @Override
95      public void setVisible(final boolean pVisible) {
96          theNode.setManaged(pVisible);
97          theNode.setVisible(pVisible);
98      }
99  
100     @Override
101     public void setEnabled(final boolean pEnabled) {
102         theChart.setDisable(!pEnabled);
103     }
104 
105     @Override
106     public void setPreferredWidth(final Integer pWidth) {
107         theChart.setPrefWidth(pWidth);
108     }
109 
110     @Override
111     public void setPreferredHeight(final Integer pHeight) {
112         theChart.setPrefHeight(pHeight);
113     }
114 
115     @Override
116     public void updateBarChart(final TethysUIBarChartData pData) {
117         /* Update underlying data */
118         super.updateBarChart(pData);
119 
120         /* Set the chart title and Axis labels */
121         theChart.setTitle(pData.getTitle());
122         theChart.getXAxis().setLabel(pData.getXAxisLabel());
123         theChart.getYAxis().setLabel(pData.getYAxisLabel());
124     }
125 
126     @Override
127     protected void resetData() {
128         /* Clear the data */
129         final ObservableList<Series<String, Number>> myData = theChart.getData();
130         myData.clear();
131         theSeries.clear();
132 
133         /* Clear underlying data  */
134         super.resetData();
135     }
136 
137     @Override
138     protected void createSection(final String pName,
139                                  final TethysUIBarChartDataSection pSection) {
140         /* Add to underlying data  */
141         super.createSection(pName, pSection);
142 
143         /* Access the series */
144         final Series<String, Number> mySeries = theSeries.computeIfAbsent(pName, n -> {
145             final Series<String, Number> s = new Series<>();
146             s.setName(n);
147             final ObservableList<Series<String, Number>> myData = theChart.getData();
148             myData.add(s);
149             return s;
150         });
151 
152         /* Create section */
153         final ObservableList<Data<String, Number>> mySections = mySeries.getData();
154         final Data<String, Number> myData = new Data<>(pSection.getReference(), pSection.getValue().doubleValue());
155         mySections.add(myData);
156         final Node myNode = myData.getNode();
157 
158         /* Build name */
159         final String myName = pName + ":" + myData.getXValue();
160 
161         /* Create the toolTip */
162         final String myTooltip = getToolTip(myName);
163         Tooltip.install(myNode, new Tooltip(myTooltip));
164 
165         /* Install click handler for node */
166         myNode.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> selectSection(myName));
167     }
168 }