7
Flotr.addPlugin('legend', {
9
show: true, // => setting to true will show the legend, hide otherwise
10
noColumns: 1, // => number of colums in legend table // @todo: doesn't work for HtmlText = false
11
labelFormatter: function(v){return v;}, // => fn: string -> string
12
labelBoxBorderColor: '#CCCCCC', // => border color for the little label boxes
17
container: null, // => container (as jQuery object) to put legend in, null means default on top of graph
18
position: 'nw', // => position of default legend container within plot
19
margin: 5, // => distance from grid edge to default legend container within plot
20
backgroundColor: null, // => null means auto-detect
21
backgroundOpacity: 0.85// => set to 0 to avoid background, set to 1 for a solid background
24
'flotr:afterinit': function() {
25
this.legend.insertLegend();
29
* Adds a legend div to the canvas container or draws it on the canvas.
31
insertLegend: function(){
33
if(!this.options.legend.show)
36
var series = this.series,
37
plotOffset = this.plotOffset,
38
options = this.options,
39
legend = options.legend,
43
itemCount = _.filter(series, function(s) {return (s.label && !s.hide);}).length,
49
if (!options.HtmlText && this.textEnabled && !legend.container) {
51
size: options.fontSize*1.1,
52
color: options.grid.color
55
var lbw = legend.labelBoxWidth,
56
lbh = legend.labelBoxHeight,
57
lbm = legend.labelBoxMargin,
58
offsetX = plotOffset.left + m,
59
offsetY = plotOffset.top + m;
61
// We calculate the labels' max width
62
var labelMaxWidth = 0;
63
for(i = series.length - 1; i > -1; --i){
64
if(!series[i].label || series[i].hide) continue;
65
label = legend.labelFormatter(series[i].label);
66
labelMaxWidth = Math.max(labelMaxWidth, this._text.measureText(label, style).width);
69
var legendWidth = Math.round(lbw + lbm*3 + labelMaxWidth),
70
legendHeight = Math.round(itemCount*(lbm+lbh) + lbm);
72
if(p.charAt(0) == 's') offsetY = plotOffset.top + this.plotHeight - (m + legendHeight);
73
if(p.charAt(1) == 'e') offsetX = plotOffset.left + this.plotWidth - (m + legendWidth);
76
color = this.processColor(legend.backgroundColor || 'rgb(240,240,240)', {opacity: legend.backgroundOpacity || 0.1});
78
ctx.fillStyle = color;
79
ctx.fillRect(offsetX, offsetY, legendWidth, legendHeight);
80
ctx.strokeStyle = legend.labelBoxBorderColor;
81
ctx.strokeRect(Flotr.toPixel(offsetX), Flotr.toPixel(offsetY), legendWidth, legendHeight);
84
var x = offsetX + lbm;
85
var y = offsetY + lbm;
86
for(i = 0; i < series.length; i++){
87
if(!series[i].label || series[i].hide) continue;
88
label = legend.labelFormatter(series[i].label);
90
ctx.fillStyle = series[i].color;
91
ctx.fillRect(x, y, lbw-1, lbh-1);
93
ctx.strokeStyle = legend.labelBoxBorderColor;
95
ctx.strokeRect(Math.ceil(x)-1.5, Math.ceil(y)-1.5, lbw+2, lbh+2);
98
Flotr.drawText(ctx, label, x + lbw + lbm, y + lbh, style);
104
for(i = 0; i < series.length; ++i){
105
if(!series[i].label || series[i].hide) continue;
107
if(i % legend.noColumns === 0){
108
fragments.push(rowStarted ? '</tr><tr>' : '<tr>');
112
// @TODO remove requirement on bars
114
boxWidth = legend.labelBoxWidth,
115
boxHeight = legend.labelBoxHeight,
116
opacityValue = (s.bars ? s.bars.fillOpacity : legend.labelBoxOpacity),
117
opacity = 'opacity:' + opacityValue + ';filter:alpha(opacity=' + opacityValue*100 + ');';
119
label = legend.labelFormatter(s.label);
120
color = 'background-color:' + ((s.bars && s.bars.show && s.bars.fillColor && s.bars.fill) ? s.bars.fillColor : s.color) + ';';
123
'<td class="flotr-legend-color-box">',
124
'<div style="border:1px solid ', legend.labelBoxBorderColor, ';padding:1px">',
125
'<div style="width:', (boxWidth-1), 'px;height:', (boxHeight-1), 'px;border:1px solid ', series[i].color, '">', // Border
126
'<div style="width:', boxWidth, 'px;height:', boxHeight, 'px;', 'opacity:.4;', color, '"></div>', // Background
130
'<td class="flotr-legend-label">', label, '</td>'
133
if(rowStarted) fragments.push('</tr>');
135
if(fragments.length > 0){
136
var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join('') + '</table>';
137
if(legend.container){
138
D.insert(legend.container, table);
141
var styles = {position: 'absolute', 'z-index': 2};
143
if(p.charAt(0) == 'n') { styles.top = (m + plotOffset.top) + 'px'; styles.bottom = 'auto'; }
144
else if(p.charAt(0) == 's') { styles.bottom = (m + plotOffset.bottom) + 'px'; styles.top = 'auto'; }
145
if(p.charAt(1) == 'e') { styles.right = (m + plotOffset.right) + 'px'; styles.left = 'auto'; }
146
else if(p.charAt(1) == 'w') { styles.left = (m + plotOffset.left) + 'px'; styles.right = 'auto'; }
148
var div = D.create('div'), size;
149
div.className = 'flotr-legend';
150
D.setStyles(div, styles);
151
D.insert(div, table);
152
D.insert(this.el, div);
154
if(!legend.backgroundOpacity)
157
var c = legend.backgroundColor || options.grid.backgroundColor || '#ffffff';
159
_.extend(styles, D.size(div), {
160
'backgroundColor': c,
163
styles.width += 'px';
164
styles.height += 'px';
166
// Put in the transparent background separately to avoid blended labels and
167
div = D.create('div');
168
div.className = 'flotr-legend-bg';
169
D.setStyles(div, styles);
170
D.opacity(div, legend.backgroundOpacity);
172
D.insert(this.el, div);