Introduce ChartItems instead of Json API

Different nvd3 charts require different JSON formats. Don't let the
application developer deal with these.

Provide a simple data model for chart data, with immutable item objects
that can be shared between sessions. These objects don't have a remote
counterpart, they're rendered as JSON on setItems().

Change-Id: I48bc7f5239698ea2b0c1634c900846233d631ad8
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java
index 6fd3e1f..ea1c472 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java
@@ -71,7 +71,7 @@
     requireJs( registerResource( "chart/chart.js" ) );
   }
 
-  public void setChartData( JsonArray data ) {
+  protected void setItems( JsonArray data ) {
     checkWidget();
     remoteObject.set( "items", data );
   }
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java
index fd053d8..3319ca7 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java
@@ -20,7 +20,7 @@
   private static final String NVD3_JS_URL
     = "https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.js";
 
-  public NvChart( Composite parent, int style, String renderer ) {
+  protected NvChart( Composite parent, int style, String renderer ) {
     super( parent, style, renderer );
     requireJs( NVD3_JS_URL );
     requireCss( NVD3_CSS_URL );
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarChart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarChart.java
index 291db0e..625ef38 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarChart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarChart.java
@@ -11,6 +11,8 @@
 package org.eclipse.rap.addons.chart.basic;
 
 import org.eclipse.rap.addons.chart.NvChart;
+import org.eclipse.rap.json.JsonArray;
+import org.eclipse.rap.json.JsonObject;
 import org.eclipse.swt.widgets.Composite;
 
 
@@ -36,4 +38,12 @@
     return showValues;
   }
 
+  public void setItems( BarItem... items ) {
+    JsonArray values = new JsonArray();
+    for( BarItem item : items ) {
+      values.add( item.toJson() );
+    }
+    setItems( new JsonArray().add( new JsonObject().add( "values", values ) ) );
+  }
+
 }
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarItem.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarItem.java
new file mode 100644
index 0000000..c61ebb6
--- /dev/null
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/BarItem.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.eclipse.rap.addons.chart.internal.ColorUtil.toHtmlString;
+
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.swt.graphics.RGB;
+
+
+public class BarItem {
+
+  protected double value;
+  protected String text;
+  protected RGB color;
+
+  public BarItem( double value, String text ) {
+    this.value = value;
+    this.text = text;
+  }
+
+  public BarItem( double value, String text, RGB color ) {
+    this.value = value;
+    this.text = text;
+    this.color = color;
+  }
+
+  protected JsonObject toJson() {
+    JsonObject json = new JsonObject().add( "value", value );
+    if( text != null ) {
+      json.add( "label", text );
+    }
+    if( color != null ) {
+      json.add( "color", toHtmlString( color ) );
+    }
+    return json;
+  }
+
+}
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/DataPoint.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/DataPoint.java
new file mode 100644
index 0000000..fc20ad5
--- /dev/null
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/DataPoint.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import org.eclipse.rap.json.JsonObject;
+
+public class DataPoint {
+
+  public double x;
+  public double y;
+
+  public DataPoint(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  protected JsonObject toJson() {
+    return new JsonObject().add( "x", x ).add( "y", y );
+  }
+
+}
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineChart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineChart.java
index f834173..b3b7619 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineChart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineChart.java
@@ -11,6 +11,7 @@
 package org.eclipse.rap.addons.chart.basic;
 
 import org.eclipse.rap.addons.chart.NvChart;
+import org.eclipse.rap.json.JsonArray;
 import org.eclipse.swt.widgets.Composite;
 
 
@@ -73,4 +74,12 @@
     return yAxisFormat;
   }
 
+  public void setItems( LineItem... items ) {
+    JsonArray values = new JsonArray();
+    for( LineItem item : items ) {
+      values.add( item.toJson() );
+    }
+    setItems( values );
+  }
+
 }
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineItem.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineItem.java
new file mode 100644
index 0000000..831c4d2
--- /dev/null
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/LineItem.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.eclipse.rap.addons.chart.internal.ColorUtil.toHtmlString;
+
+import org.eclipse.rap.json.JsonArray;
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.swt.graphics.RGB;
+
+public class LineItem {
+
+  private DataPoint[] points;
+  private String text;
+  private RGB color;
+
+  public LineItem( DataPoint[] points, String text ) {
+    this( points, text, null );
+  }
+
+  public LineItem( DataPoint[] points, String text, RGB color ) {
+    this.points = points;
+    this.text = text;
+    this.color = color;
+  }
+
+  protected JsonObject toJson() {
+    JsonArray values = new JsonArray();
+    for( DataPoint point : points ) {
+      values.add( point.toJson() );
+    }
+    JsonObject json = new JsonObject().add( "values", values );
+    if( text != null ) {
+      json.add( "key", text );
+    }
+    if( color != null ) {
+      json.add( "color", toHtmlString( color ) );
+    }
+    return json;
+  }
+
+}
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieChart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieChart.java
index 2dad0cc..a673373 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieChart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieChart.java
@@ -11,6 +11,7 @@
 package org.eclipse.rap.addons.chart.basic;
 
 import org.eclipse.rap.addons.chart.NvChart;
