diff --git a/core/api/src/main/java/org/onosproject/ui/chart/ChartModel.java b/core/api/src/main/java/org/onosproject/ui/chart/ChartModel.java
new file mode 100644
index 0000000..8101eb0
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/ui/chart/ChartModel.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.ui.chart;
+
+import com.google.common.collect.Maps;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A simple model of chart data.
+ *
+ * <p>
+ * Note that this is not a full MVC type model; the expected usage pattern
+ * is to create an empty chart, add data points (by consulting the business model),
+ * and produce the list of data points which contain a label and a set of data
+ * values for all serials.
+ */
+public class ChartModel {
+
+    // key is series name, value is series index
+    private final Map<String, Integer> seriesMap;
+    private final DataPoint[] dataPoints;
+
+    /**
+     * Constructs a chart model with initialized series set.
+     *
+     * @param series a set of series
+     */
+    public ChartModel(int size, String... series) {
+        checkNotNull(series, "series cannot be null");
+        checkArgument(series.length > 0, "must be at least one series");
+        seriesMap = Maps.newConcurrentMap();
+
+        for (int index = 0; index < series.length; index++) {
+            seriesMap.put(series[index], index);
+        }
+
+        checkArgument(size > 0, "must have at least one data point");
+        dataPoints = new DataPoint[size];
+    }
+
+    private void checkDataPoint(DataPoint dataPoint) {
+        checkArgument(dataPoint.getSize() == seriesCount(),
+                "data size should be equal to number of series");
+    }
+
+    /**
+     * Returns the number of series in this chart model.
+     *
+     * @return number of series
+     */
+    public int seriesCount() {
+        return seriesMap.size();
+    }
+
+    /**
+     * Shifts all of the data points to the left,
+     * and adds a new data point to the tail of the array.
+     *
+     * @param label label name
+     * @param values a set of data values
+     */
+    public void addDataPoint(String label, Double[] values) {
+        DataPoint dp = new DataPoint(label, values);
+        checkDataPoint(dp);
+
+        for (int index = 1; index < dataPoints.length; index++) {
+            dataPoints[index - 1] = dataPoints[index];
+        }
+        dataPoints[dataPoints.length - 1] = dp;
+    }
+
+    /**
+     * Returns all of series.
+     *
+     * @return an array of series
+     */
+    public String[] getSeries() {
+        return seriesMap.keySet().toArray(new String[seriesMap.size()]);
+    }
+
+    /**
+     * Returns all of data points.
+     *
+     * @return an array of data points
+     */
+    public DataPoint[] getDataPoints() {
+        return Arrays.copyOf(dataPoints, dataPoints.length);
+    }
+
+    /**
+     * Returns the last element inside all of data points.
+     *
+     * @return data point
+     */
+    public DataPoint getLastDataPoint() {
+        return dataPoints[dataPoints.length - 1];
+    }
+
+    /**
+     * A class of data point.
+     */
+    public class DataPoint {
+        // values for all series
+        private final Double[] values;
+        private final String label;
+
+        /**
+         * Constructs a data point.
+         *
+         * @param label label name
+         * @param values a set of data values for all series
+         */
+        public DataPoint(String label, Double[] values) {
+            this.label = label;
+            this.values = values;
+        }
+
+        /**
+         * Returns the label name of this data point.
+         *
+         * @return label name
+         */
+        public String getLabel() {
+            return label;
+        }
+
+        /**
+         * Returns the size of data point.
+         * This should be identical to the size of series.
+         *
+         * @return size of data point
+         */
+        public int getSize() {
+            return values.length;
+        }
+
+        /**
+         * Returns the value of the data point of the given series.
+         *
+         * @param series series name
+         * @return data value of a specific series
+         */
+        public Double getValue(String series) {
+            return values[seriesMap.get(series)];
+        }
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/ui/chart/package-info.java b/core/api/src/main/java/org/onosproject/ui/chart/package-info.java
new file mode 100644
index 0000000..4c24238
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/ui/chart/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Facilities for creating chart models of data for the GUI.
+ */
+package org.onosproject.ui.chart;
\ No newline at end of file
diff --git a/core/api/src/test/java/org/onosproject/ui/chart/ChartModelTest.java b/core/api/src/test/java/org/onosproject/ui/chart/ChartModelTest.java
new file mode 100644
index 0000000..640cbac
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/ui/chart/ChartModelTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ui.chart;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for {@link ChartModel}.
+ */
+public class ChartModelTest {
+
+    private static final String FOO = "foo";
+    private static final String BAR = "bar";
+    private static final String ZOO = "zoo";
+
+    private static final Double[] VALUES1 = {0D, 1D, 2D};
+    private static final Double[] VALUES2 = {3D, 4D, 5D};
+    private static final Double[] VALUES3 = {6D, 7D, 8D};
+
+    private static final String[] SERIES = {FOO, BAR, ZOO};
+
+    private ChartModel cm;
+
+    @Test(expected = NullPointerException.class)
+    public void guardAgainstNullSeries() {
+        cm = new ChartModel(1, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void guardAgainstWrongDpNumber() {
+        cm = new ChartModel(0, FOO);
+    }
+
+    @Test
+    public void testSeriesCount() {
+        cm = new ChartModel(1, FOO, BAR, ZOO);
+        assertEquals("Wrong series count", 3, cm.seriesCount());
+    }
+
+    @Test
+    public void testAddDataPoint() {
+        cm = new ChartModel(2, FOO, BAR, ZOO);
+
+        cm.addDataPoint("1", VALUES1);
+        cm.addDataPoint("2", VALUES2);
+
+        assertEquals("Wrong result", "1", cm.getDataPoints()[0].getLabel());
+        assertEquals("Wrong result", "2", cm.getDataPoints()[1].getLabel());
+
+        cm.addDataPoint("3", VALUES3);
+
+        assertEquals("Wrong result", "2", cm.getDataPoints()[0].getLabel());
+        assertEquals("Wrong result", "3", cm.getDataPoints()[1].getLabel());
+    }
+
+    @Test
+    public void testGetData() {
+        cm = new ChartModel(2, FOO, BAR, ZOO);
+
+        cm.addDataPoint("1", VALUES1);
+        assertThat(cm.getLastDataPoint().getValue(ZOO), is(2D));
+
+        cm.addDataPoint("2", VALUES2);
+        assertThat(cm.getLastDataPoint().getValue(BAR), is(4D));
+    }
+
+    @Test
+    public void testGetSeries() {
+        cm = new ChartModel(1, FOO, BAR, ZOO);
+
+        assertArrayEquals("series", SERIES, cm.getSeries());
+    }
+}
