odoo/addons/web_graph/static/lib/flotr2/js/plugins/legend.js

180 lines
7.0 KiB
JavaScript

(function () {
var
D = Flotr.DOM,
_ = Flotr._;
Flotr.addPlugin('legend', {
options: {
show: true, // => setting to true will show the legend, hide otherwise
noColumns: 1, // => number of colums in legend table // @todo: doesn't work for HtmlText = false
labelFormatter: function(v){return v;}, // => fn: string -> string
labelBoxBorderColor: '#CCCCCC', // => border color for the little label boxes
labelBoxWidth: 14,
labelBoxHeight: 10,
labelBoxMargin: 5,
labelBoxOpacity: 0.4,
container: null, // => container (as jQuery object) to put legend in, null means default on top of graph
position: 'nw', // => position of default legend container within plot
margin: 5, // => distance from grid edge to default legend container within plot
backgroundColor: null, // => null means auto-detect
backgroundOpacity: 0.85// => set to 0 to avoid background, set to 1 for a solid background
},
callbacks: {
'flotr:afterinit': function() {
this.legend.insertLegend();
}
},
/**
* Adds a legend div to the canvas container or draws it on the canvas.
*/
insertLegend: function(){
if(!this.options.legend.show)
return;
var series = this.series,
plotOffset = this.plotOffset,
options = this.options,
legend = options.legend,
fragments = [],
rowStarted = false,
ctx = this.ctx,
itemCount = _.filter(series, function(s) {return (s.label && !s.hide);}).length,
p = legend.position,
m = legend.margin,
i, label, color;
if (itemCount) {
if (!options.HtmlText && this.textEnabled && !legend.container) {
var style = {
size: options.fontSize*1.1,
color: options.grid.color
};
var lbw = legend.labelBoxWidth,
lbh = legend.labelBoxHeight,
lbm = legend.labelBoxMargin,
offsetX = plotOffset.left + m,
offsetY = plotOffset.top + m;
// We calculate the labels' max width
var labelMaxWidth = 0;
for(i = series.length - 1; i > -1; --i){
if(!series[i].label || series[i].hide) continue;
label = legend.labelFormatter(series[i].label);
labelMaxWidth = Math.max(labelMaxWidth, this._text.measureText(label, style).width);
}
var legendWidth = Math.round(lbw + lbm*3 + labelMaxWidth),
legendHeight = Math.round(itemCount*(lbm+lbh) + lbm);
if(p.charAt(0) == 's') offsetY = plotOffset.top + this.plotHeight - (m + legendHeight);
if(p.charAt(1) == 'e') offsetX = plotOffset.left + this.plotWidth - (m + legendWidth);
// Legend box
color = this.processColor(legend.backgroundColor || 'rgb(240,240,240)', {opacity: legend.backgroundOpacity || 0.1});
ctx.fillStyle = color;
ctx.fillRect(offsetX, offsetY, legendWidth, legendHeight);
ctx.strokeStyle = legend.labelBoxBorderColor;
ctx.strokeRect(Flotr.toPixel(offsetX), Flotr.toPixel(offsetY), legendWidth, legendHeight);
// Legend labels
var x = offsetX + lbm;
var y = offsetY + lbm;
for(i = 0; i < series.length; i++){
if(!series[i].label || series[i].hide) continue;
label = legend.labelFormatter(series[i].label);
ctx.fillStyle = series[i].color;
ctx.fillRect(x, y, lbw-1, lbh-1);
ctx.strokeStyle = legend.labelBoxBorderColor;
ctx.lineWidth = 1;
ctx.strokeRect(Math.ceil(x)-1.5, Math.ceil(y)-1.5, lbw+2, lbh+2);
// Legend text
Flotr.drawText(ctx, label, x + lbw + lbm, y + lbh, style);
y += lbh + lbm;
}
}
else {
for(i = 0; i < series.length; ++i){
if(!series[i].label || series[i].hide) continue;
if(i % legend.noColumns === 0){
fragments.push(rowStarted ? '</tr><tr>' : '<tr>');
rowStarted = true;
}
// @TODO remove requirement on bars
var s = series[i],
boxWidth = legend.labelBoxWidth,
boxHeight = legend.labelBoxHeight,
opacityValue = (s.bars ? s.bars.fillOpacity : legend.labelBoxOpacity),
opacity = 'opacity:' + opacityValue + ';filter:alpha(opacity=' + opacityValue*100 + ');';
label = legend.labelFormatter(s.label);
color = 'background-color:' + ((s.bars && s.bars.show && s.bars.fillColor && s.bars.fill) ? s.bars.fillColor : s.color) + ';';
fragments.push(
'<td class="flotr-legend-color-box">',
'<div style="border:1px solid ', legend.labelBoxBorderColor, ';padding:1px">',
'<div style="width:', (boxWidth-1), 'px;height:', (boxHeight-1), 'px;border:1px solid ', series[i].color, '">', // Border
'<div style="width:', boxWidth, 'px;height:', boxHeight, 'px;', 'opacity:.4;', color, '"></div>', // Background
'</div>',
'</div>',
'</td>',
'<td class="flotr-legend-label">', label, '</td>'
);
}
if(rowStarted) fragments.push('</tr>');
if(fragments.length > 0){
var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join('') + '</table>';
if(legend.container){
D.insert(legend.container, table);
}
else {
var styles = {position: 'absolute', 'z-index': 2};
if(p.charAt(0) == 'n') { styles.top = (m + plotOffset.top) + 'px'; styles.bottom = 'auto'; }
else if(p.charAt(0) == 's') { styles.bottom = (m + plotOffset.bottom) + 'px'; styles.top = 'auto'; }
if(p.charAt(1) == 'e') { styles.right = (m + plotOffset.right) + 'px'; styles.left = 'auto'; }
else if(p.charAt(1) == 'w') { styles.left = (m + plotOffset.left) + 'px'; styles.right = 'auto'; }
var div = D.create('div'), size;
div.className = 'flotr-legend';
D.setStyles(div, styles);
D.insert(div, table);
D.insert(this.el, div);
if(!legend.backgroundOpacity)
return;
var c = legend.backgroundColor || options.grid.backgroundColor || '#ffffff';
_.extend(styles, D.size(div), {
'backgroundColor': c,
'z-index': 1
});
styles.width += 'px';
styles.height += 'px';
// Put in the transparent background separately to avoid blended labels and
div = D.create('div');
div.className = 'flotr-legend-bg';
D.setStyles(div, styles);
D.opacity(div, legend.backgroundOpacity);
D.insert(div, ' ');
D.insert(this.el, div);
}
}
}
}
}
});
})();