1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.perf.impl.chart;
33
34 import java.io.Serializable;
35 import java.time.ZoneId;
36 import java.time.format.DateTimeFormatter;
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.List;
40 import javax.annotation.Nullable;
41 import javax.annotation.concurrent.Immutable;
42 import org.jfree.chart.axis.TickUnits;
43 import org.jfree.data.DomainOrder;
44 import org.jfree.data.general.DatasetChangeListener;
45 import org.jfree.data.general.DatasetGroup;
46 import org.jfree.data.xy.XYZDataset;
47 import org.spf4j.base.Arrays;
48 import org.spf4j.base.ComparablePair;
49 import org.spf4j.perf.impl.Quanta;
50
51 @Immutable
52 final class QuantizedXYZDatasetImpl implements XYZDataset, Serializable {
53
54 private static final long serialVersionUID = 1L;
55
56 private final double[] x;
57 private final double[] y;
58 private final double[] z;
59 private final double minValue;
60 private final double maxValue;
61 private final ArrayList<ComparablePair<Quanta, Integer>> quantas;
62 private final double[][] data;
63 private final long startTimeMillis;
64 private final long stepMillis;
65
66 QuantizedXYZDatasetImpl(final String[] dataSources, final double[][] pdata,
67 final long startTimeMillis, final long step) {
68 this.data = pdata;
69 this.startTimeMillis = startTimeMillis;
70 this.stepMillis = step;
71 quantas = new ArrayList<>(dataSources.length);
72 for (int i = 0; i < dataSources.length; i++) {
73 String ds = dataSources[i];
74 if (ds.startsWith("Q")) {
75 Quanta quanta = new Quanta(ds);
76 quantas.add(ComparablePair.of(quanta, i));
77 }
78 }
79 Collections.sort(quantas);
80 final int nrQuantas = quantas.size();
81 int seriesSize = nrQuantas * data.length;
82 x = new double[seriesSize];
83 y = new double[seriesSize];
84 z = new double[seriesSize];
85 double lMinValue = Double.POSITIVE_INFINITY;
86 double lMaxValue = Double.NEGATIVE_INFINITY;
87
88 int k = 0;
89
90 for (int j = 0; j < nrQuantas; j++) {
91 ComparablePair<Quanta, Integer> pair = quantas.get(j);
92 double[] values = Arrays.getColumn(data, pair.getSecond());
93 for (int i = 0; i < values.length; i++) {
94 x[k] = i;
95 y[k] = j;
96 double zval = values[i];
97 z[k] = zval;
98 if (zval > lMaxValue) {
99 lMaxValue = zval;
100 }
101 if (zval < lMinValue) {
102 lMinValue = zval;
103 }
104 k++;
105 }
106 }
107 this.minValue = lMinValue;
108 this.maxValue = lMaxValue;
109
110 }
111
112 @Override
113 public Number getZ(final int series, final int item) {
114 return z[item];
115 }
116
117 @Override
118 public double getZValue(final int series, final int item) {
119 return z[item];
120 }
121
122 @Override
123 public DomainOrder getDomainOrder() {
124 return DomainOrder.ASCENDING;
125 }
126
127 @Override
128 public int getItemCount(final int series) {
129 return x.length;
130 }
131
132 @Override
133 public Number getX(final int series, final int item) {
134 return x[item];
135 }
136
137 @Override
138 public double getXValue(final int series, final int item) {
139 return x[item];
140 }
141
142 @Override
143 public Number getY(final int series, final int item) {
144 return y[item];
145 }
146
147 @Override
148 public double getYValue(final int series, final int item) {
149 return y[item];
150 }
151
152 @Override
153 public int getSeriesCount() {
154 return 1;
155 }
156
157 @Override
158 public Comparable getSeriesKey(final int series) {
159 return "RrdXYZDataset";
160 }
161
162 @Override
163 public int indexOf(final Comparable seriesKey) {
164 return 0;
165 }
166
167 @Override
168 public void addChangeListener(final DatasetChangeListener listener) {
169
170 }
171
172 @Override
173 public void removeChangeListener(final DatasetChangeListener listener) {
174
175 }
176
177 @Override
178 @Nullable
179 public DatasetGroup getGroup() {
180 return null;
181 }
182
183 @Override
184 public void setGroup(final DatasetGroup group) {
185
186 }
187
188 public double getMaxValue() {
189 return maxValue;
190 }
191
192 public double getMinValue() {
193 return minValue;
194 }
195
196 public List<ComparablePair<Quanta, Integer>> getQuantas() {
197 return Collections.unmodifiableList(quantas);
198 }
199
200 public TickUnits createXTickUnits() {
201 TickUnits tux = new TickUnits();
202 if (data.length == 0) {
203 return tux;
204 }
205 ZoneId systemDefault = ZoneId.systemDefault();
206 final DateTimeFormatter formatter = DateTimeFormatter
207 .ofPattern("yyyyMMdd'T'HH:mm:ss").withZone(systemDefault);
208 final DateTimeFormatter shortFormat = DateTimeFormatter
209 .ofPattern("yyyyMMdd'T'HH").withZone(systemDefault);
210 final DateTimeFormatter mediumFormat = DateTimeFormatter
211 .ofPattern("yyyyMMdd'T'HH:mm").withZone(systemDefault);
212 final long[] timestamps = new long[data[0].length];
213 long time = startTimeMillis;
214 for (int i = 0; i < timestamps.length; i++) {
215 timestamps[i] = time;
216 time += stepMillis;
217 }
218 tux.add(new TimestampTickUnitImpl(1, timestamps, stepMillis, formatter));
219 long nr = 5000L / stepMillis;
220 if (nr > 1) {
221 tux.add(new TimestampTickUnitImpl(nr, timestamps, stepMillis, formatter));
222 }
223
224 nr = 15000L / stepMillis;
225 if (nr > 1) {
226 tux.add(new TimestampTickUnitImpl(nr, timestamps, stepMillis, formatter));
227 }
228
229 nr = 60000L / stepMillis;
230 if (nr > 1) {
231 tux.add(new TimestampTickUnitImpl(nr, timestamps, stepMillis, mediumFormat));
232 }
233
234 nr = 900000L / stepMillis;
235 if (nr > 1) {
236 tux.add(new TimestampTickUnitImpl(nr, timestamps, stepMillis, mediumFormat));
237 }
238
239 nr = 3600000L / stepMillis;
240 if (nr > 1) {
241 tux.add(new TimestampTickUnitImpl(nr, timestamps, stepMillis, shortFormat));
242 }
243
244 nr = 21600000L / stepMillis;
245 if (nr > 1) {
246 tux.add(new TimestampTickUnitImpl(nr, timestamps, stepMillis, shortFormat));
247 }
248
249 return tux;
250 }
251
252 public TickUnits createYTickUnits() {
253 TickUnits tu = new TickUnits();
254 final List<ComparablePair<Quanta, Integer>> lquantas = this.getQuantas();
255 tu.add(new QuantizedNumberTickUnit(1, lquantas));
256 return tu;
257 }
258
259 @Override
260 public String toString() {
261 return "QuantizedXYZDatasetImpl{" + "x=" + java.util.Arrays.toString(x)
262 + ", y=" + java.util.Arrays.toString(y) + ", z=" + java.util.Arrays.toString(z)
263 + ", minValue=" + minValue + ", maxValue=" + maxValue + ", quantas=" + quantas
264 + ", data=" + java.util.Arrays.toString(data)
265 + ", startTimeMillis=" + startTimeMillis + ", stepMillis=" + stepMillis + '}';
266 }
267
268 }