<?xml version="1.0" encoding="UTF-8"?>
<window apply="demo.bar.BarNegativeStackComposer">
<charts id="chart" type="bar"
title="Population pyramid for Andorra, 2023" />
</window>
package demo.bar;
import org.zkoss.chart.AxisAccessibility;
import org.zkoss.chart.Charts;
import org.zkoss.chart.XAxis;
import org.zkoss.chart.YAxis;
import org.zkoss.json.JavaScriptValue;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Window;
public class BarNegativeStackComposer extends SelectorComposer<Window> {
@Wire
Charts chart;
public void doAfterCompose(Window comp) throws Exception {
super.doAfterCompose(comp);
chart.setSubtitle("Source: <a " +
"href=\"https://countryeconomy.com/demography/population-structure/andorra\"" +
"target=\"_blank\">countryeconomy.com</a>");
chart.getAccessibility().getPoint().setValueDescriptionFormat("{index}. Age {xDescription}, {value}%.");
chart.setModel(BarNegativeStackData.getCategoryModel());
XAxis xAxis = chart.getXAxis();
xAxis.setReversed(false);
xAxis.getLabels().setStep(1);
xAxis.getAccessibility().setDescription("Age (male)");
// mirror axis on right side
XAxis minorAxis = chart.getXAxis(1);
minorAxis.setOpposite(true);
minorAxis.setReversed(false);
minorAxis.setLinkedTo(0);
minorAxis.getLabels().setStep(1);
minorAxis.getAccessibility().setDescription("Age (female)");
minorAxis.setCategories(BarNegativeStackData.getCategories());
YAxis yAxis = chart.getYAxis();
yAxis.setTitle("");
yAxis.getLabels().setFormatter(new JavaScriptValue("function() {return Math.abs(this.value) + '%';}"));
AxisAccessibility yAxisAccessibility = yAxis.getAccessibility();
yAxisAccessibility.setDescription("Percentage population");
yAxisAccessibility.setRangeDescription("Range: 0 to 5%");
chart.getPlotOptions().getSeries().setStacking("normal");
chart.getPlotOptions().getSeries().setBorderRadius("50%");
chart.getTooltip().setFormat("<b>{series.name}, age {point.category}</b><br/>" +
"Population: {(abs point.y):.1f}%");
}
}
package demo.bar;
import org.zkoss.chart.model.CategoryModel;
import org.zkoss.chart.model.DefaultCategoryModel;
public class BarNegativeStackData {
private static CategoryModel model;
static {
model = new DefaultCategoryModel();
model.setValue("Male", "0-4", -1.38);
model.setValue("Male", "5-9", -2.09);
model.setValue("Male", "10-14", -2.45);
model.setValue("Male", "15-19", -2.71);
model.setValue("Male", "20-24", -2.97);
model.setValue("Male", "25-29", -3.69);
model.setValue("Male", "30-34", -4.04);
model.setValue("Male", "35-40", -3.81);
model.setValue("Male", "40-45", -4.19);
model.setValue("Male", "45-49", -4.61);
model.setValue("Male", "50-54", -4.56);
model.setValue("Male", "55-59", -4.21);
model.setValue("Male", "60-64", -3.53);
model.setValue("Male", "65-69", -2.55);
model.setValue("Male", "70-74", -1.82);
model.setValue("Male", "75-79", -1.46);
model.setValue("Male", "80-84", -0.78);
model.setValue("Male", "80+", -0.71);
model.setValue("Female", "0-4", 1.35);
model.setValue("Female", "5-9", 1.98);
model.setValue("Female", "10-14", 2.43);
model.setValue("Female", "15-19", 2.39);
model.setValue("Female", "20-24", 2.71);
model.setValue("Female", "25-29", 3.02);
model.setValue("Female", "30-34", 3.50);
model.setValue("Female", "35-40", 3.52);
model.setValue("Female", "40-45", 4.03);
model.setValue("Female", "45-49", 4.40);
model.setValue("Female", "50-54", 4.17);
model.setValue("Female", "55-59", 3.88);
model.setValue("Female", "60-64", 3.29);
model.setValue("Female", "65-69", 2.42);
model.setValue("Female", "70-74", 1.80);
model.setValue("Female", "75-79", 1.39);
model.setValue("Female", "80-84", 0.99);
model.setValue("Female", "80+", 1.15);
}
public static CategoryModel getCategoryModel() {
return model;
}
public static String[] getCategories() {
return model.getCategories().toArray(new String[0]);
}
}