Description & Source Code

This example shows a subset of the available charts when using ZK's chart component.

Developers specify the chart type (pie, line, bar, etc.) and supply it with a data model. Optionally, a chart can be drawn in 3D, its transparency may be adjusted, and the chart area can accept event registration. For example, a chart drill down method can be triggered by a click or mouse over event.

This feature requires ZK PE or EE
<vlayout apply="org.zkoss.bind.BindComposer" 
	viewModel="@id('vm') @init('demo.chart.other.ChartsVM')">
	<chart id="chart" width="520" height="300" fgAlpha="255" paneColor="#ffffff" 
		model="@bind(vm.model)" type="@bind(vm.type)" threeD="@bind(vm.threeD)"
		onClick="@command('showMessage',msg=event.areaComponent.tooltiptext)" engine="@bind(vm.engine)"/>
	<hlayout visible="@bind(not empty vm.message)">
		You clicked on :<label value="@bind(vm.message)"/>
<hlayout apply="org.zkoss.bind.BindComposer"
	viewModel="@id('vm') @init('demo.chart.other.ChartsConfigVM')">
	<radiogroup selectedIndex="@save(vm.selectedIndex)"
		onCheck="@global-command('configChanged',threeD=vm.selected.threeD,type=vm.selected.type)" >
		<vlayout children="@bind(vm.items)">
			<template name="children">
				<radio label="@bind(each.label)" checked="@init(forEachStatus.index eq vm.selectedIndex)" />
package demo.chart.other;

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.zkex.zul.impl.JFreeChartEngine;
import org.zkoss.zul.ChartModel;