+import org.eclipse.rap.json.JsonArray;
 import org.eclipse.swt.widgets.Composite;
 
 
@@ -36,4 +37,12 @@
     return showLabels;
   }
 
+  public void setItems( PieItem... items ) {
+    JsonArray values = new JsonArray();
+    for( PieItem item : items ) {
+      values.add( item.toJson() );
+    }
+    setItems( values );
+  }
+
 }
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieItem.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieItem.java
new file mode 100644
index 0000000..aa65a12
--- /dev/null
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/basic/PieItem.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.eclipse.rap.addons.chart.internal.ColorUtil.toHtmlString;
+
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.swt.graphics.RGB;
+
+
+public class PieItem {
+
+  protected double value;
+  protected String text;
+  protected RGB color;
+
+  public PieItem( double value, String text ) {
+    this.value = value;
+    this.text = text;
+  }
+
+  public PieItem( double value, String text, RGB color ) {
+    this.value = value;
+    this.text = text;
+    this.color = color;
+  }
+
+  protected JsonObject toJson() {
+    JsonObject json = new JsonObject().add( "value", value );
+    if( text != null ) {
+      json.add( "label", text );
+    }
+    if( color != null ) {
+      json.add( "color", toHtmlString( color ) );
+    }
+    return json;
+  }
+
+}
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/internal/ColorUtil.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/internal/ColorUtil.java
new file mode 100644
index 0000000..bd3db7c
--- /dev/null
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/internal/ColorUtil.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.internal;
+
+import org.eclipse.swt.graphics.RGB;
+
+
+public class ColorUtil {
+
+  public static String toHtmlString( RGB color ) {
+    StringBuilder result = new StringBuilder( 7 ).append( '#' );
+    append2x( result, color.red );
+    append2x( result, color.green );
+    append2x( result, color.blue );
+    return result.toString();
+  }
+
+  private static void append2x( StringBuilder result, int red ) {
+    if( red < 16 ) {
+      result.append( '0' );
+    }
+    result.append( Integer.toHexString( red ) );
+  }
+
+  private ColorUtil() {
+    // prevent instantiation
+  }
+
+}
diff --git a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/BarChartSnippet.java b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/BarChartSnippet.java
index 62544b0..ae9875c 100644
--- a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/BarChartSnippet.java
+++ b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/BarChartSnippet.java
@@ -10,9 +10,10 @@
  ******************************************************************************/
 package org.eclipse.rap.addons.chart.nv.demo;
 
+import static org.eclipse.rap.addons.chart.nv.demo.Colors.CAT10_COLORS;
+
 import org.eclipse.rap.addons.chart.basic.BarChart;
-import org.eclipse.rap.json.JsonArray;
-import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.addons.chart.basic.BarItem;
 import org.eclipse.rap.rwt.application.AbstractEntryPoint;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
@@ -59,28 +60,17 @@
   }
 
   private void update() {
-    barChart.setChartData( createData() );
+    barChart.setItems( createItems() );
   }
 
