legend.lzx
<library>
<include href="extensions/drawview.lzx"/>
<include href="utils/layouts/wrappinglayout.lzx"/>
<class name="chartlegend" extends="drawview">
<attribute name="border" type="color" value="$once{null}"/>
<attribute name="borderwidth" type="number" value="1
"/>
<attribute name="backcolor" type="color" value="$once{null}"/>
<attribute name="hlcolor" type="color" value="$once{null}"/>
<attribute name="ltitle" type="string" value="$once{null}"/>
<attribute name="resizetodata" type="string" value="$once{null}"/>
<attribute name="textsize" type="number" value="10
"/>
<attribute name="titletextsize" type="number" value="12
"/>
<attribute name="titleposition" type="string" value="left
"/>
<attribute name="textcolor" type="color" value="#000000
"/>
<attribute name="titlecolor" type="color" value="#000000
"/>
<attribute name="charttype" type="string" value="$once{typeof linechart != 'undefined' ? (parent instanceof lz.linechart ? 'line' : null) : null}"/>
<attribute name="posit" type="string" value="right
"/>
<attribute name="piepieces" value="$once{[]}"/>
<attribute name="piececolors" value="$once{[]}"/>
<attribute name="pieradius" type="number" value="0
"/>
<attribute name="centerx" type="number" value="0
"/>
<attribute name="centery" type="number" value="0
"/>
<attribute name="legendvalues" value="$once{[]}"/>
<attribute name="itemnums" type="number" value="0
"/>
<attribute name="legendx" type="number" value="0
"/>
<attribute name="legendy" type="number" value="0
"/>
<attribute name="legendwidth" type="number" value="0
"/>
<attribute name="legendheight" type="number" value="0
"/>
<attribute name="legenddrawn" type="boolean" value="false
"/>
<handler name="oncontext">
if(this.charttype == 'pie'){
this.buildPieLegend();
}
</handler>
<method name="buildPieLegend">
if(this.posit == 'top'){
ctrx = this.width / 2;
ctry = this.height / 2 + (this.height * .1);
} else if(this.posit == 'bottom'){
ctrx = this.width / 2;
ctry = this.height / 2 - (this.height * .1);
} else if(this.posit == 'left'){
ctrx = this.width / 2 + (this.width * .1);
ctry = this.height / 2;
} else if(this.posit == 'right'){
ctrx = this.width / 2 - (this.width * .1);
ctry = this.height / 2;
} else if(this.posit == 'manualtop'){
} else if(this.posit == 'manualbottom'){
} else if(this.posit == 'manualleft'){
} else if(this.posit == 'manualright'){
}
var twidth;
var theight;
if(this.posit == 'top' || this.posit == 'bottom'){
var numrows = Math.floor(Math.sqrt(this.itemnums));
if(numrows > 1){
numrows = numrows - 1;
}
var numcols = Math.ceil(this.itemnums / numrows);
var litemwidth = parent.expanded ? 80 : 30;
var litemheight = parent.expanded ? 14 : 8;
if(this.ltitle != null){
new lz.legendtitle(this, {name:'legendtitle', ltitle:this.ltitle, tposit:this.titleposition,
ttsize:(parent.expanded ? this.titletextsize : 10), tcolor:this.titlecolor});
}
this.setAttribute('width', litemwidth * numcols);
this.setAttribute('height', litemheight * numrows + (this.ltitle != null ? this.legendtitle.height : 0));
this.setAttribute('x', (parent.width - this.width) / 2);
if(this.posit == 'bottom'){
this.setAttribute('y', (this.centery + this.pieradius) +
(parent.height - this.centery - this.pieradius - this.height) / 2);
} else {
this.setAttribute('y', (this.centery - this.pieradius - this.height) / 2);
}
} else if(this.posit == 'left' || this.posit == 'right') {
var numcols = Math.floor(Math.sqrt(this.itemnums));
if(numcols > 1){
numcols = numcols - 1;
}
var numrows = Math.ceil(this.itemnums / numcols);
var litemwidth = parent.expanded ? 80 : 30;
var litemheight = parent.expanded ? 14 : 8;
if(this.ltitle != null){
new lz.legendtitle(this, {name:'legendtitle', ltitle:this.ltitle, tposit:this.titleposition,
ttsize:(parent.expanded ? this.titletextsize : 10), tcolor:this.titlecolor});
}
this.setAttribute('width', litemwidth * numcols);
this.setAttribute('height', litemheight * numrows + (this.ltitle != null ? this.legendtitle.height : 0));
if(this.posit == 'left'){
this.setAttribute('x', (this.centerx - this.pieradius - this.width) / 2);
this.setAttribute('y', (parent.height - this.height) / 2);
} else {
this.setAttribute('x', (this.centerx + this.pieradius) +
(parent.width - this.centerx - this.pieradius - this.width) / 2);
this.setAttribute('y', (parent.height - this.height) / 2);
}
} else {
this.setAttribute('width', this.legendwidth);
this.setAttribute('height', this.legendheight);
this.setAttribute('x', this.legendx);
this.setAttribute('y', this.legendy);
if(this.width / 4 > this.height){
var numrows = Math.floor(Math.sqrt(this.itemnums));
if(numrows > 1){
numrows = numrows - 1;
}
var numcols = Math.ceil(this.itemnums / numrows);
} else {
var numcols = Math.floor(Math.sqrt(this.itemnums));
if(numcols > 1){
numcols = numcols - 1;
}
var numrows = Math.ceil(this.itemnums / numcols);
}
if(this.ltitle != null){
new lz.legendtitle(this, {name:'legendtitle', ltitle:this.ltitle, tposit:this.titleposition,
ttsize:(parent.expanded ? this.titletextsize : 10), tcolor:this.titlecolor});
}
var litemwidth = (this.width / numcols);
var litemheight = (this.height / numrows);
}
for(var i = 0; i < this.piepieces.length; i++){
var pclink = this.piepieces[i];
new lz.legenditem(this, {itemvalue:parent[pclink]['piecevalue'],
lpiece:this.piepieces[i], width:litemwidth,
hlcolor:(this.hlcolor == null ? this.backcolor : this.hlcolor),
height:litemheight, iconcolor:this.piececolors[i],
itemlabel:this.legendvalues[i], iconshape:'triangle'});
}
this.fillStyle = this.backcolor;
this.strokeStyle = this.border;
this.lineWidth = this.borderwidth;
this.beginPath();
this.moveTo(-this.borderwidth,-this.borderwidth);
this.lineTo(this.width, -this.borderwidth);
this.lineTo(this.width, this.height);
this.lineTo(-this.borderwidth, this.height);
this.lineTo(-this.borderwidth,-this.borderwidth);
this.closePath();
if(this.backcolor != null){
this.fill();
}
if(this.border != null && this.borderwidth != 0){
this.stroke();
}
</method>
<method name="buildLegend">
var dloc = parent.findData();
var dnum = parent.subnodes[dloc].subviews.length;
var iconcolor = null;
var itemlabel = null;
var itemcount = 0;
// Calculate the legend item size.
for(var i = 0; i < dnum; i++){
var ll = parent.subnodes[dloc].subviews[i];
if(ll.legenddata != null &&
typeof ll.legenddata != 'undefined'){
itemcount++;
}
}
if(this.resizetodata == null){
if(this.width / 4 > this.height){
var numrows = Math.floor(Math.sqrt(itemcount));
if(numrows > 1){
numrows = numrows - 1;
}
var numcols = Math.ceil(itemcount / numrows);
} else {
var numcols = Math.floor(Math.sqrt(itemcount));
if(numcols > 1){
numcols = numcols - 1;
}
var numrows = Math.ceil(itemcount / numcols);
}
if(this.ltitle != null){
numrows = numrows + 1;
}
var litemwidth = (this.width / numcols);
var litemheight = (this.height / numrows);
if(this.ltitle != null){
new lz.legendtitle(this, {name:'legendtitle', ltitle:this.ltitle, tposit:this.titleposition,
ttsize:this.titletextsize, tcolor:this.titlecolor});
}
// Create legend items.
for(var i = 0; i < dnum; i++){
var ll = parent.subnodes[dloc].subviews[i];
if(this.charttype == 'line'){
if(ll.lvdata != null &&
typeof ll.lvdata[0] != 'undefined'){
iconcolor = ll.lvdata[0];
} else {
iconcolor = ll.linesvisible;
}
} else if(ll.colordata != null &&
typeof ll.colordata[0] != 'undefined'){
iconcolor = ll.colordata[0];
} else {
iconcolor = ll.datacolor;
}
if(iconcolor.indexOf('x') != -1){
iconcolor = '#' + iconcolor.substring(iconcolor.indexOf('x')+1);
}
if(ll.legenddata != null &&
typeof ll.legenddata != 'undefined'){
itemlabel = ll.legenddata;
} else {
//itemlabel = ll.legenddatapath;
}
if(itemlabel != null){
new lz.legenditem(this, {itemvalue:itemlabel,
width:litemwidth, height:litemheight, dlink:ll,
hlcolor:(this.hlcolor == null ? this.backcolor : this.hlcolor),
height:this.height, iconcolor:iconcolor, textcolor:this.textcolor,
textsize:this.textsize, itemlabel:itemlabel, iconshape:'square'});
}
}
} else if(this.resizetodata == 'wide'){
var numrows = Math.floor(Math.sqrt(itemcount));
if(numrows > 1){
numrows = numrows - 1;
}
var numcols = Math.ceil(itemcount / numrows);
var litemwidth = 80;
var litemheight = 14;
if(this.ltitle != null){
new lz.legendtitle(this, {name:'legendtitle', ltitle:this.ltitle, tposit:this.titleposition,
ttsize:this.titletextsize, tcolor:this.titlecolor});
}
this.setAttribute('width', litemwidth * numcols);
this.setAttribute('height', litemheight * numrows + (this.ltitle != null ? this.legendtitle.height : 0));
// Create legend items.
for(var i = 0; i < dnum; i++){
var ll = parent.subnodes[dloc].subviews[i];
if(this.charttype == 'line'){
if(ll.lvdata != null &&
typeof ll.lvdata[0] != 'undefined'){
iconcolor = ll.lvdata[0];
} else {
iconcolor = ll.linesvisible;
}
} else if(ll.colordata != null &&
typeof ll.colordata[0] != 'undefined'){
iconcolor = ll.colordata[0];
} else {
iconcolor = ll.datacolor;
}
if(iconcolor.indexOf('x') != -1){
iconcolor = '#' + iconcolor.substring(iconcolor.indexOf('x')+1);
}
if(ll.legenddata != null &&
typeof ll.legenddata != 'undefined'){
itemlabel = ll.legenddata;
} else {
//itemlabel = ll.legenddatapath;
}
if(itemlabel != null){
new lz.legenditem(this, {itemvalue:itemlabel,
width:litemwidth, height:litemheight, dlink:ll,
hlcolor:(this.hlcolor == null ? this.backcolor : this.hlcolor),
height:this.height, iconcolor:iconcolor, textcolor:this.textcolor,
textsize:this.textsize, itemlabel:itemlabel, iconshape:'square'});
}
}
} else if(this.resizetodata == 'tall'){
var numcols = Math.floor(Math.sqrt(itemcount));
if(numcols > 1){
numcols = numcols - 1;
}
var numrows = Math.ceil(itemcount / numcols);
var litemwidth = 80;
var litemheight = 14;
if(this.ltitle != null){
new lz.legendtitle(this, {name:'legendtitle', ltitle:this.ltitle, tposit:this.titleposition,
ttsize:this.titletextsize, tcolor:this.titlecolor});
}
this.setAttribute('width', litemwidth * numcols);
this.setAttribute('height', litemheight * numrows + (this.ltitle != null ? this.legendtitle.height : 0));
// Create legend items.
for(var i = 0; i < dnum; i++){
var ll = parent.subnodes[dloc].subviews[i];
if(this.charttype == 'line'){
if(ll.lvdata != null &&
typeof ll.lvdata[0] != 'undefined'){
iconcolor = ll.lvdata[0];
} else {
iconcolor = ll.linesvisible;
}
} else if(ll.colordata != null &&
typeof ll.colordata[0] != 'undefined'){
iconcolor = ll.colordata[0];
} else {
iconcolor = ll.datacolor;
}
if(iconcolor.indexOf('x') != -1){
iconcolor = '#' + iconcolor.substring(iconcolor.indexOf('x')+1);
}
if(ll.legenddata != null &&
typeof ll.legenddata != 'undefined'){
itemlabel = ll.legenddata;
} else {
//itemlabel = ll.legenddatapath;
}
if(itemlabel != null){
new lz.legenditem(this, {itemvalue:itemlabel,
width:litemwidth, height:litemheight, dlink:ll,
hlcolor:(this.hlcolor == null ? this.backcolor : this.hlcolor),
height:this.height, iconcolor:iconcolor, textcolor:this.textcolor,
textsize:this.textsize, itemlabel:itemlabel, iconshape:'square'});
}
}
}
this.fillStyle = this.backcolor;
this.strokeStyle = this.border;
this.lineWidth = this.borderwidth;
this.beginPath();
this.moveTo(-this.borderwidth,-this.borderwidth);
this.lineTo(this.width, -this.borderwidth);
this.lineTo(this.width, this.height);
this.lineTo(-this.borderwidth, this.height);
this.lineTo(-this.borderwidth,-this.borderwidth);
this.closePath();
if(this.backcolor != null){
this.fill();
}
if(this.border != null && this.borderwidth != 0){
this.stroke();
}
this.setAttribute('legenddrawn', true);
</method>
<method name="updateLegend">
var dloc = parent.findData();
var snum = parent.subnodes[dloc].subviews.length;
</method>
<wrappinglayout spacing="0"/>
<doc>
<tag name="shortdesc">
<text>
(See barchart, linechart, or piechart for an example.)
</text>
</tag>
</doc>
</class>
<class name="legenditem" extends="view">
<attribute name="itemvalue" type="string" value="$once{null}"/>
<attribute name="iconcolor" type="color" value="$once{null}"/>
<attribute name="textcolor" type="color" value="$once{null}"/>
<attribute name="textsize" type="number" value="$once{null}"/>
<attribute name="iconshape" type="string" value="$once{null}"/>
<attribute name="hlcolor" type="color" value="$once{null}"/>
<attribute name="itemlabel" type="string" value="$once{null}"/>
<attribute name="dlink" value="$once{null}"/>
<attribute name="lpiece" value="$once{null}"/>
<handler name="oninit">
if(this.itemlabel != null){
this.ltext.setAttribute('text', itemlabel);
} else {
this.ltext.setAttribute('text', itemvalue);
}
</handler>
<handler name="onmouseover">
this.setAttribute('bgcolor', this.hlcolor);
if(parent.charttype == 'pie'){
parent.parent[this.lpiece].setAttribute('exploded', true);
}
</handler>
<handler name="onmouseout">
this.setAttribute('bgcolor', parent.backcolor);
if(parent.charttype == 'pie'){
parent.parent[this.lpiece].setAttribute('exploded', false);
}
</handler>
<handler name="onclick">
if(parent.charttype != "pie"){
this.dlink.setAttribute('dataenabled', !this.dlink.dataenabled);
}
if(parent.charttype == "line"){
parent.parent.ondata.sendEvent();
}
</handler>
<drawview name="licon">
<handler name="oncontext">
this.fillStyle = parent.iconcolor;
this.beginPath();
if(parent.iconshape == 'triangle'){
this.moveTo(2, 2);
this.lineTo(parent.height - 2, parent.height - 2);
this.lineTo(2, parent.height - 2);
this.lineTo(2, 2);
}
if(parent.iconshape == 'square'){
this.moveTo(2, 2);
this.lineTo(parent.height - 2, 2);
this.lineTo(parent.height - 2, parent.height - 2);
this.lineTo(2, parent.height - 2);
this.lineTo(2, 2);
}
this.closePath();
this.fill();
this.stroke();
</handler>
</drawview>
<text name="ltext" x="${parent.height + 2}" fgcolor="${parent.textcolor}" fontsize="${parent.textsize != null ? parent.textsize : (parent.height < 10 ? 7 : 10)}"/>
<doc>
<tag name="shortdesc">
<text>
(See barchart, linechart, or piechart for an example.)
</text>
</tag>
</doc>
</class>
<class name="legendtitle" width="${parent.width}" height="${typeof this.tt != 'undefined' ? this.tt.height + 4 : 16}">
<attribute name="ltitle" type="string" value="$once{null}"/>
<attribute name="ttsize" type="string" value="10
"/>
<attribute name="tcolor" type="color" value="$once{null}"/>
<attribute name="tposit" type="string" value="left
"/>
<text name="tt" fontstyle="bold" text="${parent.ltitle}" fontsize="${parent.ttsize}" fgcolor="${parent.tcolor}" x="${parent.tposit == 'left' ? 0 : (parent.tposit == 'right' ? (parent.width - this.width - 4) : (parent.width - this.width) / 2)}"/>
<doc>
<tag name="shortdesc">
<text>
(See barchart, linechart, or piechart for an example.)
</text>
</tag>
</doc>
</class>
</library>
Cross References
Includes
Classes