public class ChartsVM {
	boolean threeD;
	ChartModel model;
	String type;
	String message;
	ChartsEngine engine;
	public void init() {
		type = "wind";
		threeD = false;
		model = ChartData.getModel(type);
		engine = new ChartsEngine();
	public String getType() {
		return type;

	public String getMessage(){
		return message;
	public boolean isThreeD() {
		return threeD;

	public ChartModel getModel() {
		return model;

	public JFreeChartEngine getEngine() {
		return engine;

	public void onShowMessage(
			@BindingParam("msg") String message){
		this.message = message;

	public void onConfigChanged(
			@BindingParam("threeD") boolean threeD,
			@BindingParam("type") String type){
		this.threeD = threeD;
		this.type = type;
		this.model = ChartData.getModel(type);
package demo.chart.other;

import java.util.ArrayList;
import java.util.List;

import org.zkoss.bind.annotation.Init;

public class ChartsConfigVM {

	int selectedIndex;
	List<ChartItem> items;

	public void init() {
		selectedIndex = 0;
		items = new ArrayList<ChartItem>();
		items.add(new ChartItem("Wind Plot", "wind", false));
		items.add(new ChartItem("Ring Chart", "ring", false));
		items.add(new ChartItem("Stacked Bar Chart", "stacked_bar", false));
		items.add(new ChartItem("Stacked Bar Chart 3D", "stacked_bar", true));
		items.add(new ChartItem("Stacked Area Chart", "stacked_area", false));
		items.add(new ChartItem("Scatter Chart", "scatter", false));
		items.add(new ChartItem("XY Area Chart", "area", false));
		items.add(new ChartItem("Step Area Chart", "step_area", false));
		items.add(new ChartItem("XY Stacked Area Chart", "stacked_area", false));
		items.add(new ChartItem("Histogram Chart", "histogram", false));

	public int getSelectedIndex() {
		return selectedIndex;

	public void setSelectedIndex(int selectedIndex) {
		this.selectedIndex = selectedIndex;
	public ChartItem getSelected(){
		if(selectedIndex<0 || selectedIndex>=items.size()) 
			return null;
		return items.get(selectedIndex);

	public List<ChartItem> getItems() {
		return items;

package demo.chart.other;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import org.zkoss.zul.CategoryModel;
import org.zkoss.zul.ChartModel;
import org.zkoss.zul.PieModel;
import org.zkoss.zul.SimpleCategoryModel;
import org.zkoss.zul.SimplePieModel;
import org.zkoss.zul.SimpleXYModel;
import org.zkoss.zul.SimpleXYZModel;
import org.zkoss.zul.XYModel;
import org.zkoss.zul.XYZModel;

public class ChartData {

	// type to model map
	static HashMap<String,ChartModel> models = new HashMap<String,ChartModel>();
	static {
		int year = Calendar.getInstance().get(Calendar.YEAR) + 1900;
		// Wind Model
		XYZModel windmodel = new SimpleXYZModel();
		// series, date, direction (0-12), force(0-12)
		windmodel.addValue("Wind!", new Long(date(1, 3).getTime()), new Double(0d), new Double(10.0));
		windmodel.addValue("Wind!", new Long(date(1, 4).getTime()), new Double(1d), new Double(8.5));
		windmodel.addValue("Wind!", new Long(date(1, 5).getTime()), new Double(2.0), new Double(10.0));
		windmodel.addValue("Wind!", new Long(date(1, 6).getTime()), new Double(3.0), new Double(10.0));
		windmodel.addValue("Wind!", new Long(date(1, 7).getTime()), new Double(4.0), new Double(7.0));
		windmodel.addValue("Wind!", new Long(date(1, 8).getTime()), new Double(5.0), new Double(10.0));
		windmodel.addValue("Wind!", new Long(date(1, 9).getTime()), new Double(6.0), new Double(8.0));
		windmodel.addValue("Wind!", new Long(date(1, 10).getTime()), new Double(7.0), new Double(11.0));
		windmodel.addValue("Wind!", new Long(date(1, 11).getTime()), new Double(8.0), new Double(10.0));
		windmodel.addValue("Wind!", new Long(date(1, 12).getTime()), new Double(9.0), new Double(11.0));
		windmodel.addValue("Wind!", new Long(date(1, 13).getTime()), new Double(10.0), new Double(3.0));
		windmodel.addValue("Wind!", new Long(date(1, 14).getTime()), new Double(11.0), new Double(9.0));
		windmodel.addValue("Wind!", new Long(date(1, 15).getTime()), new Double(12.0), new Double(11.0));
		windmodel.addValue("Wind!", new Long(date(1, 16).getTime()), new Double(0.0), new Double(0.0));
		models.put("wind", windmodel);

		PieModel piemodel = new SimplePieModel();
		piemodel.setValue("C/C++", new Double(21.2));
		piemodel.setValue("VB", new Double(10.2));
		piemodel.setValue("Java", new Double(40.4));
		piemodel.setValue("PHP", new Double(28.2));
		models.put("ring", piemodel);
		// XY Model
		XYModel xymodel = new SimpleXYModel();
		xymodel.addValue(year - 1 + "", new Integer(20), new Integer(120));
		xymodel.addValue(year - 1 + "", new Integer(40), new Integer(135));
		xymodel.addValue(year - 1 + "", new Integer(60), new Integer(140));
		xymodel.addValue(year - 1 + "", new Integer(80), new Integer(160));
		xymodel.addValue(year + "", new Integer(30), new Integer(120));
		xymodel.addValue(year + "", new Integer(50), new Integer(135));
		xymodel.addValue(year + "", new Integer(70), new Integer(140));
		xymodel.addValue(year + "", new Integer(90), new Integer(160));
		models.put("scatter", xymodel);
		models.put("area", xymodel);
		models.put("step_area", xymodel);
		models.put("stacked_area", xymodel);
		models.put("histogram", xymodel);

		/* Category Model */
		CategoryModel categorymodel = new SimpleCategoryModel();
		categorymodel.setValue(year - 1 + "", "Q1", new Integer(20));
		categorymodel.setValue(year - 1 + "", "Q2", new Integer(35));
		categorymodel.setValue(year - 1 + "", "Q3", new Integer(40));
		categorymodel.setValue(year - 1 + "", "Q4", new Integer(55));
		categorymodel.setValue(year + "", "Q1", new Integer(40));
		categorymodel.setValue(year + "", "Q2", new Integer(60));
		categorymodel.setValue(year + "", "Q3", new Integer(70));
		categorymodel.setValue(year + "", "Q4", new Integer(90));
		models.put("stacked_bar", categorymodel);
		models.put("stacked_area", categorymodel);
	public static ChartModel getModel(String type){
		return models.get(type);

	private static Date date(int month, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, month - 1);
		calendar.set(Calendar.DAY_OF_MONTH, day);
		return calendar.getTime();

package demo.chart.other;

public class ChartItem {

	String label;
	String type;
	boolean threeD;
	public ChartItem(String label,String type, boolean threeD) {
		this.label = label;
		this.type = type;
		this.threeD = threeD;
	public String getLabel() {
		return label;
	public String getType() {
		return type;
	public boolean isThreeD() {
		return threeD;
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');