HolonInformationPanel.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. package ui.view.information;
  2. import java.awt.BorderLayout;
  3. import java.awt.Color;
  4. import java.awt.Component;
  5. import java.awt.GridBagConstraints;
  6. import java.awt.GridBagLayout;
  7. import java.awt.GridLayout;
  8. import java.awt.Insets;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. import java.util.function.Predicate;
  12. import java.util.stream.Collectors;
  13. import java.util.stream.Stream;
  14. import javax.swing.BorderFactory;
  15. import javax.swing.JLabel;
  16. import javax.swing.JLayeredPane;
  17. import javax.swing.JPanel;
  18. import javax.swing.OverlayLayout;
  19. import javax.swing.border.EmptyBorder;
  20. import org.knowm.xchart.PieChart;
  21. import org.knowm.xchart.PieChartBuilder;
  22. import org.knowm.xchart.PieSeries.PieSeriesRenderStyle;
  23. import org.knowm.xchart.XChartPanel;
  24. import org.knowm.xchart.style.PieStyler;
  25. import org.knowm.xchart.style.PieStyler.LabelType;
  26. import classes.GroupNode;
  27. import classes.HolonElement;
  28. import classes.HolonElement.Priority;
  29. import classes.HolonObject;
  30. import preferences.ColorPreference;
  31. import ui.controller.Control;
  32. import ui.controller.FlexManager;
  33. import ui.controller.FlexManager.FlexWrapper;
  34. import ui.model.Consumer;
  35. import ui.model.DecoratedGroupNode;
  36. import ui.model.DecoratedHolonObject;
  37. import ui.model.DecoratedHolonObject.HolonObjectState;
  38. import ui.model.Passiv;
  39. import ui.model.Supplier;
  40. import utility.FormatFloat;
  41. public class HolonInformationPanel extends JPanel {
  42. private Predicate<DecoratedHolonObject> stateFilter = (object) -> true;//= (object) -> object.getState() == HolonObjectState.PRODUCER;
  43. private Predicate<HolonElement> priorityFilter = (ele) -> ele.getPriority() == Priority.Low;
  44. private final int defaultWidth = 50;
  45. private final int defaultHeight = 200;
  46. private PieChart supplyChart = createSupplyStateChart();
  47. private PieChart priorityChart = createPriorityChart();
  48. private PieChart flexibilityChart = createFlexibilityChart();
  49. private PieChart energyChart = createProductionChart();
  50. private PieChart activeChart = createActiveChart();
  51. private XChartPanel<PieChart> panelHolonObject;
  52. private XChartPanel<PieChart> panelPriority;
  53. private XChartPanel<PieChart> panelFlexibility;
  54. private XChartPanel<PieChart> panelEnergy;
  55. private XChartPanel<PieChart> panelActive;
  56. private JPanel graphPanel = new JPanel(new GridLayout(0, 2));
  57. private JPanel titlePanel = new JPanel(new BorderLayout(0, 0));
  58. private Control control;
  59. private JLabel differenceEnergyLabelAmount = new JLabel("");
  60. public void updateCharts() {
  61. if (control.getModel().getSelectedObjects().isEmpty()) {
  62. return;
  63. }
  64. FilterableGroupNode decoratedGroupNode = multiSelectionToFilterableGroupNode();
  65. // UPDATE SUPPLY STATE
  66. int producerAmount = decoratedGroupNode.getAmountOfSupplier(stateFilter);
  67. int overSuppliedAmount = decoratedGroupNode.getAmountOfConsumerWithState(stateFilter, HolonObjectState.OVER_SUPPLIED);
  68. int suppliedAmount = decoratedGroupNode.getAmountOfConsumerWithState(stateFilter, HolonObjectState.SUPPLIED);
  69. int partiallySuppliedAmount = decoratedGroupNode
  70. .getAmountOfConsumerWithState(stateFilter, HolonObjectState.PARTIALLY_SUPPLIED);
  71. int notSuppliedAmount = decoratedGroupNode.getAmountOfConsumerWithState(stateFilter, HolonObjectState.NOT_SUPPLIED);
  72. int noEnergyAmount = decoratedGroupNode.getAmountOfPassiv(stateFilter);
  73. supplyChart.updatePieSeries("Producer", producerAmount);
  74. supplyChart.updatePieSeries("Over supplied", overSuppliedAmount);
  75. supplyChart.updatePieSeries("Supplied", suppliedAmount);
  76. supplyChart.updatePieSeries("Partial supplied", partiallySuppliedAmount);
  77. supplyChart.updatePieSeries("Not supplied", notSuppliedAmount);
  78. supplyChart.updatePieSeries("No energy", noEnergyAmount);
  79. panelHolonObject.updateToolTips();
  80. // UPDATE PRIORITYS
  81. ui.view.information.FilterableGroupNode.PriorityCounts priorityCounts = decoratedGroupNode.getPriorityCounts(stateFilter);
  82. priorityChart.updatePieSeries("Essential", priorityCounts.essential);
  83. priorityChart.updatePieSeries("High", priorityCounts.high);
  84. priorityChart.updatePieSeries("Medium", priorityCounts.medium);
  85. priorityChart.updatePieSeries("Low", priorityCounts.low);
  86. boolean hasPriority = priorityCounts.essential + priorityCounts.high + priorityCounts.medium
  87. + priorityCounts.low > 0;
  88. priorityChart.updatePieSeries("No Data", hasPriority ? 0 : 1);
  89. panelPriority.updateToolTips();
  90. // UPDATE PRODUCTION
  91. float production = decoratedGroupNode.getProduction(stateFilter, priorityFilter);
  92. float consumption = decoratedGroupNode.getConsumption(stateFilter,priorityFilter);
  93. System.out.println("production" + production);
  94. System.out.println("consumption" + consumption);
  95. float difference = Math.abs(production - consumption);
  96. energyChart.updatePieSeries("Production", production);
  97. energyChart.updatePieSeries("Consumption", consumption);
  98. differenceEnergyLabelAmount.setText(FormatFloat.doubleFixedPlaces(1, difference));
  99. panelEnergy.updateToolTips();
  100. // UPDATE FLEXIBILITIES
  101. int inUse = 0;
  102. int offered = 0;
  103. int onCooldown = 0;
  104. int notOffered = 0;
  105. int unavailable = 0;
  106. FlexManager manager = control.getSimManager().getActualFlexManager();
  107. Stream<FlexWrapper> flexWrapperStream = decoratedGroupNode.getFlexibilitiesStream(stateFilter, priorityFilter)
  108. .map(flex -> manager.getFlexWrapperFromFlexibility(flex));
  109. List<FlexWrapper> wrapperList = flexWrapperStream.collect(Collectors.toList());
  110. for (FlexWrapper wrapper : wrapperList) {
  111. switch (wrapper.getState()) {
  112. case IN_USE:
  113. inUse++;
  114. break;
  115. case NOT_OFFERED:
  116. notOffered++;
  117. break;
  118. case OFFERED:
  119. offered++;
  120. break;
  121. case ON_COOLDOWN:
  122. onCooldown++;
  123. break;
  124. case UNAVAILABLE:
  125. unavailable++;
  126. break;
  127. default:
  128. break;
  129. }
  130. }
  131. flexibilityChart.updatePieSeries("Offered", offered);
  132. flexibilityChart.updatePieSeries("In use", inUse);
  133. flexibilityChart.updatePieSeries("On cooldown", onCooldown);
  134. flexibilityChart.updatePieSeries("Not offered", notOffered);
  135. flexibilityChart.updatePieSeries("Unavailable", unavailable);
  136. boolean hasFlex = offered + inUse + onCooldown + notOffered + unavailable > 0;
  137. flexibilityChart.updatePieSeries("No Data", hasFlex ? 0 : 1);
  138. panelFlexibility.updateToolTips();
  139. // UPDATE ActiveInActive
  140. int activeAmount = decoratedGroupNode.getAmountOfAktiveElementsFromHolonObjects(stateFilter, priorityFilter);
  141. int inactiveAmounts = decoratedGroupNode.getAmountOfElementsFromHolonObjects(stateFilter, priorityFilter) - activeAmount;
  142. activeChart.updatePieSeries("Active", activeAmount);
  143. activeChart.updatePieSeries("Inactive", inactiveAmounts);
  144. panelActive.updateToolTips();
  145. this.revalidate();
  146. this.repaint();
  147. }
  148. private FilterableGroupNode multiSelectionToFilterableGroupNode() {
  149. FilterableGroupNode temp = new FilterableGroupNode(new GroupNode("Temp"), control.getModel().getCurrentIteration());
  150. // GroupNodes
  151. HashMap<GroupNode, DecoratedGroupNode> accessMapGroupNode = control.getSimManager()
  152. .getActualVisualRepresentationalState().getCreatedGroupNodes();
  153. List<FilterableGroupNode> groupNodeList = control.getModel().getSelectedObjects().stream()
  154. .filter(object -> object instanceof GroupNode).map(object -> accessMapGroupNode.get(object))
  155. .map(node -> new FilterableGroupNode(node, control.getModel().getCurrentIteration())).collect(Collectors.toList());
  156. temp.getGroupNodeList().addAll(groupNodeList);
  157. // HolonObjects
  158. HashMap<HolonObject, DecoratedHolonObject> accessMapHolonObject = control.getSimManager()
  159. .getActualVisualRepresentationalState().createdHolonObjects;
  160. List<DecoratedHolonObject> holonObjectList = control.getModel().getSelectedObjects().stream()
  161. .filter(object -> object instanceof HolonObject).map(object -> accessMapHolonObject.get(object))
  162. .collect(Collectors.toList());
  163. for (DecoratedHolonObject object : holonObjectList) {
  164. switch (object.getState()) {
  165. case NO_ENERGY:
  166. temp.getPassivList().add((Passiv) object);
  167. break;
  168. case PRODUCER:
  169. temp.getSupplierList().add((Supplier) object);
  170. break;
  171. default:
  172. temp.getConsumerList().add((Consumer) object);
  173. break;
  174. }
  175. }
  176. return temp;
  177. }
  178. public HolonInformationPanel(Control control) {
  179. control.OnSelectionChanged.addListener(() -> updateCharts());
  180. this.control = control;
  181. this.setLayout(new BorderLayout());
  182. initGraphPanel();
  183. initTitlePanel();
  184. this.setBackground(ColorPreference.Panel.Background);
  185. this.add(titlePanel, BorderLayout.PAGE_START);
  186. this.add(graphPanel, BorderLayout.CENTER);
  187. }
  188. public void initGraphPanel() {
  189. graphPanel.setBackground(ColorPreference.Panel.Background);
  190. panelHolonObject = new XChartPanel<PieChart>(supplyChart);
  191. panelHolonObject.setBackground(ColorPreference.Panel.Background);
  192. graphPanel.add(panelHolonObject);
  193. panelPriority = new XChartPanel<PieChart>(priorityChart);
  194. panelPriority.setBackground(ColorPreference.Panel.Background);
  195. graphPanel.add(panelPriority);
  196. panelFlexibility = new XChartPanel<PieChart>(flexibilityChart);
  197. panelFlexibility.setBackground(ColorPreference.Panel.Background);
  198. graphPanel.add(panelFlexibility);
  199. Component panel = initEnergyChart();
  200. graphPanel.add(panel);
  201. panelActive = new XChartPanel<PieChart>(activeChart);
  202. panelActive.setBackground(ColorPreference.Panel.Background);
  203. panelActive.setLayout(new GridBagLayout());
  204. graphPanel.add(panelActive);
  205. graphPanel.setBorder(BorderFactory.createLineBorder(Color.lightGray));
  206. }
  207. private JLayeredPane initEnergyChart() {
  208. JLayeredPane panel = new JLayeredPane();
  209. JPanel panelMiddle = new JPanel(new GridBagLayout());
  210. panelEnergy = new XChartPanel<PieChart>(energyChart);
  211. panelEnergy.setBackground(ColorPreference.Panel.Background);
  212. GridBagConstraints c = new GridBagConstraints();
  213. c.gridx = 0;
  214. c.gridy = 0;
  215. c.insets = new Insets(15, 0, 0, 0); // top padding
  216. JLabel difference = new JLabel("Difference:");
  217. difference.setHorizontalAlignment(JLabel.CENTER);
  218. difference.setAlignmentX(Component.CENTER_ALIGNMENT);
  219. difference.setForeground(ColorPreference.Panel.Title);
  220. difference.setFont(new java.awt.Font("Arial", java.awt.Font.BOLD, 10));
  221. panelMiddle.add(difference, c);
  222. differenceEnergyLabelAmount.setHorizontalAlignment(JLabel.CENTER);
  223. differenceEnergyLabelAmount.setForeground(Color.red);
  224. differenceEnergyLabelAmount.setAlignmentX(Component.CENTER_ALIGNMENT);
  225. differenceEnergyLabelAmount.setFont(new java.awt.Font("Arial", java.awt.Font.BOLD, 12));
  226. c.insets = new Insets(0, 0, 0, 0);
  227. c.gridy = 1;
  228. panelMiddle.add(differenceEnergyLabelAmount, c);
  229. panel.setLayout(new OverlayLayout(panel));
  230. panelEnergy.setOpaque(false);
  231. panelMiddle.setOpaque(false);
  232. panel.add(panelMiddle, Integer.valueOf(0));
  233. panel.add(panelEnergy, Integer.valueOf(1));
  234. return panel;
  235. }
  236. public void initTitlePanel() {
  237. titlePanel.setBackground(ColorPreference.Panel.Background);
  238. titlePanel.setBorder(new EmptyBorder(5, 5, 2, 0));
  239. }
  240. public void setDefaultPieChartSettings(PieChart chart) {
  241. PieStyler styler = chart.getStyler();
  242. styler.setChartTitleVisible(true);
  243. styler.setDefaultSeriesRenderStyle(PieSeriesRenderStyle.Donut);
  244. styler.setLabelsFont(new java.awt.Font("Arial", java.awt.Font.PLAIN, 14));
  245. styler.setLabelType(LabelType.Percentage);
  246. styler.setLabelsFontColor(Color.black);
  247. styler.setLabelsFontColorAutomaticEnabled(false);
  248. styler.setLabelsDistance(0.8);
  249. styler.setChartFontColor(ColorPreference.Panel.Title);
  250. styler.setToolTipsEnabled(true);
  251. styler.setPlotContentSize(0.9);
  252. styler.setPlotBackgroundColor(ColorPreference.Panel.Transparent);
  253. styler.setPlotBorderColor(ColorPreference.Panel.Transparent);
  254. styler.setLegendVisible(false);
  255. styler.setChartBackgroundColor(ColorPreference.Panel.Transparent);
  256. }
  257. public PieChart createSupplyStateChart() {
  258. PieChart chart = new PieChartBuilder().width(defaultWidth).height(defaultHeight).title("Holon Objects").build();
  259. setDefaultPieChartSettings(chart);
  260. Color[] sliceColors = new Color[] { ColorPreference.HolonObject.Producer,
  261. ColorPreference.HolonObject.OverSupplied, ColorPreference.HolonObject.Supplied,
  262. ColorPreference.HolonObject.PartiallySupplied, ColorPreference.HolonObject.NotSupplied,
  263. ColorPreference.HolonObject.NoEnergy };
  264. chart.getStyler().setSeriesColors(sliceColors);
  265. // Series
  266. chart.addSeries("Producer", 0);
  267. chart.addSeries("Over supplied", 0);
  268. chart.addSeries("Supplied", 0);
  269. chart.addSeries("Partial supplied", 0);
  270. chart.addSeries("Not supplied", 0);
  271. chart.addSeries("No energy", 0);
  272. return chart;
  273. }
  274. public PieChart createPriorityChart() {
  275. PieChart chart = new PieChartBuilder().width(defaultWidth).height(defaultHeight).title("Priotities").build();
  276. setDefaultPieChartSettings(chart);
  277. // Customize Chart
  278. Color[] sliceColors = new Color[] { ColorPreference.Element.Priority.Essential,
  279. ColorPreference.Element.Priority.High, ColorPreference.Element.Priority.Medium,
  280. ColorPreference.Element.Priority.Low, ColorPreference.Element.Priority.NoData };
  281. chart.getStyler().setSeriesColors(sliceColors);
  282. // Series
  283. chart.addSeries("Essential", 0);
  284. chart.addSeries("High", 0);
  285. chart.addSeries("Medium", 0);
  286. chart.addSeries("Low", 0);
  287. chart.addSeries("No Data", 0);
  288. return chart;
  289. }
  290. public PieChart createFlexibilityChart() {
  291. PieChart chart = new PieChartBuilder().width(defaultWidth).height(defaultHeight).title("Flexibilities").build();
  292. setDefaultPieChartSettings(chart);
  293. // Customize Chart
  294. Color[] sliceColors = new Color[] { ColorPreference.Flexibility.Offered, ColorPreference.Flexibility.InUse,
  295. ColorPreference.Flexibility.OnCooldown, ColorPreference.Flexibility.NotOffered,
  296. ColorPreference.Flexibility.Unavailable, ColorPreference.Element.Priority.NoData };
  297. chart.getStyler().setSeriesColors(sliceColors);
  298. // Series
  299. chart.addSeries("Offered", 0);
  300. chart.addSeries("In use", 0);
  301. chart.addSeries("On cooldown", 0);
  302. chart.addSeries("Not offered", 0);
  303. chart.addSeries("Unavailable", 0);
  304. chart.addSeries("No Data", 0);
  305. return chart;
  306. }
  307. public PieChart createProductionChart() {
  308. PieChart chart = new PieChartBuilder().width(defaultWidth).height(defaultHeight)
  309. .title("Production vs. Consumption").build();
  310. setDefaultPieChartSettings(chart);
  311. // Customize Chart
  312. // Customize Chart
  313. Color[] barColors = new Color[] { ColorPreference.Energy.Production, ColorPreference.Energy.Consumption };
  314. chart.getStyler().setSeriesColors(barColors);
  315. // Series
  316. chart.addSeries("Production", 0);
  317. chart.addSeries("Consumption", 0);
  318. return chart;
  319. }
  320. public PieChart createActiveChart() {
  321. PieChart chart = new PieChartBuilder().width(defaultWidth).height(defaultHeight).title("Active").build();
  322. setDefaultPieChartSettings(chart);
  323. // Customize Chart
  324. // Customize Chart
  325. Color[] barColors = new Color[] { ColorPreference.Element.Active, ColorPreference.Element.Inactive };
  326. chart.getStyler().setSeriesColors(barColors);
  327. // Series
  328. chart.addSeries("Active", 0);
  329. chart.addSeries("Inactive", 0);
  330. return chart;
  331. }
  332. }