-  private static JsonArray createData() {
-    return new JsonArray()
-      .add( new JsonObject().add( "key", "foo" ).add( "values", createRandomValues() ) );
-  }
-
-  private static JsonArray createRandomValues() {
-    return new JsonArray()
-      .add( createItem( "Item 1", "#ff0000", Math.random() * 100 ) )
-      .add( createItem( "Item 2", "#00ff00", Math.random() * 100 ) )
-      .add( createItem( "Item 3", "#0000ff", Math.random() * 100 ) )
-      .add( createItem( "Item 4", "#ffff00", Math.random() * 100 ) )
-      .add( createItem( "Item 5", "#00ffff", Math.random() * 100 ) );
-  }
-
-  private static JsonObject createItem( String text, String color, double value ) {
-    return new JsonObject()
-      .add( "label", text )
-      .add( "color", color )
-      .add( "value", value );
+  private static BarItem[] createItems() {
+    return new BarItem[] {
+      new BarItem( Math.random() * 100, "Item 1", CAT10_COLORS[ 0 ] ),
+      new BarItem( Math.random() * 100, "Item 2", CAT10_COLORS[ 1 ] ),
+      new BarItem( Math.random() * 100, "Item 3", CAT10_COLORS[ 2 ] ),
+      new BarItem( Math.random() * 100, "Item 4", CAT10_COLORS[ 3 ] ),
+      new BarItem( Math.random() * 100, "Item 5", CAT10_COLORS[ 4 ] )
+    };
   }
 
 }
diff --git a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/Colors.java b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/Colors.java
new file mode 100644
index 0000000..4ba69d8
--- /dev/null
+++ b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/Colors.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.nv.demo;
+
+import org.eclipse.swt.graphics.RGB;
+
+
+public class Colors {
+
+  public static final RGB[] CAT10_COLORS = {
+    new RGB( 0x1f, 0x77, 0xb4 ),
+    new RGB( 0xff, 0x7f, 0x0e ),
+    new RGB( 0x2c, 0xa0, 0x2c ),
+    new RGB( 0xd6, 0x27, 0x28 ),
+    new RGB( 0x94, 0x67, 0xbd ),
+    new RGB( 0x8c, 0x56, 0x4b ),
+    new RGB( 0xe3, 0x77, 0xc2 ),
+    new RGB( 0x7f, 0x7f, 0x7f ),
+    new RGB( 0xbc, 0xbd, 0x22 ),
+    new RGB( 0x17, 0xbe, 0xcf )
+  };
+
+}
diff --git a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/LineChartSnippet.java b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/LineChartSnippet.java
index ee54139..0e391b3 100644
--- a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/LineChartSnippet.java
+++ b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/LineChartSnippet.java
@@ -10,9 +10,11 @@
  ******************************************************************************/
 package org.eclipse.rap.addons.chart.nv.demo;
 
+import static org.eclipse.rap.addons.chart.nv.demo.Colors.CAT10_COLORS;
+
+import org.eclipse.rap.addons.chart.basic.DataPoint;
 import org.eclipse.rap.addons.chart.basic.LineChart;
-import org.eclipse.rap.json.JsonArray;
-import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.addons.chart.basic.LineItem;
 import org.eclipse.rap.rwt.application.AbstractEntryPoint;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
@@ -61,28 +63,22 @@
   }
 
   private void update() {
-    lineChart.setChartData( createData() );
+    lineChart.setItems( createItems() );
   }
 
-  private static JsonArray createData() {
-    return new JsonArray()
-      .add( createItem( "Series 1", "#ff0000", createRandomSeries() ) )
-      .add( createItem( "Series 2", "#0000ff", createRandomSeries() ) );
+  private static LineItem[] createItems() {
+    return new LineItem[] {
+      new LineItem( createRandomPoints(), "Series 1", CAT10_COLORS[ 0 ] ),
+      new LineItem( createRandomPoints(), "Series 2", CAT10_COLORS[ 1 ] )
+    };
   }
 
-  private static JsonObject createItem( String text, String color, JsonArray values ) {
-    return new JsonObject()
-      .add( "key", text )
-      .add( "color", color )
-      .add( "values", values );
-  }
-
-  private static JsonArray createRandomSeries() {
-    JsonArray data = new JsonArray();
-    for( int i = 0; i < 100; i++ ) {
-      data.add( new JsonObject().add( "x", i ).add( "y", Math.random() * 100 ) );
+  private static DataPoint[] createRandomPoints() {
+    DataPoint[] values = new DataPoint[100];
+    for( int i = 0; i < values.length; i++ ) {
+      values[i] = new DataPoint( i, Math.random() * 100 );
     }
-    return data;
+    return values;
   }
 
 }
diff --git a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/PieChartSnippet.java b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/PieChartSnippet.java
index 0046034..dabddd9 100644
--- a/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/PieChartSnippet.java
+++ b/examples/org.eclipse.rap.addons.chart.demo/src/org/eclipse/rap/addons/chart/nv/demo/PieChartSnippet.java
@@ -10,9 +10,11 @@
  ******************************************************************************/
 package org.eclipse.rap.addons.chart.nv.demo;
 
+
+import static org.eclipse.rap.addons.chart.nv.demo.Colors.CAT10_COLORS;
+
+import org.eclipse.rap.addons.chart.basic.PieItem;
 import org.eclipse.rap.addons.chart.basic.PieChart;
-import org.eclipse.rap.json.JsonArray;
-import org.eclipse.rap.json.JsonObject;
 import org.eclipse.rap.rwt.application.AbstractEntryPoint;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
@@ -59,21 +61,17 @@
   }
 
   private void update() {
-    pieChart.setChartData( createData() );
+    pieChart.setItems( createItems() );
   }
 
-  private static JsonArray createData() {
-    return new JsonArray()
-      .add( createItem( "Item 1", "#ff0000", Math.random() * 100 ) )
-      .add( createItem( "Item 2", "#00ff00", Math.random() * 100 ) )
-      .add( createItem( "Item 3", "#0000ff", Math.random() * 100 ) );
-  }
-
-  private static JsonObject createItem( String text, String color, double value ) {
-    return new JsonObject()
-      .add( "label", text )
-      .add( "color", color )
-      .add( "value", value );
+  private static PieItem[] createItems() {
+    return new PieItem[] {
+      new PieItem( Math.random() * 100, "Item 1", CAT10_COLORS[ 0 ] ),
+      new PieItem( Math.random() * 100, "Item 2", CAT10_COLORS[ 1 ] ),
+      new PieItem( Math.random() * 100, "Item 3", CAT10_COLORS[ 2 ] ),
+      new PieItem( Math.random() * 100, "Item 4", CAT10_COLORS[ 3 ] ),
+      new PieItem( Math.random() * 100, "Item 5", CAT10_COLORS[ 4 ] )
+    };
   }
 
 }
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java
index 61815d4..32f15d3 100644
--- a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java
@@ -110,19 +110,19 @@
   }
 
   @Test( expected = SWTException.class )
