blob: 9493acf8b5ac885de0a2d1c38266d567f3f639ac [file] [log] [blame]
Jian Lib6859e12016-03-01 09:29:24 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Jian Lib6859e12016-03-01 09:29:24 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.ui.chart;
18
Jian Li15468822016-04-15 16:28:11 -070019import com.google.common.collect.Lists;
Jian Lib6859e12016-03-01 09:29:24 -080020import com.google.common.collect.Maps;
Jian Li15468822016-04-15 16:28:11 -070021import com.google.common.collect.Sets;
Jian Lib6859e12016-03-01 09:29:24 -080022
23import java.util.Arrays;
Jian Li15468822016-04-15 16:28:11 -070024import java.util.List;
Jian Lib6859e12016-03-01 09:29:24 -080025import java.util.Map;
Jian Li15468822016-04-15 16:28:11 -070026import java.util.Set;
Jian Lib6859e12016-03-01 09:29:24 -080027
28import static com.google.common.base.Preconditions.checkArgument;
29import static com.google.common.base.Preconditions.checkNotNull;
30
31/**
Jian Li15468822016-04-15 16:28:11 -070032 * A simple model of time series chart data.
Jian Lib6859e12016-03-01 09:29:24 -080033 *
34 * <p>
35 * Note that this is not a full MVC type model; the expected usage pattern
36 * is to create an empty chart, add data points (by consulting the business model),
37 * and produce the list of data points which contain a label and a set of data
38 * values for all serials.
39 */
40public class ChartModel {
41
Jian Li15468822016-04-15 16:28:11 -070042 private final Set<String> seriesSet;
43 private final String[] seriesArray;
44 private final List<Long> labels = Lists.newArrayList();
45 private final List<DataPoint> dataPoints = Lists.newArrayList();
Jian Lib6859e12016-03-01 09:29:24 -080046
47 /**
48 * Constructs a chart model with initialized series set.
49 *
Jian Lib6859e12016-03-01 09:29:24 -080050 * @param series a set of series
51 */
Jian Li15468822016-04-15 16:28:11 -070052 public ChartModel(String... series) {
Jian Lib6859e12016-03-01 09:29:24 -080053 checkNotNull(series, "series cannot be null");
54 checkArgument(series.length > 0, "must be at least one series");
Jian Lib6859e12016-03-01 09:29:24 -080055
Jian Li15468822016-04-15 16:28:11 -070056 seriesSet = Sets.newHashSet(series);
57
58 if (seriesSet.size() != series.length) {
59 throw new IllegalArgumentException("duplicate series detected");
Jian Lib6859e12016-03-01 09:29:24 -080060 }
61
Jian Li15468822016-04-15 16:28:11 -070062 this.seriesArray = Arrays.copyOf(series, series.length);
Jian Lib6859e12016-03-01 09:29:24 -080063 }
64
65 private void checkDataPoint(DataPoint dataPoint) {
Jian Li15468822016-04-15 16:28:11 -070066 checkArgument(dataPoint.size() == seriesCount(),
Jian Lib6859e12016-03-01 09:29:24 -080067 "data size should be equal to number of series");
68 }
69
70 /**
Jian Li15468822016-04-15 16:28:11 -070071 * Checks the validity of the given series.
72 *
73 * @param series series name
74 */
75 private void checkSeries(String series) {
76 checkNotNull(series, "must provide a series name");
77 if (!seriesSet.contains(series)) {
78 throw new IllegalArgumentException("unknown series: " + series);
79 }
80 }
81
82 /**
Jian Lib6859e12016-03-01 09:29:24 -080083 * Returns the number of series in this chart model.
84 *
85 * @return number of series
86 */
87 public int seriesCount() {
Jian Li15468822016-04-15 16:28:11 -070088 return seriesSet.size();
Jian Lib6859e12016-03-01 09:29:24 -080089 }
90
91 /**
Jian Li15468822016-04-15 16:28:11 -070092 * Adds a data point to the chart model.
Jian Lib6859e12016-03-01 09:29:24 -080093 *
Jian Li15468822016-04-15 16:28:11 -070094 * @return the data point, for chaining
Jian Lib6859e12016-03-01 09:29:24 -080095 */
Jian Li15468822016-04-15 16:28:11 -070096 public DataPoint addDataPoint(Long label) {
97 DataPoint dp = new DataPoint();
98 labels.add(label);
99 dataPoints.add(dp);
100 return dp;
Jian Lib6859e12016-03-01 09:29:24 -0800101 }
102
103 /**
104 * Returns all of series.
105 *
106 * @return an array of series
107 */
108 public String[] getSeries() {
Jian Li15468822016-04-15 16:28:11 -0700109 return seriesArray;
Jian Lib6859e12016-03-01 09:29:24 -0800110 }
111
112 /**
Jian Li15468822016-04-15 16:28:11 -0700113 * Returns all of data points in order.
Jian Lib6859e12016-03-01 09:29:24 -0800114 *
115 * @return an array of data points
116 */
117 public DataPoint[] getDataPoints() {
Jian Li15468822016-04-15 16:28:11 -0700118 return dataPoints.toArray(new DataPoint[dataPoints.size()]);
119 }
120
121 /**
122 * Returns all of labels in order.
123 *
124 * @return an array of labels
125 */
126 public Object[] getLabels() {
127 return labels.toArray(new Long[labels.size()]);
128 }
129
130 /**
131 * Returns the number of data points in this chart model.
132 *
133 * @return number of data points
134 */
135 public int dataPointCount() {
136 return dataPoints.size();
Jian Lib6859e12016-03-01 09:29:24 -0800137 }
138
139 /**
140 * Returns the last element inside all of data points.
141 *
142 * @return data point
143 */
144 public DataPoint getLastDataPoint() {
Jian Li15468822016-04-15 16:28:11 -0700145 return dataPoints.get(dataPoints.size() - 1);
Jian Lib6859e12016-03-01 09:29:24 -0800146 }
147
148 /**
149 * A class of data point.
150 */
151 public class DataPoint {
152 // values for all series
Jian Li15468822016-04-15 16:28:11 -0700153 private final Map<String, Double> data = Maps.newHashMap();
Jian Lib6859e12016-03-01 09:29:24 -0800154
155 /**
Jian Li15468822016-04-15 16:28:11 -0700156 * Sets the data value for the given series of this data point.
Jian Lib6859e12016-03-01 09:29:24 -0800157 *
Jian Li15468822016-04-15 16:28:11 -0700158 * @param series series name
159 * @param value value to set
160 * @return self, for chaining
Jian Lib6859e12016-03-01 09:29:24 -0800161 */
Jian Li15468822016-04-15 16:28:11 -0700162 public DataPoint data(String series, Double value) {
163 checkSeries(series);
164 data.put(series, value);
165 return this;
Jian Lib6859e12016-03-01 09:29:24 -0800166 }
167
168 /**
Jian Li15468822016-04-15 16:28:11 -0700169 * Returns the data value with the given series for this data point.
Jian Lib6859e12016-03-01 09:29:24 -0800170 *
Jian Li15468822016-04-15 16:28:11 -0700171 * @return data value
Jian Lib6859e12016-03-01 09:29:24 -0800172 */
Jian Li15468822016-04-15 16:28:11 -0700173 public Double get(String series) {
174 return data.get(series);
175 }
176
177 /**
178 * Return the data value with the same order of series.
179 *
180 * @return an array of ordered data values
181 */
182 public Double[] getAll() {
183 Double[] value = new Double[getSeries().length];
184 int idx = 0;
185 for (String s : getSeries()) {
186 value[idx] = get(s);
187 idx++;
188 }
189 return value;
Jian Lib6859e12016-03-01 09:29:24 -0800190 }
191
192 /**
193 * Returns the size of data point.
Jian Lib6859e12016-03-01 09:29:24 -0800194 *
Jian Li15468822016-04-15 16:28:11 -0700195 * @return the size of data point
Jian Lib6859e12016-03-01 09:29:24 -0800196 */
Jian Li15468822016-04-15 16:28:11 -0700197 public int size() {
198 return data.size();
Jian Lib6859e12016-03-01 09:29:24 -0800199 }
200 }
201}