barchart.lzx
<library>
<include href="shared/basechart.lzx"/>
<include href="shared/databar.lzx"/>
<include href="shared/barchartbacking.lzx"/>
<class name="barchart" extends="basechart">
<attribute name="barspace" type="number" value="2
"/>
<attribute name="staggerticks" type="boolean" value="true
"/>
<attribute name="numbars" type="number" value="0
"/>
<attribute name="datadrawn" type="boolean" value="false
"/>
<attribute name="altmaximum" type="number" value="${this.drawaxis == 'y' ? this.maximum : 100}"/>
<attribute name="altminimum" type="number" value="${this.drawaxis == 'y' ? this.minimum : 0}"/>
<handler name="ondata">
if(this.adjusttodata == true){
//this.adjustToData();
}
this.dataclip.datapane.breakDown();
this.setAttribute('datadrawn', false);
this.setAttribute('rendercomplete', false);
this.chartbg.clearAll();
if(this.drawaxis == 'x'){
this.buildBarsVert();
this.chartbg.clearHTickLabels();
} else {
this.buildBarsHoriz();
this.chartbg.clearVTickLabels();
}
this.chartbg.renderAll();
if(this.findLegend() != null){
if(this.subnodes[this.findLegend()].legenddrawn != true){
this.subnodes[this.findLegend()].buildLegend();
}
}
</handler>
<event name="ondrawaxis"/>
<handler name="ondrawaxis">
this.dataclip.datapane.setAttribute('anicomplete', false);
this.ondata.sendEvent();
</handler>
<method name="buildBarsVert">
var snum = this.seriesnumber; // Number of dataseries.
var dnode = this.findData(); // Location of chartdata.
var barspace = this.barspace; // Space between bars.
var tickset = 0;
var xpos; // x location of bars, to be determined later.
var barviewwidth = scaledaltmax - scaledaltmin;
for(var j = 0; j < snum; j++){
var bl = this.subnodes[dnode].subviews[j];
if(bl.ydata != null &&
bl.dataenabled == true){
var ylength = bl.ydata.length;
var visbars = Math.abs(this.altmaximum) - Math.abs(this.altminimum);
this.setAttribute('barcount', visbars);
var barwidth = Math.round(barviewwidth / (ylength * snum)) -
barspace;
var xstartpos = (barviewwidth - (((barwidth + barspace) *
ylength) * snum) + barspace) / 2;
xpos = xstartpos + (barwidth * j) + (barspace * j);
this.setAttribute('numbars', snum * ylength);
for(var i = 0; i < ylength; i++){
var barheight = (bl.ydata[i] *
this.scaler) - (this.zerowidth / (2 * this.scaler));
var bvalue = bl.ydata[i];
var datacolor = bl.datacolor;
var dhover = bl.tooltip;
var aninit = bl.animationinit;
var dataopacity = bl.dataopacity;
var barrsc;
var bcolor;
if(bl.rscdata != null){
if(typeof bl.rscdata[i] !=
'undefined'){
barrsc = bl.rscdata[i];
} else {
barrsc = null;
}
} else {
barrsc = bl.dataresource;
}
if(bl.colordata != null){
if(typeof bl.colordata[i] !=
'undefined'){
bcolor = bl.colordata[i];
} else {
bcolor = null;
}
} else {
bcolor = bl.datacolor;
}
var yposit = this.dataclip.datapane.height -
this.height;
if(barheight < 0){
barheight = barheight * -1;
yposit = this.dataclip.datapane.height;
}
new databar(dataclip.datapane, {width:barwidth,
height:barheight, x:xpos, y:yposit,
realy:plotheight, bgcolor:bcolor,
tooltip:dhover, realx:xpos, animationinit:aninit,
stretches:"both", resource:barrsc, datalink:bl,
opacity:dataopacity, dataresource:barrsc, barnumber:i,
name:"bar"+j+i, drawaxis:this.drawaxis, barset:j,
siblingbars:snum * ylength, barspace:barspace,
totalsets:snum, bvalue:bvalue});
if(bl.labeldata != null){
var ltxtsize = bl.labeltextsize;
var lborder = bl.labelborder;
var lbwidth = bl.labelborderwidth;
var lbcolor = bl.labelcolor;
var ltcolor = bl.labeltextcolor;
var labelheight = 15;
var labelwidth = barwidth * 2;
if(bl.labeldata[i] != null){
var ltext = bl.labeldata[i];
var doanim = false;
if(aninit != ''){
doanim = true;
}
new label(dataclip.datapane, {height:labelheight,
x:xpos + (barwidth / 2), labelnumber:i,
bgcolor:lbcolor, name:"label"+j+i, fadein:doanim,
ltext:ltext, labelset:j,
ltextsize:ltxtsize, lborder:lborder,
lbwidth:lbwidth, ltcolor:ltcolor, datalink:bl,
drawaxis:this.drawaxis, charttype:"bar"});
}
}
if(this.rendercomplete != true){
if(bl.baselabels != null &&
typeof bl.baselabeldata[i] != 'undefined'){
var xtext = bl.baselabeldata[i];
var vtickunit = (barwidth + barspace) * i;
var basesetter = tickset * (barwidth + barspace) +
((snum * vtickunit) + (barwidth / 2) +
(xstartpos));
var loffset = 0;
var toffset = typeof toffset == 'undefined' ?
((tickset + 2) % 2 == 0 ? 0 : 14) : (toffset == 14 ? 0 : 14);
if(this.staggerticks == true){
if(snum > 1){
loffset = (tickset * 14);
} else {
loffset = toffset;
}
}
new ticklabel(chartbg.vtickclip.vtickpane,
{x:basesetter, ltext:xtext, y:plotheight,
fontsize:this.vticklabelsize, tickaxis:"x",
ltcolor:this.baselabels, datalink:bl,
ticklength:this.vticklength,
labelset:j, labelnumber:i, loffset:loffset,
labelangle:bl.baselabelangle});
}
}
xpos = xpos + (barspace * snum + (barwidth * snum));
}
}
if(bl.baselabels != null){
tickset++;
}
}
this.setAttribute('rendercomplete', true);
this.setAttribute('datadrawn', true);
this.dataclip.datapane.setAttribute('anicomplete', true);
</method>
<method name="buildBarsHoriz">
var snum = this.seriesnumber; // Number of dataseries.
var dnode = this.findData(); // Location of chartdata.
var barspace = this.barspace; // Space between bars.
var tickset = 0;
var ypos; // x location of bars, to be determined later.
var barviewwidth = scaledaltmax - scaledaltmin;
for(var j = 0; j < snum; j++){
var bl = this.subnodes[dnode].subviews[j];
if(bl.ydata != null &&
bl.dataenabled == true){
var xlength = bl.ydata.length;
var barwidth = Math.round(barviewwidth / (xlength * snum)) -
barspace;
var xstartpos = (barviewwidth - (((barwidth + barspace) *
xlength) * snum) + barspace) / 2;
ypos = xstartpos + (barwidth * j) + (barspace * j);
this.setAttribute('numbars', snum * xlength);
for(var i = 0; i < xlength; i++){
var barheight = Math.abs(bl.ydata[i] *
this.altscaler) - (this.zerowidth / (2 * this.altscaler));
var bvalue = bl.ydata[i];
var datacolor = bl.datacolor;
var dhover = bl.tooltip;
var aninit = bl.animationinit;
var dataopacity = bl.dataopacity;
var barrsc;
if(bl.rscdata != null){
if(typeof bl.rscdata[i] !=
'undefined'){
barrsc = bl.rscdata[i];
} else {
barrsc = null;
}
} else {
barrsc = bl.dataresource;
}
if(bl.colordata != null){
if(typeof bl.colordata[i] !=
'undefined'){
bcolor = bl.colordata[i];
} else {
bcolor = null;
}
} else {
bcolor = bl.datacolor;
}
var yposit = plotheight - barheight;
new databar(dataclip.datapane, {width:barheight,
height:barwidth, y:ypos,
realy:ypos, bgcolor:bcolor, datalink:bl,
tooltip:dhover, totalsets:snum,
animationinit:aninit, drawaxis:this.drawaxis,
stretches:"both", resource:barrsc, barnumber:i,
opacity:dataopacity, dataresource:barrsc, barset:j,
name:"bar"+j+i, siblingbars:snum * xlength,
barspace:barspace, bvalue:bvalue});
if(bl.labeldata != null){
var ltxtsize = bl.labeltextsize;
var lborder = bl.labelborder;
var lbwidth = bl.labelborderwidth;
var lbcolor = bl.labelcolor;
var ltcolor = bl.labeltextcolor;
var labelheight = 15;
var labelwidth = barwidth * 2;
if(bl.labeldata[i] != null){
var ltext = bl.labeldata[i];
var doanim = false;
if(aninit != ''){
doanim = true;
}
new label(dataclip.datapane, {height:labelheight,
y:ypos + (barwidth / 2), datalink:bl,
x:barheight + labelwidth + 4,
bgcolor:lbcolor, name:"label"+j+i, fadein:doanim,
ltext:ltext, labelnumber:i, labelset:j,
ltextsize:ltxtsize, lborder:lborder,
lbwidth:lbwidth, ltcolor:ltcolor,
drawaxis:this.drawaxis, charttype:"bar"});
}
}
if(this.rendercomplete != true){
if(bl.baselabels != null &&
typeof bl.baselabeldata[i] != 'undefined'){
var xtext = bl.baselabeldata[i];
var htickunit = (barwidth + barspace) * i;
var basesetter = tickset * (barwidth + barspace) +
((snum * htickunit) + (barwidth / 2) +
(xstartpos));
var loffset = 0;
var toffset = typeof toffset == 'undefined' ?
((tickset + 2) % 2 == 0 ? 0 : this.vticklength) :
(toffset == this.vticklength ? 0 : this.vticklength);
if(this.staggerticks == true){
if(snum > 1){
loffset = (tickset * this.vticklength);
} else {
loffset = toffset;
}
}
new ticklabel(chartbg.htickclip.htickpane,
{x:chartbg.htickclip.htickpane.width, ltext:xtext,
y:basesetter, fontsize:this.vticklabelsize,
tickaxis:"y", ltcolor:this.baselabels, datalink:bl,
ticklength:this.vticklength,
labelset:j, labelnumber:i,
loffset:loffset, labelangle:bl.baselabelangle});
}
}
ypos = ypos + (barspace * snum + (barwidth * snum));
}
}
if(bl.baselabels != null){
tickset++;
}
}
this.setAttribute('rendercomplete', true);
this.setAttribute('datadrawn', true);
this.dataclip.datapane.setAttribute('anicomplete', true);
</method>
<chartbacking name="chartbg" width="${parent.plotwidth}" height="${parent.plotheight}" x="${parent.plotx}" y="${parent.ploty}"/>
<view name="dataclip" width="$once{parent.plotwidth - (parent.borderwidth * 2)}" height="$once{parent.plotheight - (parent.borderwidth * 2)}" x="$once{parent.plotx + parent.borderwidth + 1}" y="$once{parent.ploty + parent.borderwidth}" clip="true">
<view name="datapane" x="${parent.parent.paneslider}" y="${parent.parent.altslider}" width="${parent.parent.scaledaltmax - parent.parent.scaledaltmin}" height="${parent.parent.scaledmax - parent.parent.scaledmin}">
<attribute name="anicomplete" type="boolean" value="false
"/>
<handler name="onmousedown">
if(parent.parent.draggable){
dragger.setAttribute('applied', true);
}
</handler>
<handler name="onmouseup">
if(parent.parent.draggable){
dragger.setAttribute('applied', false);
}
</handler>
<method name="breakDown">
var killviews = 0;
for(var i = 0; i <= this.subviews.length; i++){
if(this.subviews[i] instanceof lz.databar ||
this.subviews[i] instanceof lz.label){
killviews++;
}
}
var remainviews = this.subviews.length - killviews;
while(this.subviews.length != remainviews){
for(var j = 0; j <= this.subviews.length; j++){
if(this.subviews[j] instanceof lz.databar ||
this.subviews[j] instanceof lz.label){
this.subviews[j].destroy();
}
}
}
</method>
<dragstate name="dragger" drag_axis="both" drag_min_x="${parent.width - this.width + 2}" drag_max_x="0" drag_min_y="${parent.height - this.height + 2}" drag_max_y="0"/>
</view>
</view>
<chartzoomer name="datazoom"/>
<doc>
<tag name="shortdesc">
<text>
The barchart class draws data in bars using the
information in the child dataseries object(s).
</text>
</tag>
<text>
<p>This is an example of a simple barchart with minimal customization. By
specifying additional attributes, one can exercise much greater control over
the visual appearance of the chart. (See: /test/charting/ for more detailed
examples.)</p>
<example title="Simple barchart">
<canvas width="600" height="500">
<dataset name="dset" request="true" src="resources/barchart_data_02.xml"/>
<barchart name="testchart" width="500" height="400" datapath="dset:/">
<chartdata>
<dataseries ydatapath="salesdata/fy2005/month/@amount"
datacolor="0xAABBDD" label="salesdata/fy2005/month/@amount"/>
<dataseries ydatapath="salesdata/fy2006/month/@amount"
label="salesdata/fy2006/month/@amount" datacolor="salesdata/fy2006/month/@color"/>
</chartdata>
</barchart>
</canvas>
</example>
</text>
</doc>
</class>
</library>
Cross References
Includes
Classes
- <class name="barchart" extends="basechart">