-  public void testSetChartData_checksWidget() {
+  public void testSetItems_checksWidget() {
     Chart chart = new Chart( shell, SWT.NONE, "foo" ) {};
     chart.dispose();
 
-    chart.setChartData( new JsonArray() );
+    chart.setItems( new JsonArray() );
   }
 
   @Test
-  public void testSetChartData_isRendered() {
+  public void testSetItems_isRendered() {
     Chart chart = new Chart( shell, SWT.NONE, "foo" ) {};
     JsonArray data = new JsonArray().add( 23 ).add( 42 );
 
-    chart.setChartData( data );
+    chart.setItems( data );
 
     verify( remoteObject ).set( "items", data );
   }
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarChart_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarChart_Test.java
index 069ad1e..0cba0e6 100644
--- a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarChart_Test.java
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarChart_Test.java
@@ -16,6 +16,7 @@
 import static org.mockito.Matchers.eq;
 
 import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.json.JsonValue;
 import org.eclipse.rap.rwt.internal.remote.ConnectionImpl;
 import org.eclipse.rap.rwt.remote.Connection;
 import org.eclipse.rap.rwt.remote.RemoteObject;
@@ -85,6 +86,17 @@
     verify( remoteObject ).call( "setOptions", new JsonObject().add( "showValues", false ) );
   }
 
+  @Test
+  public void testSetItems() {
+    reset( remoteObject );
+
+    chart.setItems( new BarItem( 23, "foo" ), new BarItem( 42, "bar" ) );
+
+    String expected = "[ { \"values\": [ { \"value\": 23, \"label\": \"foo\" },"
+                                      + "{ \"value\": 42, \"label\": \"bar\" } ] } ]";
+    verify( remoteObject ).set( "items", JsonValue.readFrom(expected) );
+  }
+
   private Connection fakeConnection( RemoteObject remoteObject ) {
     ConnectionImpl connection = mock( ConnectionImpl.class );
     when( connection.createRemoteObject( anyString() ) ).thenReturn( remoteObject );
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarItem_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarItem_Test.java
new file mode 100644
index 0000000..555c70b
--- /dev/null
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/BarItem_Test.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.json.JsonValue;
+import org.eclipse.swt.graphics.RGB;
+import org.junit.Test;
+
+
+public class BarItem_Test {
+
+  @Test
+  public void testToJson() {
+    BarItem item = new BarItem( 23, "foo", new RGB( 0, 8, 128 ) );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'value': 23, 'label': 'foo', 'color': '#000880'}" );
+    assertEquals( expected, json );
+  }
+
+  @Test
+  public void testToJson_skipsMissingColor() {
+    BarItem item = new BarItem( 23, "foo" );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'value': 23, 'label': 'foo'}" );
+    assertEquals( expected, json );
+  }
+
+  @Test
+  public void testToJson_skipsMissingText() {
+    BarItem item = new BarItem( 23, null, new RGB( 0, 8, 128 ) );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'value': 23, 'color': '#000880'}" );
+    assertEquals( expected, json );
+  }
+
+  private static JsonValue parse( String json ) {
+    return JsonValue.readFrom( json.replace( '\'', '"' ) );
+  }
+
+}
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/DataPoint_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/DataPoint_Test.java
new file mode 100644
index 0000000..018e03f
--- /dev/null
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/DataPoint_Test.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.rap.json.JsonObject;
+import org.junit.Test;
+
+
+public class DataPoint_Test {
+
+  @Test
+  public void testToJson() {
+    DataPoint dataPoint = new DataPoint( 1.41, 3.14 );
+
+    JsonObject json = dataPoint.toJson();
+
+    assertEquals( new JsonObject().add( "x", 1.41 ).add( "y",  3.14 ), json );
+  }
+
+}
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineChart_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineChart_Test.java
index 4108ca6..7fdc1ff 100644
--- a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineChart_Test.java
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineChart_Test.java
@@ -16,6 +16,7 @@
 import static org.mockito.Matchers.eq;
 
 import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.json.JsonValue;
 import org.eclipse.rap.rwt.internal.remote.ConnectionImpl;
 import org.eclipse.rap.rwt.remote.Connection;
 import org.eclipse.rap.rwt.remote.RemoteObject;
@@ -145,6 +146,22 @@
     verify( remoteObject, times( 0 ) ).set( eq( "spacing" ), anyInt() );
   }
 
