2 * g.Raphael 0.5 - Charting library, based on Raphaƫl
4 * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
5 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
7 imports = typeof(imports) == 'undefined' ? false : imports;
8 Raphael = typeof(Raphael) != 'undefined' ? Raphael : (imports ? imports.seed.Raphael.Raphael : {});
9 Roo = typeof(Roo) != 'undefined' ? Roo: (imports ? imports.seed.Roo.Roo: {});
14 * Create a vertical chart
15 * support left axis with interval
17 * @param {Raphael} paper to draw on
18 * @param {int} width - width of the chart
19 * @param {int} height - height of the chart
20 * @param {Array} values
21 * @param {Object} opts options
22 * background (string) : background color
23 * colors (array) : colors of the bars
24 * labelfont (string) : font family of bar labels
25 * labelfontsize (number) : font size of bar labels
26 * labelfontweight (string) (number) : font weight of bar labels
27 * labelfontcolors (array) : font colors of bar labels
28 * gutter (string) (number) : height of gutters in terms of percentage of bar height (e.g. '20%' : height raito of a bar to a gutter is 10 to 2)
29 * axis (string) : composed of 4 '0' / '1' separated by space (indicated whether top / right / bottom / left axis should be shown)
30 * (e.g. '0 0 1 1' indicates that the bottom and the left axis should be shown)
31 * leftaxiswidth (number) : width of left axis area
32 * leftaxisstep (number) : number of steps in left axis
33 * leftaxisfontsize (number) : font size of labels in left axis
34 * axisfont (string) : font family of labels in axes
35 * axisfontweight (string) (number) : font weight of labels in axes
36 * axisfontcolor (string) : font color of labels in axes
37 * legend (array) : legend
38 * legendkeyshape (string) : shape of the legend keys ('circle' / 'rect')
39 * legendkeysize (number) : size of the legend keys (diameter for 'circle' and width for 'rect')
40 * legendfont (string) : font family of the legend labels
41 * legendfontsize (number) : font size of the legend labels
42 * legendfontcolor (string) : font color of the legend colors
43 * lineheight (number) : distance between two legend labels
46 function MVBarchart(paper, width, height, values, opts) {
52 max = opts.max ? opts.max : (values.length == 0 ? 0 : Math.max(...values)),
53 background = opts.background || '#FFFFFF',
54 colors = opts.colors || chartinst.colors,
55 labelFont = opts.labelfont || 'Work Sans',
56 labelFontSize = opts.labelfontsize || 16,
57 labelFontWeight = opts.labelfontweight || 'bold',
58 labelFontColors = opts.labelfontcolors || [],
59 gutter = parseFloat(opts.gutter || "20%"),
60 axis = opts.axis || "0 0 0 0",
61 ax = (axis + "").split(/[,\s]+/),
63 leftAxisStep = opts.leftaxisstep || 10;
64 leftAxisFontSize = opts.leftaxisfontsize || 12,
65 axisFont = opts.axisfont || 'Work Sans',
66 axisFontWeight = opts.axisfontweight || 'normal',
67 axisFontColor = opts.axisfontcolor || '#323232';
69 bottomPadding = 120; // for legends
73 leftAxisWidth = opts.leftaxiswidth || 50;
74 max = Math.ceil(max / leftAxisStep) * leftAxisStep;
77 var step = max / leftAxisStep;
86 max = Math.ceil(step / factor) * factor * leftAxisStep;
88 if(labelFontColors.length < len) {
89 for(var i = labelFontColors.length; i < len; i++) {
90 labelFontColors.push('#323232');
95 paper.rect(0, 0, width, height).attr({ stroke: "none", fill: background });
97 var barWidth = (width - leftAxisWidth) / (len * (100 + gutter) + gutter) * 100;
98 var barHeight = (height - topPadding - bottomPadding); // maximum height of bar
99 var barGutter = barWidth * (gutter / 100);
102 var unit = barHeight / max;
109 height - bottomPadding,
123 values.forEach(function(v,k) {
128 paper.rect(leftAxisWidth + barGutter + (k * (barWidth + barGutter)), topPadding + barHeight - v * unit, barWidth, v * unit).attr({stroke: "none", fill: colors[k]});
131 // 4 pixels away from top of the bar
132 // align bar label in the center
133 paper.text(leftAxisWidth + barGutter + (k * (barWidth + barGutter)) + barWidth / 2, topPadding + barHeight - v * unit - 4 - labelFontSize / 2, Roo.util.Format.number(v, 0)).attr({
134 "font-size": labelFontSize,
135 "font-family": labelFont,
136 "font-weight": labelFontWeight,
137 "text-anchor": 'middle',
138 fill : labelFontColors[k]
143 chartinst.legend(paper, opts, values, len, height, bottomPadding);
150 var F = function() {};
151 F.prototype = Raphael.g;
152 MVBarchart.prototype = new F;
154 Raphael.fn.mvbarchart = function(width, height, values, opts) {
155 return new MVBarchart(this, width, height, values, opts);
159 MVBarchart.prototype.leftAxis = function (paper, x, y, width, length, max, steps, axisWidth, axisFont, axisFontSize, axisFontWeight, axisFontColor)
161 var path = ["M", x, y, "l", 0, length],
162 d = Math.ceil(max / steps),
166 for(var i = 0; i <= steps; i++) {
167 // 0 pixels away from the left of the graph
168 paper.text(0, y - i * dl, Roo.util.Format.number(Math.round(i * d), 0)).attr({
169 "font-size": axisFontSize,
170 "font-family": axisFont,
171 "font-weight": axisFontWeight,
172 "text-anchor": 'start',
176 // left axis interval
177 paper.path(["M", x, y - i * dl, "l", width - x, 0]).attr({ stroke: '#9E9E9E', "stroke-width": 1 });
180 paper.path(path).attr({ stroke: '#000', "stroke-width": 0 }); // default no axis
184 MVBarchart.prototype.legend = function (paper, opts, values, len, height, bottomPadding)
186 var chartinst = this,
187 legendKeyShape = opts.legendkeyshape || 'rect',
188 legendKeySize = opts.legendkeysize || 14,
189 legendFont = opts.legendfont || "Work Sans",
190 legendFontSize = opts.legendfontsize || 14,
191 legendFontColor = opts.legendfontcolor || '#323232',
192 lineHeight = opts.lineheight || 23;
195 for (var i = 0; i < len; i++) {
196 // 0 pixels away from left of the graph
197 // 30 pixels away from bottom of the chart
198 if(legendKeyShape == 'rect') {
199 // pass top left position for 'rect'
202 height - bottomPadding + 30 + i * lineHeight - legendKeySize / 2,
206 ).attr({ fill: opts.colors && opts.colors[i] || chartinst.colors[i] || "#3E66BC", "stroke": "#fff" });
209 // pass center position for 'circle'
212 height - bottomPadding + 30 + i * lineHeight,
214 ).attr({ fill: opts.colors && opts.colors[i] || chartinst.colors[i] || "#3E66BC", "stroke": "#fff" });
217 var text = (opts.legend) ? opts.legend[i] : values[i].toString();
219 if(text.indexOf('#qty#') !== -1) {
220 text = text.replace('#qty#', Roo.util.Format.number(Math.round(values[i]), 0));
223 // 12 pixels away from th right of the legend key
224 paper.text(legendKeySize + 12, height - bottomPadding + 30 + i * lineHeight - legendKeySize / 10, text).attr({
225 "font-size": legendFontSize,
226 "font-family": legendFont,
227 "text-anchor": "start",
228 fill : legendFontColor