Description & Source Code
  • Description
  • View
  • View Model
  • Model

This example demonstrates how a pie chart can be dynamically updated by using its model.
The onChange event is fired to trigger an update when the control panel's value is changed.

<vlayout apply="org.zkoss.bind.BindComposer" 
	viewModel="@id('vm') @init('demo.chart.pie.PieChartVM')">
	<chart id="mychart" title="Pie Chart Demo" 
		width="550" height="400" paneColor="#ffffff" fgAlpha="192"
		type="pie" threeD="@bind(vm.threeD)" 
		model="@bind(vm.model)" engine="@bind(vm.engine)"
	<hlayout  visible="@bind(not empty vm.message)">
		You clicked on :<label value="@bind(vm.message)"/>

<vlayout apply="org.zkoss.bind.BindComposer" 
	viewModel="@id('vm') @init('demo.chart.pie.PieChartConfigVM')">
	<grid width="98%">
			<column label="Category"  />
			<column label="Value" width="90px" />
				<label value="C#" />
				<doublebox value="@bind(vm.value1)" constraint="no empty" width="70px"
					onChange="@global-command('dataChanged', category='C#', num=vm.value1)" />
				<label value="VB" />
				<doublebox value="@bind(vm.value2)" constraint="no empty" width="70px"
					onChange="@global-command('dataChanged', category='VB', num=vm.value2)" />
				<label value="Java" />
				<doublebox value="@bind(vm.value3)" constraint="no empty" width="70px"
					onChange="@global-command('dataChanged', category='Java', num=vm.value3)" />
				<label value="PHP" />
				<doublebox value="@bind(vm.value4)" constraint="no empty" width="70px"
					onChange="@global-command('dataChanged', category='PHP', num=vm.value4)" />
	<separator height="10px" />
	<groupbox sclass="z-demo-config">
		<caption>Chart Control</caption>
				<radio label="Pie Chart" selected="true"
					onCheck="@global-command('configChanged', threeD=false, exploded=false)" />			
				<radio label="Pie Chart 3D"
					onCheck="@global-command('configChanged', threeD=true, exploded=false)" />
				<radio label="Pie Chart Exploded"
					onCheck="@global-command('configChanged', threeD=false, exploded=true)" />
package demo.chart.pie;

import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zul.PieModel;

import demo.chart.PieChartData;

public class PieChartVM {

	PieChartEngine engine;
	PieModel model;
	boolean threeD = false;
	String message;
	public void init() {
		// prepare chart data
		engine = new PieChartEngine();

		model = PieChartData.getModel();

	public PieChartEngine getEngine() {
		return engine;

	public PieModel getModel() {
		return model;

	public boolean isThreeD() {
		return threeD;
	public String getMessage(){
		return message;
	public void onShowMessage(
			@BindingParam("msg") String message){
		this.message = message;
	public void onDataChanged(
			@BindingParam("category")String category,
			@BindingParam("num") Number num){
		model.setValue(category, num);
	public void onConfigChanged(
			@BindingParam("threeD") boolean threeD,
			@BindingParam("exploded") boolean exploded){
		this.threeD = threeD;
package demo.chart.pie;

public class PieChartConfigVM {
	double value1 = 22.1D;
	double value2 = 10.2D;
	double value3 = 40.4D;
	double value4 = 28.2D;

	public double getValue1() {
		return value1;

	public void setValue1(double value1) {
		this.value1 = value1;

	public double getValue2() {
		return value2;

	public void setValue2(double value2) {
		this.value2 = value2;

	public double getValue3() {
		return value3;

	public void setValue3(double value3) {
		this.value3 = value3;

	public double getValue4() {
		return value4;

	public void setValue4(double value4) {
		this.value4 = value4;

package demo.chart.pie;

import java.awt.Color;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.DefaultDrawingSupplier;
import org.jfree.chart.plot.PiePlot;
import org.zkoss.zkex.zul.impl.JFreeChartEngine;
import org.zkoss.zul.Chart;

import demo.chart.ChartColors;

 * you are able to do many advanced chart customization by extending ChartEngine
public class PieChartEngine extends JFreeChartEngine {
	private boolean explode = false;
	public boolean prepareJFreeChart(JFreeChart jfchart, Chart chart) {

		PiePlot piePlot = (PiePlot) jfchart.getPlot();

		//override some default colors
		Paint[] colors = new Paint[] {ChartColors.COLOR_1, ChartColors.COLOR_2, ChartColors.COLOR_3, ChartColors.COLOR_4};
		DefaultDrawingSupplier defaults = new DefaultDrawingSupplier();
		piePlot.setDrawingSupplier(new DefaultDrawingSupplier(colors, new Paint[]{defaults.getNextFillPaint()}, new Paint[]{defaults.getNextOutlinePaint()}, 
				new Stroke[]{defaults.getNextStroke()}, new Stroke[] {defaults.getNextOutlineStroke()}, new Shape[] {defaults.getNextShape()}));


		piePlot.setExplodePercent("Java", explode ? 0.2 : 0);

		return false;

	public void setExplode(boolean explode) {
		this.explode = explode;
package demo.chart;

import org.zkoss.zul.PieModel;
import org.zkoss.zul.SimplePieModel;

public class PieChartData {

	public static PieModel getModel(){
		PieModel model = new SimplePieModel();
		model.setValue("C#", new Double(21.2));
		model.setValue("VB", new Double(10.2));
		model.setValue("Java", new Double(40.4));
		model.setValue("PHP", new Double(28.2));
		return model;
package demo.chart;

import java.awt.Color;

import org.apache.commons.lang.StringUtils;

public class ChartColors {
	//main colors
	public static Color COLOR_1 = new Color(0x3E454C);
	public static Color COLOR_2 = new Color(0x2185C5);
	public static Color COLOR_3 = new Color(0x7ECEFD);
	public static Color COLOR_4 = new Color(0xFFF6E5);
	public static Color COLOR_5 = new Color(0xFF7F66);
	//additional colors
	public static Color COLOR_6 = new Color(0x98D9FF);
	public static Color COLOR_7 = new Color(0x4689B1);
	public static Color COLOR_8 = new Color(0xB17C35);
	public static Color COLOR_9 = new Color(0xFDC77E);
	public static String toHtmlColor(Color color) {
		return "#" + toHexColor(color);

	public static String toHexColor(Color color) {
		return StringUtils.leftPad(Integer.toHexString(color.getRGB() & 0xFFFFFF), 6, '0');