diff --git a/src/pretix/static/charts/morris.js b/src/pretix/static/charts/morris.js index 3a1a83084..35ad2070f 100644 --- a/src/pretix/static/charts/morris.js +++ b/src/pretix/static/charts/morris.js @@ -1,5 +1,5 @@ /* @license -morris.js v0.5.0 +morris.js v0.5.1 Copyright 2014 Olly Smith All rights reserved. Licensed under the BSD-2-Clause License. */ @@ -74,6 +74,7 @@ Licensed under the BSD-2-Clause License. __extends(Grid, _super); function Grid(options) { + this.hasToShow = __bind(this.hasToShow, this); this.resizeHandler = __bind(this.resizeHandler, this); var _this = this; if (typeof options.element === 'string') { @@ -197,7 +198,7 @@ Licensed under the BSD-2-Clause License. }; Grid.prototype.setData = function(data, redraw) { - var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval, _ref; + var e, flatEvents, from, idx, index, maxGoal, minGoal, ret, row, step, to, total, y, ykey, ymax, ymin, yval, _i, _len, _ref, _ref1; if (redraw == null) { redraw = true; } @@ -254,7 +255,7 @@ Licensed under the BSD-2-Clause License. if ((yval != null) && typeof yval !== 'number') { yval = null; } - if (yval != null) { + if ((yval != null) && this.hasToShow(idx)) { if (this.cumulative) { total += yval; } else { @@ -288,21 +289,24 @@ Licensed under the BSD-2-Clause License. this.events = []; if (this.options.events.length > 0) { if (this.options.parseTime) { - this.events = (function() { - var _i, _len, _ref, _results; - _ref = this.options.events; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - e = _ref[_i]; - _results.push(Morris.parseDate(e)); + _ref = this.options.events; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + e = _ref[_i]; + if (e instanceof Array) { + from = e[0], to = e[1]; + this.events.push([Morris.parseDate(from), Morris.parseDate(to)]); + } else { + this.events.push(Morris.parseDate(e)); } - return _results; - }).call(this); + } } else { this.events = this.options.events; } - this.xmax = Math.max(this.xmax, Math.max.apply(Math, this.events)); - this.xmin = Math.min(this.xmin, Math.min.apply(Math, this.events)); + flatEvents = $.map(this.events, function(e) { + return e; + }); + this.xmax = Math.max(this.xmax, Math.max.apply(Math, flatEvents)); + this.xmin = Math.min(this.xmin, Math.min.apply(Math, flatEvents)); } if (this.xmin === this.xmax) { this.xmin -= 1; @@ -316,7 +320,7 @@ Licensed under the BSD-2-Clause License. } this.ymax += 1; } - if (((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') || this.options.grid === true) { + if (((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'y') || this.options.grid === true) { if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) { this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines); this.ymin = Math.min(this.ymin, this.grid[0]); @@ -324,9 +328,9 @@ Licensed under the BSD-2-Clause License. } else { step = (this.ymax - this.ymin) / (this.options.numLines - 1); this.grid = (function() { - var _i, _ref1, _ref2, _results; + var _j, _ref2, _ref3, _results; _results = []; - for (y = _i = _ref1 = this.ymin, _ref2 = this.ymax; step > 0 ? _i <= _ref2 : _i >= _ref2; y = _i += step) { + for (y = _j = _ref2 = this.ymin, _ref3 = this.ymax; step > 0 ? _j <= _ref3 : _j >= _ref3; y = _j += step) { _results.push(y); } return _results; @@ -405,7 +409,7 @@ Licensed under the BSD-2-Clause License. }; Grid.prototype._calc = function() { - var bottomOffsets, gridLine, h, i, w, yLabelWidths, _ref, _ref1; + var angle, bottomOffsets, gridLine, h, i, w, yLabelWidths, _ref, _ref1; w = this.el.width(); h = this.el.height(); if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) { @@ -427,23 +431,53 @@ Licensed under the BSD-2-Clause License. } return _results; }).call(this); - this.left += Math.max.apply(Math, yLabelWidths); + if (!this.options.horizontal) { + this.left += Math.max.apply(Math, yLabelWidths); + } else { + this.bottom -= Math.max.apply(Math, yLabelWidths); + } } if ((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'x') { + if (!this.options.horizontal) { + angle = -this.options.xLabelAngle; + } else { + angle = -90; + } bottomOffsets = (function() { var _i, _ref2, _results; _results = []; for (i = _i = 0, _ref2 = this.data.length; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) { - _results.push(this.measureText(this.data[i].text, -this.options.xLabelAngle).height); + _results.push(this.measureText(this.data[i].label, angle).height); } return _results; }).call(this); - this.bottom -= Math.max.apply(Math, bottomOffsets); + if (!this.options.horizontal) { + this.bottom -= Math.max.apply(Math, bottomOffsets); + } else { + this.left += Math.max.apply(Math, bottomOffsets); + } } this.width = Math.max(1, this.right - this.left); this.height = Math.max(1, this.bottom - this.top); - this.dx = this.width / (this.xmax - this.xmin); - this.dy = this.height / (this.ymax - this.ymin); + if (!this.options.horizontal) { + this.dx = this.width / (this.xmax - this.xmin); + this.dy = this.height / (this.ymax - this.ymin); + this.yStart = this.bottom; + this.yEnd = this.top; + this.xStart = this.left; + this.xEnd = this.right; + this.xSize = this.width; + this.ySize = this.height; + } else { + this.dx = this.height / (this.xmax - this.xmin); + this.dy = this.width / (this.ymax - this.ymin); + this.yStart = this.left; + this.yEnd = this.right; + this.xStart = this.top; + this.xEnd = this.bottom; + this.xSize = this.height; + this.ySize = this.width; + } if (this.calc) { return this.calc(); } @@ -451,14 +485,18 @@ Licensed under the BSD-2-Clause License. }; Grid.prototype.transY = function(y) { - return this.bottom - (y - this.ymin) * this.dy; + if (!this.options.horizontal) { + return this.bottom - (y - this.ymin) * this.dy; + } else { + return this.left + (y - this.ymin) * this.dy; + } }; Grid.prototype.transX = function(x) { if (this.data.length === 1) { - return (this.left + this.right) / 2; + return (this.xStart + this.xEnd) / 2; } else { - return this.left + (x - this.xmin) * this.dx; + return this.xStart + (x - this.xmin) * this.dx; } }; @@ -485,32 +523,50 @@ Licensed under the BSD-2-Clause License. }; Grid.prototype.yAxisFormat = function(label) { - return this.yLabelFormat(label); + return this.yLabelFormat(label, 0); }; - Grid.prototype.yLabelFormat = function(label) { + Grid.prototype.yLabelFormat = function(label, i) { if (typeof this.options.yLabelFormat === 'function') { - return this.options.yLabelFormat(label); + return this.options.yLabelFormat(label, i); } else { return "" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits; } }; + Grid.prototype.getYAxisLabelX = function() { + return this.left - this.options.padding / 2; + }; + Grid.prototype.drawGrid = function() { - var lineY, y, _i, _len, _ref, _ref1, _ref2, _results; + var basePos, lineY, pos, _i, _len, _ref, _ref1, _ref2, _results; if (this.options.grid === false && ((_ref = this.options.axes) !== true && _ref !== 'both' && _ref !== 'y')) { return; } + if (!this.options.horizontal) { + basePos = this.getYAxisLabelX(); + } else { + basePos = this.getXAxisLabelY(); + } _ref1 = this.grid; _results = []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { lineY = _ref1[_i]; - y = this.transY(lineY); + pos = this.transY(lineY); if ((_ref2 = this.options.axes) === true || _ref2 === 'both' || _ref2 === 'y') { - this.drawYAxisLabel(this.left - this.options.padding / 2, y, this.yAxisFormat(lineY)); + if (!this.options.horizontal) { + this.drawYAxisLabel(basePos, pos, this.yAxisFormat(lineY)); + } else { + this.drawXAxisLabel(pos, basePos, this.yAxisFormat(lineY)); + } } if (this.options.grid) { - _results.push(this.drawGridLine("M" + this.left + "," + y + "H" + (this.left + this.width))); + pos = Math.floor(pos) + 0.5; + if (!this.options.horizontal) { + _results.push(this.drawGridLine("M" + this.xStart + "," + pos + "H" + this.xEnd)); + } else { + _results.push(this.drawGridLine("M" + pos + "," + this.xStart + "V" + this.xEnd)); + } } else { _results.push(void 0); } @@ -543,11 +599,42 @@ Licensed under the BSD-2-Clause License. }; Grid.prototype.drawGoal = function(goal, color) { - return this.raphael.path("M" + this.left + "," + (this.transY(goal)) + "H" + this.right).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth); + var path, y; + y = Math.floor(this.transY(goal)) + 0.5; + if (!this.options.horizontal) { + path = "M" + this.xStart + "," + y + "H" + this.xEnd; + } else { + path = "M" + y + "," + this.xStart + "V" + this.xEnd; + } + return this.raphael.path(path).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth); }; Grid.prototype.drawEvent = function(event, color) { - return this.raphael.path("M" + (this.transX(event)) + "," + this.bottom + "V" + this.top).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth); + var from, path, to, x; + if (event instanceof Array) { + from = event[0], to = event[1]; + from = Math.floor(this.transX(from)) + 0.5; + to = Math.floor(this.transX(to)) + 0.5; + if (!this.options.horizontal) { + return this.raphael.rect(from, this.yEnd, to - from, this.yStart - this.yEnd).attr({ + fill: color, + stroke: false + }).toBack(); + } else { + return this.raphael.rect(this.yStart, from, this.yEnd - this.yStart, to - from).attr({ + fill: color, + stroke: false + }).toBack(); + } + } else { + x = Math.floor(this.transX(event)) + 0.5; + if (!this.options.horizontal) { + path = "M" + x + "," + this.yStart + "V" + this.yEnd; + } else { + path = "M" + this.yStart + "," + x + "H" + this.yEnd; + } + return this.raphael.path(path).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth); + } }; Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) { @@ -586,6 +673,10 @@ Licensed under the BSD-2-Clause License. return this.redraw(); }; + Grid.prototype.hasToShow = function(i) { + return this.options.shown === true || this.options.shown[i] === true; + }; + return Grid; })(Morris.EventEmitter); @@ -662,13 +753,13 @@ Licensed under the BSD-2-Clause License. this.options.parent.append(this.el); } - Hover.prototype.update = function(html, x, y) { + Hover.prototype.update = function(html, x, y, centre_y) { if (!html) { return this.hide(); } else { this.html(html); this.show(); - return this.moveTo(x, y); + return this.moveTo(x, y, centre_y); } }; @@ -676,7 +767,7 @@ Licensed under the BSD-2-Clause License. return this.el.html(content); }; - Hover.prototype.moveTo = function(x, y) { + Hover.prototype.moveTo = function(x, y, centre_y) { var hoverHeight, hoverWidth, left, parentHeight, parentWidth, top; parentWidth = this.options.parent.innerWidth(); parentHeight = this.options.parent.innerHeight(); @@ -684,11 +775,18 @@ Licensed under the BSD-2-Clause License. hoverHeight = this.el.outerHeight(); left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth); if (y != null) { - top = y - hoverHeight - 10; - if (top < 0) { - top = y + 10; - if (top + hoverHeight > parentHeight) { - top = parentHeight / 2 - hoverHeight / 2; + if (centre_y === true) { + top = y - hoverHeight / 2; + if (top < 0) { + top = 0; + } + } else { + top = y - hoverHeight - 10; + if (top < 0) { + top = y + 10; + if (top + hoverHeight > parentHeight) { + top = parentHeight / 2 - hoverHeight / 2; + } } } } else { @@ -745,10 +843,14 @@ Licensed under the BSD-2-Clause License. pointStrokeColors: ['#ffffff'], pointFillColors: [], smooth: true, + shown: true, xLabels: 'auto', xLabelFormat: null, xLabelMargin: 24, - hideHover: false + hideHover: false, + trendLine: false, + trendLineWidth: 2, + trendLineColors: ['#689bc3', '#a2b3bf', '#64b764'] }; Line.prototype.calc = function() { @@ -840,11 +942,15 @@ Licensed under the BSD-2-Clause License. Line.prototype.hoverContentForRow = function(index) { var content, j, row, y, _i, _len, _ref; row = this.data[index]; - content = "
" + row.label + "
"; + content = $("
").text(row.label); + content = content.prop('outerHTML'); _ref = row.y; for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) { y = _ref[j]; - content += "
\n " + this.options.labels[j] + ":\n " + (this.yLabelFormat(y)) + "\n
"; + if (this.options.labels[j] === false) { + continue; + } + content += "
\n " + this.options.labels[j] + ":\n " + (this.yLabelFormat(y, j)) + "\n
"; } if (typeof this.options.hoverCallback === 'function') { content = this.options.hoverCallback(index, this.options, content, row.src); @@ -954,11 +1060,20 @@ Licensed under the BSD-2-Clause License. var i, _i, _j, _ref, _ref1, _results; this.seriesPoints = []; for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) { - this._drawLineFor(i); + if (this.hasToShow(i)) { + if (this.options.trendLine !== false && this.options.trendLine === true || this.options.trendLine[i] === true) { + this._drawTrendLine(i); + } + this._drawLineFor(i); + } } _results = []; for (i = _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) { - _results.push(this._drawPointFor(i)); + if (this.hasToShow(i)) { + _results.push(this._drawPointFor(i)); + } else { + _results.push(void 0); + } } return _results; }; @@ -987,6 +1102,38 @@ Licensed under the BSD-2-Clause License. } }; + Line.prototype._drawTrendLine = function(index) { + var a, b, data, datapoints, path, sum_x, sum_xx, sum_xy, sum_y, val, x, y, _i, _len, _ref; + sum_x = 0; + sum_y = 0; + sum_xx = 0; + sum_xy = 0; + datapoints = 0; + _ref = this.data; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + val = _ref[_i]; + x = val.x; + y = val.y[index]; + if (y === void 0) { + continue; + } + datapoints += 1; + sum_x += x; + sum_y += y; + sum_xx += x * x; + sum_xy += x * y; + } + a = (datapoints * sum_xy - sum_x * sum_y) / (datapoints * sum_xx - sum_x * sum_x); + b = (sum_y / datapoints) - ((a * sum_x) / datapoints); + data = [{}, {}]; + data[0].x = this.transX(this.data[0].x); + data[0].y = this.transY(this.data[0].x * a + b); + data[1].x = this.transX(this.data[this.data.length - 1].x); + data[1].y = this.transY(this.data[this.data.length - 1].x * a + b); + path = Morris.Line.createPath(data, false, this.bottom); + return path = this.raphael.path(path).attr('stroke', this.colorFor(null, index, 'trendLine')).attr('stroke-width', this.options.trendLineWidth); + }; + Line.createPath = function(coords, smooth, bottom) { var coord, g, grads, i, ix, lg, path, prevCoord, x1, x2, y1, y2, _i, _len; path = ""; @@ -1078,8 +1225,10 @@ Licensed under the BSD-2-Clause License. return this.options.lineColors.call(this, row, sidx, type); } else if (type === 'point') { return this.options.pointFillColors[sidx % this.options.pointFillColors.length] || this.options.lineColors[sidx % this.options.lineColors.length]; - } else { + } else if (type === 'line') { return this.options.lineColors[sidx % this.options.lineColors.length]; + } else { + return this.options.trendLineColors[sidx % this.options.trendLineColors.length]; } }; @@ -1120,6 +1269,9 @@ Licensed under the BSD-2-Clause License. }; Line.prototype.pointGrowSeries = function(index) { + if (this.pointSizeForSeries(index) === 0) { + return; + } return Raphael.animation({ r: this.pointSizeForSeries(index) + 3 }, 25, 'linear'); @@ -1409,7 +1561,9 @@ Licensed under the BSD-2-Clause License. barColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'], barOpacity: 1.0, barRadius: [0, 0, 0, 0], - xLabelMargin: 50 + xLabelMargin: 50, + horizontal: false, + shown: true }; Bar.prototype.calc = function() { @@ -1426,7 +1580,7 @@ Licensed under the BSD-2-Clause License. _results = []; for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) { row = _ref[idx]; - row._x = this.left + this.width * (idx + 0.5) / this.data.length; + row._x = this.xStart + this.xSize * (idx + 0.5) / this.data.length; _results.push(row._y = (function() { var _j, _len1, _ref1, _results1; _ref1 = row.y; @@ -1454,28 +1608,54 @@ Licensed under the BSD-2-Clause License. }; Bar.prototype.drawXAxis = function() { - var i, label, labelBox, margin, offset, prevAngleMargin, prevLabelMargin, row, textBox, ypos, _i, _ref, _results; - ypos = this.bottom + (this.options.xAxisLabelTopPadding || this.options.padding / 2); + var angle, basePos, i, label, labelBox, margin, maxSize, offset, prevAngleMargin, prevLabelMargin, row, size, startPos, textBox, _i, _ref, _results; + if (!this.options.horizontal) { + basePos = this.getXAxisLabelY(); + } else { + basePos = this.getYAxisLabelX(); + } prevLabelMargin = null; prevAngleMargin = null; _results = []; for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { row = this.data[this.data.length - 1 - i]; - label = this.drawXAxisLabel(row._x, ypos, row.label); + if (!this.options.horizontal) { + label = this.drawXAxisLabel(row._x, basePos, row.label); + } else { + label = this.drawYAxisLabel(basePos, row._x - 0.5 * this.options.gridTextSize, row.label); + } + if (!this.options.horizontal) { + angle = this.options.xLabelAngle; + } else { + angle = 0; + } textBox = label.getBBox(); - label.transform("r" + (-this.options.xLabelAngle)); + label.transform("r" + (-angle)); labelBox = label.getBBox(); label.transform("t0," + (labelBox.height / 2) + "..."); - if (this.options.xLabelAngle !== 0) { - offset = -0.5 * textBox.width * Math.cos(this.options.xLabelAngle * Math.PI / 180.0); + if (angle !== 0) { + offset = -0.5 * textBox.width * Math.cos(angle * Math.PI / 180.0); label.transform("t" + offset + ",0..."); } - if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) { - if (this.options.xLabelAngle !== 0) { - margin = 1.25 * this.options.gridTextSize / Math.sin(this.options.xLabelAngle * Math.PI / 180.0); - prevAngleMargin = labelBox.x - margin; + if (!this.options.horizontal) { + startPos = labelBox.x; + size = labelBox.width; + maxSize = this.el.width(); + } else { + startPos = labelBox.y; + size = labelBox.height; + maxSize = this.el.height(); + } + if (((prevLabelMargin == null) || prevLabelMargin >= startPos + size || (prevAngleMargin != null) && prevAngleMargin >= startPos) && startPos >= 0 && (startPos + size) < maxSize) { + if (angle !== 0) { + margin = 1.25 * this.options.gridTextSize / Math.sin(angle * Math.PI / 180.0); + prevAngleMargin = startPos - margin; + } + if (!this.options.horizontal) { + _results.push(prevLabelMargin = startPos - this.options.xLabelMargin); + } else { + _results.push(prevLabelMargin = startPos); } - _results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin); } else { _results.push(label.remove()); } @@ -1483,10 +1663,23 @@ Licensed under the BSD-2-Clause License. return _results; }; + Bar.prototype.getXAxisLabelY = function() { + return this.bottom + (this.options.xAxisLabelTopPadding || this.options.padding / 2); + }; + Bar.prototype.drawSeries = function() { - var barWidth, bottom, groupWidth, idx, lastTop, left, leftPadding, numBars, row, sidx, size, spaceLeft, top, ypos, zeroPos; - groupWidth = this.width / this.options.data.length; - numBars = this.options.stacked ? 1 : this.options.ykeys.length; + var barWidth, bottom, groupWidth, i, idx, lastTop, left, leftPadding, numBars, row, sidx, size, spaceLeft, top, ypos, zeroPos, _i, _ref; + groupWidth = this.xSize / this.options.data.length; + if (this.options.stacked) { + numBars = 1; + } else { + numBars = 0; + for (i = _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { + if (this.hasToShow(i)) { + numBars += 1; + } + } + } barWidth = (groupWidth * this.options.barSizeRatio - this.options.barGap * (numBars - 1)) / numBars; if (this.options.barSize) { barWidth = Math.min(barWidth, this.options.barSize); @@ -1495,18 +1688,21 @@ Licensed under the BSD-2-Clause License. leftPadding = spaceLeft / 2; zeroPos = this.ymin <= 0 && this.ymax >= 0 ? this.transY(0) : null; return this.bars = (function() { - var _i, _len, _ref, _results; - _ref = this.data; + var _j, _len, _ref1, _results; + _ref1 = this.data; _results = []; - for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) { - row = _ref[idx]; + for (idx = _j = 0, _len = _ref1.length; _j < _len; idx = ++_j) { + row = _ref1[idx]; lastTop = 0; _results.push((function() { - var _j, _len1, _ref1, _results1; - _ref1 = row._y; + var _k, _len1, _ref2, _results1; + _ref2 = row._y; _results1 = []; - for (sidx = _j = 0, _len1 = _ref1.length; _j < _len1; sidx = ++_j) { - ypos = _ref1[sidx]; + for (sidx = _k = 0, _len1 = _ref2.length; _k < _len1; sidx = ++_k) { + ypos = _ref2[sidx]; + if (!this.hasToShow(sidx)) { + continue; + } if (ypos !== null) { if (zeroPos) { top = Math.min(ypos, zeroPos); @@ -1515,19 +1711,28 @@ Licensed under the BSD-2-Clause License. top = ypos; bottom = this.bottom; } - left = this.left + idx * groupWidth + leftPadding; + left = this.xStart + idx * groupWidth + leftPadding; if (!this.options.stacked) { left += sidx * (barWidth + this.options.barGap); } size = bottom - top; if (this.options.verticalGridCondition && this.options.verticalGridCondition(row.x)) { - this.drawBar(this.left + idx * groupWidth, this.top, groupWidth, Math.abs(this.top - this.bottom), this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius); + if (!this.options.horizontal) { + this.drawBar(this.xStart + idx * groupWidth, this.yEnd, groupWidth, this.ySize, this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius); + } else { + this.drawBar(this.yStart, this.xStart + idx * groupWidth, this.ySize, groupWidth, this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius); + } } if (this.options.stacked) { top -= lastTop; } - this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius); - _results1.push(lastTop += size); + if (!this.options.horizontal) { + this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius); + _results1.push(lastTop += size); + } else { + this.drawBar(top, left, size, barWidth, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius); + _results1.push(lastTop -= size); + } } else { _results1.push(null); } @@ -1558,23 +1763,29 @@ Licensed under the BSD-2-Clause License. } }; - Bar.prototype.hitTest = function(x) { + Bar.prototype.hitTest = function(x, y) { + var pos; if (this.data.length === 0) { return null; } - x = Math.max(Math.min(x, this.right), this.left); - return Math.min(this.data.length - 1, Math.floor((x - this.left) / (this.width / this.data.length))); + if (!this.options.horizontal) { + pos = x; + } else { + pos = y; + } + pos = Math.max(Math.min(pos, this.xEnd), this.xStart); + return Math.min(this.data.length - 1, Math.floor((pos - this.xStart) / (this.xSize / this.data.length))); }; Bar.prototype.onGridClick = function(x, y) { var index; - index = this.hitTest(x); + index = this.hitTest(x, y); return this.fire('click', index, this.data[index].src, x, y); }; Bar.prototype.onHoverMove = function(x, y) { var index, _ref; - index = this.hitTest(x); + index = this.hitTest(x, y); return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index)); }; @@ -1587,17 +1798,27 @@ Licensed under the BSD-2-Clause License. Bar.prototype.hoverContentForRow = function(index) { var content, j, row, x, y, _i, _len, _ref; row = this.data[index]; - content = "
" + row.label + "
"; + content = $("
").text(row.label); + content = content.prop('outerHTML'); _ref = row.y; for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) { y = _ref[j]; - content += "
\n " + this.options.labels[j] + ":\n " + (this.yLabelFormat(y)) + "\n
"; + if (this.options.labels[j] === false) { + continue; + } + content += "
\n " + this.options.labels[j] + ":\n " + (this.yLabelFormat(y, j)) + "\n
"; } if (typeof this.options.hoverCallback === 'function') { content = this.options.hoverCallback(index, this.options, content, row.src); } - x = this.left + (index + 0.5) * this.width / this.data.length; - return [content, x]; + if (!this.options.horizontal) { + x = this.left + (index + 0.5) * this.width / this.data.length; + return [content, x]; + } else { + x = this.left + 0.5 * this.width; + y = this.top + (index + 0.5) * this.height / this.data.length; + return [content, x, y, true]; + } }; Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {