--- /dev/null
+/*!
+ * g.Raphael 0.5 - Charting library, based on Raphaƫl
+ *
+ * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
+ */
+imports = typeof(imports) == 'undefined' ? false : imports;
+Raphael = typeof(Raphael) != 'undefined' ? Raphael : (imports ? imports.seed.Raphael.Raphael : {});
+Roo = typeof(Roo) != 'undefined' ? Roo: (imports ? imports.seed.Roo.Roo: {});
+
+(function () {
+
+ /**
+ * Create a horizontal chart
+ * support left axis with labels and bottom axis with interval
+ *
+ * @param {Raphael} paper to draw on
+ * @param {int} width - width of the chart
+ * @param {int} height - height of the chart
+ * @param {Array} values
+ * @param {Object} opts options
+ * background (string) : background color
+ * colors (array) : colors of the bars
+ * labelfont (string) : font family of bar labels
+ * labelfontsize (number) : font size of bar labels
+ * labelfontweight (string) (number) : font weight of bar labels
+ * labelfontcolors (array) : font colors of bar labels
+ * 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)
+ * axis (string) : composed of 4 '0' / '1' separated by space (indicated whether top / right / bottom / left axis should be shown)
+ * (e.g. '0 0 1 1' indicates that the bottom and the left axis should be shown)
+ * leftaxiswidth (number) : width of left axis area
+ * leftaxislabels (array) : labels in left axis area
+ * leftaxisfontsize (number) : font size of labels in left axis
+ * bottomaxisheight (number) : height of bottom axis area
+ * bottomaxisstep (number) : number of steps in bottom axis
+ * bottomaxisfontsize (number) : font size of labels in bottom axis
+ * axisfont (string) : font family of labels in axes
+ * axisfontweight (string) (number) : font weight of labels in axes
+ * axisfontcolor (string) : font color of labels in axes
+ */
+
+ function MHBarchart(paper, width, height, values, opts) {
+ opts = opts || {};
+
+ var chartinst = this,
+ chart = paper.set(),
+ len = values.length,
+ max = values.length == 0 ? 0 : Math.max(...values),
+ background = opts.background || '#FFFFFF',
+ colors = opts.colors || chartinst.colors,
+ labelFont = opts.labelfont || 'Work Sans',
+ labelFontSize = opts.labelfontsize || 12,
+ labelFontWeight = opts.labelfontweight || 'bold',
+ labelFontColors = opts.labelfontcolors || [],
+ gutter = parseFloat(opts.gutter || "40%"),
+ axis = opts.axis || "0 0 0 0",
+ ax = (axis + "").split(/[,\s]+/),
+ leftAxisWidth = 0,
+ leftAxisLabels = opts.leftaxislabels || [];
+ leftAxisFontSize = opts.leftaxisfontsize || 16,
+ bottomAxisHeight = 0,
+ bottomAxisStep = opts.bottomaxisstep || 10;
+ bottomAxisFontSize = opts.bottomaxisfontsize || 16,
+ axisFont = opts.axisfont || 'Work Sans',
+ axisFontWeight = opts.axisfontweight || 'normal',
+ axisFontColor = opts.axisfontcolor || '#323232';
+
+ // bottom axis
+ if(+ax[2]) {
+ bottomAxisHeight = opts.bottomaxisheight || 30;
+ max = Math.ceil(max / bottomAxisStep) * bottomAxisStep;
+ }
+ // left axis
+ if(+ax[3]) {
+ leftAxisWidth = opts.leftaxiswidth || 240;
+ }
+
+ if(labelFontColors.length < len) {
+ for(var i = labelFontColors.length; i < len; i++) {
+ labelFontColors.push('#FFFFFF');
+ }
+ }
+
+ // background
+ paper.rect(0, 0, width, height).attr({ stroke: "none", fill: background });
+
+ var barWidth = (width - leftAxisWidth); // maximum width of bar
+ var barHeight = (height - bottomAxisHeight) / (len * (100 + gutter) + gutter) * 100;
+ var barGutter = barHeight * (gutter / 100);
+
+ // bottom axis
+ if(+ax[2]) {
+ chartinst.bottomAxis(
+ paper,
+ leftAxisWidth,
+ height - bottomAxisHeight,
+ width - leftAxisWidth,
+ max,
+ bottomAxisStep,
+ bottomAxisHeight,
+ axisFont,
+ bottomAxisFontSize,
+ axisFontWeight,
+ axisFontColor
+ )
+ }
+
+ // left axis
+ if(+ax[3]) {
+ chartinst.leftAxis(
+ paper,
+ leftAxisWidth,
+ 0,
+ height - bottomAxisHeight,
+ leftAxisLabels,
+ barHeight,
+ barGutter,
+ axisFont,
+ leftAxisFontSize,
+ axisFontWeight,
+ axisFontColor
+ )
+ }
+
+ // bars
+ var unit = barWidth / max;
+
+ values.forEach(function(v,k) {
+ if(v == 0) {
+ return;
+ }
+
+ paper.rect(leftAxisWidth, barGutter + (k * (barHeight + barGutter)), v * unit, barHeight).attr({ stroke: "none", fill: colors[k] });
+
+ // bar label
+ // 16 pixels away from right of left axis
+ // align bar label in the center
+ paper.text(leftAxisWidth + 16, barGutter + (k * (barHeight + barGutter)) + barHeight / 2, Roo.util.Format.number(v, 0)).attr({
+ "font-size": labelFontSize,
+ "font-family": labelFont,
+ "font-weight": labelFontWeight,
+ "text-anchor": 'start',
+ fill : labelFontColors[k]
+ });
+
+ });
+
+ return chart;
+
+ }
+
+ //inheritance
+ var F = function() {};
+ F.prototype = Raphael.g;
+ MHBarchart.prototype = new F;
+
+ Raphael.fn.mhbarchart = function(width, height, values, opts) {
+ return new MHBarchart(this, width, height, values, opts);
+ };
+
+ MHBarchart.prototype.bottomAxis = function (paper, x, y, length, max, steps, axisHeight, axisFont, axisFontSize, axisFontWeight, axisFontColor)
+ {
+ var path = ["M", x, y, "l", length, 0],
+ text = paper.set(),
+ d = Math.ceil(max / steps),
+ dl = length / steps;
+
+ for(var i = 0; i < steps; i++) {
+ paper.text(x + i * dl, y + axisHeight / 2, i * d).attr({
+ "font-size": axisFontSize,
+ "font-family": axisFont,
+ "font-weight": axisFontWeight,
+ "text-anchor": 'middle',
+ fill : axisFontColor
+ });
+
+ // bottom axis interval
+ paper.path(["M", x + i * dl , y, "l", 0, -1 * y]).attr({ stroke: '#9E9E9E', "stroke-width": 1 });
+ }
+
+ var res = paper.path(path).attr({ stroke: '#000', "stroke-width": 0 }); // default no axis
+
+ res.text = text;
+ res.all = paper.set([res, text]);
+ res.remove = function () {
+ this.text.remove();
+ this.constructor.prototype.remove.call(this);
+ };
+
+ return res;
+ }
+
+ MHBarchart.prototype.leftAxis = function (paper, x, y, length, labels, barHeight, barGutter, axisFont, axisFontSize, axisFontWeight, axisFontColor)
+ {
+ var path = ["M", x, y, "l", 0, length],
+ text = paper.set();
+
+ labels.forEach(function(v,k) {
+ paper.text(0, barGutter + (k * (barHeight + barGutter)) + barHeight / 2, v).attr({
+ "font-size": axisFontSize,
+ "font-family": axisFont,
+ "font-weight": axisFontWeight,
+ "text-anchor": 'start',
+ fill : axisFontColor
+ });
+ });
+
+ var res = paper.path(path).attr({ stroke: '#000', "stroke-width": 0 }); // default no axis
+
+ res.text = text;
+ res.all = paper.set([res, text]);
+ res.remove = function () {
+ this.text.remove();
+ this.constructor.prototype.remove.call(this);
+ };
+
+ return res;
+ }
+})();
\ No newline at end of file