1
2
3
4
5
6
7
8
9
10
11 package psiprobe.controllers;
12
13 import jakarta.inject.Inject;
14 import jakarta.servlet.http.HttpServletRequest;
15 import jakarta.servlet.http.HttpServletResponse;
16
17 import java.awt.BasicStroke;
18 import java.awt.Color;
19
20 import org.jfree.chart.ChartFactory;
21 import org.jfree.chart.ChartUtils;
22 import org.jfree.chart.JFreeChart;
23 import org.jfree.chart.axis.DateAxis;
24 import org.jfree.chart.plot.PlotOrientation;
25 import org.jfree.chart.renderer.xy.XYAreaRenderer;
26 import org.jfree.chart.ui.RectangleInsets;
27 import org.jfree.data.xy.DefaultTableXYDataset;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.stereotype.Controller;
31 import org.springframework.web.bind.ServletRequestUtils;
32 import org.springframework.web.bind.annotation.RequestMapping;
33 import org.springframework.web.servlet.ModelAndView;
34 import org.springframework.web.servlet.mvc.AbstractController;
35
36 import psiprobe.Utils;
37 import psiprobe.beans.stats.providers.SeriesProvider;
38 import psiprobe.jfreechart.XYLine3DRenderer;
39 import psiprobe.model.stats.StatsCollection;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 @Controller
59 public class RenderChartController extends AbstractController {
60
61
62 private static final Logger logger = LoggerFactory.getLogger(RenderChartController.class);
63
64
65 @Inject
66 private StatsCollection statsCollection;
67
68 @RequestMapping(path = "/chart.png")
69 @Override
70 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
71 throws Exception {
72 return super.handleRequest(request, response);
73 }
74
75 @Override
76 protected ModelAndView handleRequestInternal(HttpServletRequest request,
77 HttpServletResponse response) throws Exception {
78
79
80 final int seriesMaxCount = 9;
81
82
83 int[] seriesColor = new int[seriesMaxCount];
84 seriesColor[0] = Utils.toIntHex(request.getParameter("s1c"), 0x9bd2fb);
85 seriesColor[1] = Utils.toIntHex(request.getParameter("s2c"), 0xFF0606);
86 for (int i = 2; i < seriesMaxCount; i++) {
87 seriesColor[i] = Utils.toIntHex(request.getParameter("s" + (i + 1) + "c"), -1);
88 }
89
90
91 int[] seriesOutlineColor = new int[seriesMaxCount];
92 seriesOutlineColor[0] = Utils.toIntHex(request.getParameter("s1o"), 0x0665aa);
93 seriesOutlineColor[1] = Utils.toIntHex(request.getParameter("s2o"), 0x9d0000);
94 for (int i = 2; i < seriesMaxCount; i++) {
95 seriesOutlineColor[i] = Utils.toIntHex(request.getParameter("s" + (i + 1) + "o"), -1);
96 }
97
98
99 int backgroundColor = Utils.toIntHex(request.getParameter("bc"), 0xFFFFFF);
100
101
102 int gridColor = Utils.toIntHex(request.getParameter("gc"), 0);
103
104
105 String labelX = ServletRequestUtils.getStringParameter(request, "xl", "");
106
107
108 String labelY = ServletRequestUtils.getStringParameter(request, "yl", "");
109
110
111 int width = ServletRequestUtils.getIntParameter(request, "xz", 800);
112
113
114 int height = ServletRequestUtils.getIntParameter(request, "yz", 400);
115
116
117 boolean showLegend = ServletRequestUtils.getBooleanParameter(request, "l", true);
118
119
120 String provider = ServletRequestUtils.getStringParameter(request, "p");
121
122
123 String chartType = ServletRequestUtils.getStringParameter(request, "ct", "area");
124
125 DefaultTableXYDataset ds = new DefaultTableXYDataset();
126
127 if (provider != null) {
128 Object series = getApplicationContext().getBean(provider);
129 if (series instanceof SeriesProvider seriesProvider) {
130 seriesProvider.populate(ds, statsCollection, request);
131 } else {
132 logger.error("SeriesProvider '{}' does not implement '{}'", provider, SeriesProvider.class);
133 }
134 }
135
136
137 JFreeChart chart = null;
138 if ("area".equals(chartType)) {
139 chart = ChartFactory.createXYAreaChart("", labelX, labelY, ds, PlotOrientation.VERTICAL,
140 showLegend, false, false);
141
142 ((XYAreaRenderer) chart.getXYPlot().getRenderer()).setOutline(true);
143
144 } else if ("stacked".equals(chartType)) {
145 chart = ChartFactory.createStackedXYAreaChart("", labelX, labelY, ds,
146 PlotOrientation.VERTICAL, showLegend, false, false);
147
148 } else if ("line".equals(chartType)) {
149 chart = ChartFactory.createXYLineChart("", labelX, labelY, ds, PlotOrientation.VERTICAL,
150 showLegend, false, false);
151
152 final XYLine3DRenderer renderer = new XYLine3DRenderer();
153 renderer.setDrawOutlines(true);
154 for (int i = 0; i < seriesMaxCount; i++) {
155 renderer.setSeriesLinesVisible(i, true);
156 renderer.setSeriesShapesVisible(i, true);
157 renderer.setSeriesStroke(i, new BasicStroke(2));
158 }
159 renderer.setXOffset(1);
160 renderer.setYOffset(1);
161 chart.getXYPlot().setRenderer(renderer);
162 }
163
164 if (chart != null) {
165 chart.setAntiAlias(true);
166 chart.setBackgroundPaint(new Color(backgroundColor));
167 for (int i = 0; i < seriesMaxCount; i++) {
168 if (seriesColor[i] >= 0) {
169 chart.getXYPlot().getRenderer().setSeriesPaint(i, new Color(seriesColor[i]));
170 }
171 if (seriesOutlineColor[i] >= 0) {
172 chart.getXYPlot().getRenderer().setSeriesOutlinePaint(i,
173 new Color(seriesOutlineColor[i]));
174 }
175 }
176 chart.getXYPlot().setDomainGridlinePaint(new Color(gridColor));
177 chart.getXYPlot().setRangeGridlinePaint(new Color(gridColor));
178 chart.getXYPlot().setDomainAxis(0, new DateAxis());
179 chart.getXYPlot().setDomainAxis(1, new DateAxis());
180 chart.getXYPlot().setInsets(new RectangleInsets(-15, 0, 0, 10));
181
182 response.setHeader("Content-type", "image/png");
183 response.getOutputStream()
184 .write(ChartUtils.encodeAsPNG(chart.createBufferedImage(width, height)));
185 }
186
187 return null;
188 }
189 }