+  @Test
+  public void testSetItems() {
+    reset( remoteObject );
+
+    chart.setItems( new LineItem( new DataPoint[] { new DataPoint(1, 2),
+                                                         new DataPoint(3, 4) }, "foo" ),
+                    new LineItem( new DataPoint[] { new DataPoint(2, 4),
+                                                         new DataPoint(6, 8) }, "bar" ) );
+
+    String expected = "[{ \"values\": [{ \"x\": 1, \"y\": 2 },"
+                                    + "{ \"x\": 3, \"y\": 4 }], \"key\": \"foo\" },"
+                     + "{ \"values\": [{ \"x\": 2, \"y\": 4 },"
+                                    + "{ \"x\": 6, \"y\": 8 }], \"key\": \"bar\" }]";
+    verify( remoteObject ).set( "items", JsonValue.readFrom( expected ) );
+  }
+
   private Connection fakeConnection( RemoteObject remoteObject ) {
     ConnectionImpl connection = mock( ConnectionImpl.class );
     when( connection.createRemoteObject( anyString() ) ).thenReturn( remoteObject );
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineItem_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineItem_Test.java
new file mode 100644
index 0000000..2d0eabf
--- /dev/null
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/LineItem_Test.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.json.JsonValue;
+import org.eclipse.swt.graphics.RGB;
+import org.junit.Test;
+
+
+public class LineItem_Test {
+
+  @Test
+  public void testToJson() {
+    DataPoint[] points = new DataPoint[] { new DataPoint(1, 2), new DataPoint(3, 4) };
+    LineItem item = new LineItem( points, "foo", new RGB( 0, 8, 128 ) );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'values': [{'x': 1, 'y': 2}, {'x': 3, 'y': 4}],"
+                              + "'key': 'foo',"
+                              + "'color': '#000880'}" );
+    assertEquals( expected, json );
+  }
+
+  @Test
+  public void testToJson_skipsMissingColor() {
+    DataPoint[] points = new DataPoint[] { new DataPoint(1, 2), new DataPoint(3, 4) };
+    LineItem item = new LineItem( points, "foo" );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'values': [{'x': 1, 'y': 2}, {'x': 3, 'y': 4}],"
+                              + "'key': 'foo'}" );
+    assertEquals( expected, json );
+  }
+
+  @Test
+  public void testToJson_skipsMissingText() {
+    DataPoint[] points = new DataPoint[] { new DataPoint(1, 2), new DataPoint(3, 4) };
+    LineItem item = new LineItem( points, null, new RGB( 0, 8, 128 ) );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'values': [{'x': 1, 'y': 2}, {'x': 3, 'y': 4}],"
+                              + "'color': '#000880'}" );
+    assertEquals( expected, json );
+  }
+
+  private static JsonValue parse( String json ) {
+    return JsonValue.readFrom( json.replace( '\'', '"' ) );
+  }
+
+}
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieChart_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieChart_Test.java
index 5b7c3a4..b667bca 100644
--- a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieChart_Test.java
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieChart_Test.java
@@ -16,6 +16,7 @@
 import static org.mockito.Matchers.eq;
 
 import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.json.JsonValue;
 import org.eclipse.rap.rwt.internal.remote.ConnectionImpl;
 import org.eclipse.rap.rwt.remote.Connection;
 import org.eclipse.rap.rwt.remote.RemoteObject;
@@ -127,6 +128,17 @@
 //    verify( remoteObject ).call( "setOptions", new JsonObject().add( "endAngle", Math.PI ) );
 //  }
 
+  @Test
+  public void testSetItems() {
+    reset( remoteObject );
+
+    chart.setItems( new PieItem( 23, "foo" ), new PieItem( 42, "bar" ) );
+
+    String expected = "[{ \"value\": 23, \"label\": \"foo\" },"
+                     + "{ \"value\": 42, \"label\": \"bar\" }]";
+    verify( remoteObject ).set( "items", JsonValue.readFrom(expected) );
+  }
+
   private Connection fakeConnection( RemoteObject remoteObject ) {
     ConnectionImpl connection = mock( ConnectionImpl.class );
     when( connection.createRemoteObject( anyString() ) ).thenReturn( remoteObject );
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieItem_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieItem_Test.java
new file mode 100644
index 0000000..b06234c
--- /dev/null
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/basic/PieItem_Test.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ralf Sternberg - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.addons.chart.basic;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.rap.json.JsonValue;
+import org.eclipse.swt.graphics.RGB;
+import org.junit.Test;
+
+
+public class PieItem_Test {
+
+  @Test
+  public void testToJson() {
+    PieItem item = new PieItem( 23, "foo", new RGB( 0, 8, 128 ) );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'value': 23, 'label': 'foo', 'color': '#000880'}" );
+    assertEquals( expected, json );
+  }
+
+  @Test
+  public void testToJson_skipsMissingColor() {
+    PieItem item = new PieItem( 23, "foo" );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'value': 23, 'label': 'foo'}" );
+    assertEquals( expected, json );
+  }
+
+  @Test
+  public void testToJson_skipsMissingText() {
+    PieItem item = new PieItem( 23, null, new RGB( 0, 8, 128 ) );
+
+    JsonObject json = item.toJson();
+
+    JsonValue expected = parse( "{'value': 23, 'color': '#000880'}" );
+    assertEquals( expected, json );
+  }
+
+  private static JsonValue parse( String json ) {
+    return JsonValue.readFrom( json.replace( '\'', '"' ) );
+  }
+
+}