From fcaa3dee915e1ad44c4444b8631fd8ee4dfcf6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=A1=D1=82=D0=B5?= =?UTF-8?q?=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Tue, 7 Mar 2017 14:14:46 +0300 Subject: [PATCH] separate HorizontalBar component added, to remove optional 'type' parameter at Bar, which was ignored inside reactive mixins --- dist/vue-chartjs.js | 1122 ++++++++++++++----------- src/BaseCharts/Bar.js | 2 +- src/BaseCharts/HorizontalBar.js | 79 ++ src/examples/HorizontalBarExample.js | 16 + src/index.js | 3 + test/unit/specs/HorizontalBar.spec.js | 64 ++ 6 files changed, 773 insertions(+), 513 deletions(-) create mode 100644 src/BaseCharts/HorizontalBar.js create mode 100644 src/examples/HorizontalBarExample.js create mode 100644 test/unit/specs/HorizontalBar.spec.js diff --git a/dist/vue-chartjs.js b/dist/vue-chartjs.js index add0f16..81766ea 100644 --- a/dist/vue-chartjs.js +++ b/dist/vue-chartjs.js @@ -59,37 +59,41 @@ return /******/ (function(modules) { // webpackBootstrap Object.defineProperty(exports, "__esModule", { value: true }); - exports.mixins = exports.Bubble = exports.Radar = exports.PolarArea = exports.Pie = exports.Line = exports.Doughnut = exports.Bar = exports.VueCharts = undefined; + exports.mixins = exports.Bubble = exports.Radar = exports.PolarArea = exports.Pie = exports.Line = exports.Doughnut = exports.HorizontalBar = exports.Bar = exports.VueCharts = undefined; var _Bar = __webpack_require__(1); var _Bar2 = _interopRequireDefault(_Bar); - var _Doughnut = __webpack_require__(382); + var _HorizontalBar = __webpack_require__(382); + + var _HorizontalBar2 = _interopRequireDefault(_HorizontalBar); + + var _Doughnut = __webpack_require__(383); var _Doughnut2 = _interopRequireDefault(_Doughnut); - var _Line = __webpack_require__(383); + var _Line = __webpack_require__(384); var _Line2 = _interopRequireDefault(_Line); - var _Pie = __webpack_require__(384); + var _Pie = __webpack_require__(385); var _Pie2 = _interopRequireDefault(_Pie); - var _PolarArea = __webpack_require__(385); + var _PolarArea = __webpack_require__(386); var _PolarArea2 = _interopRequireDefault(_PolarArea); - var _Radar = __webpack_require__(386); + var _Radar = __webpack_require__(387); var _Radar2 = _interopRequireDefault(_Radar); - var _Bubble = __webpack_require__(387); + var _Bubble = __webpack_require__(388); var _Bubble2 = _interopRequireDefault(_Bubble); - var _index = __webpack_require__(388); + var _index = __webpack_require__(389); var _index2 = _interopRequireDefault(_index); @@ -97,6 +101,7 @@ return /******/ (function(modules) { // webpackBootstrap var VueCharts = { Bar: _Bar2.default, + HorizontalBar: _HorizontalBar2.default, Doughnut: _Doughnut2.default, Line: _Line2.default, Pie: _Pie2.default, @@ -109,6 +114,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.default = VueCharts; exports.VueCharts = VueCharts; exports.Bar = _Bar2.default; + exports.HorizontalBar = _HorizontalBar2.default; exports.Doughnut = _Doughnut2.default; exports.Line = _Line2.default; exports.Pie = _Pie2.default; @@ -195,7 +201,7 @@ return /******/ (function(modules) { // webpackBootstrap renderChart: function renderChart(data, options, type) { var chartOptions = (0, _options.mergeOptions)(this.defaultOptions, options); this._chart = new _chart2.default(this.$refs.canvas.getContext('2d'), { - type: type || 'bar', + type: 'bar', data: data, options: chartOptions }); @@ -8202,489 +8208,491 @@ return /******/ (function(modules) { // webpackBootstrap /* 7 */ /***/ function(module, exports, __webpack_require__) { - /* MIT license */ - var convert = __webpack_require__(8); - var string = __webpack_require__(10); - - var Color = function (obj) { - if (obj instanceof Color) { - return obj; - } - if (!(this instanceof Color)) { - return new Color(obj); - } - - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - }; - - // parse Color() argument - var vals; - if (typeof obj === 'string') { - vals = string.getRgba(obj); - if (vals) { - this.setValues('rgb', vals); - } else if (vals = string.getHsla(obj)) { - this.setValues('hsl', vals); - } else if (vals = string.getHwb(obj)) { - this.setValues('hwb', vals); - } else { - throw new Error('Unable to parse color from string "' + obj + '"'); - } - } else if (typeof obj === 'object') { - vals = obj; - if (vals.r !== undefined || vals.red !== undefined) { - this.setValues('rgb', vals); - } else if (vals.l !== undefined || vals.lightness !== undefined) { - this.setValues('hsl', vals); - } else if (vals.v !== undefined || vals.value !== undefined) { - this.setValues('hsv', vals); - } else if (vals.w !== undefined || vals.whiteness !== undefined) { - this.setValues('hwb', vals); - } else if (vals.c !== undefined || vals.cyan !== undefined) { - this.setValues('cmyk', vals); - } else { - throw new Error('Unable to parse color from object ' + JSON.stringify(obj)); - } - } - }; - - Color.prototype = { - rgb: function () { - return this.setSpace('rgb', arguments); - }, - hsl: function () { - return this.setSpace('hsl', arguments); - }, - hsv: function () { - return this.setSpace('hsv', arguments); - }, - hwb: function () { - return this.setSpace('hwb', arguments); - }, - cmyk: function () { - return this.setSpace('cmyk', arguments); - }, - - rgbArray: function () { - return this.values.rgb; - }, - hslArray: function () { - return this.values.hsl; - }, - hsvArray: function () { - return this.values.hsv; - }, - hwbArray: function () { - var values = this.values; - if (values.alpha !== 1) { - return values.hwb.concat([values.alpha]); - } - return values.hwb; - }, - cmykArray: function () { - return this.values.cmyk; - }, - rgbaArray: function () { - var values = this.values; - return values.rgb.concat([values.alpha]); - }, - hslaArray: function () { - var values = this.values; - return values.hsl.concat([values.alpha]); - }, - alpha: function (val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues('alpha', val); - return this; - }, - - red: function (val) { - return this.setChannel('rgb', 0, val); - }, - green: function (val) { - return this.setChannel('rgb', 1, val); - }, - blue: function (val) { - return this.setChannel('rgb', 2, val); - }, - hue: function (val) { - if (val) { - val %= 360; - val = val < 0 ? 360 + val : val; - } - return this.setChannel('hsl', 0, val); - }, - saturation: function (val) { - return this.setChannel('hsl', 1, val); - }, - lightness: function (val) { - return this.setChannel('hsl', 2, val); - }, - saturationv: function (val) { - return this.setChannel('hsv', 1, val); - }, - whiteness: function (val) { - return this.setChannel('hwb', 1, val); - }, - blackness: function (val) { - return this.setChannel('hwb', 2, val); - }, - value: function (val) { - return this.setChannel('hsv', 2, val); - }, - cyan: function (val) { - return this.setChannel('cmyk', 0, val); - }, - magenta: function (val) { - return this.setChannel('cmyk', 1, val); - }, - yellow: function (val) { - return this.setChannel('cmyk', 2, val); - }, - black: function (val) { - return this.setChannel('cmyk', 3, val); - }, - - hexString: function () { - return string.hexString(this.values.rgb); - }, - rgbString: function () { - return string.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function () { - return string.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function () { - return string.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function () { - return string.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function () { - return string.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function () { - return string.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function () { - return string.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function () { - var rgb = this.values.rgb; - return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; - }, - - luminosity: function () { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function (color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05); - } - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function (color2) { - var contrastRatio = this.contrast(color2); - if (contrastRatio >= 7.1) { - return 'AAA'; - } - - return (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function () { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb; - var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function () { - return !this.dark(); - }, - - negate: function () { - var rgb = []; - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues('rgb', rgb); - return this; - }, - - lighten: function (ratio) { - var hsl = this.values.hsl; - hsl[2] += hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - darken: function (ratio) { - var hsl = this.values.hsl; - hsl[2] -= hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - saturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] += hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - desaturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] -= hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - whiten: function (ratio) { - var hwb = this.values.hwb; - hwb[1] += hwb[1] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - blacken: function (ratio) { - var hwb = this.values.hwb; - hwb[2] += hwb[2] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - greyscale: function () { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues('rgb', [val, val, val]); - return this; - }, - - clearer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha - (alpha * ratio)); - return this; - }, - - opaquer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha + (alpha * ratio)); - return this; - }, - - rotate: function (degrees) { - var hsl = this.values.hsl; - var hue = (hsl[0] + degrees) % 360; - hsl[0] = hue < 0 ? 360 + hue : hue; - this.setValues('hsl', hsl); - return this; - }, - - /** - * Ported from sass implementation in C - * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 - */ - mix: function (mixinColor, weight) { - var color1 = this; - var color2 = mixinColor; - var p = weight === undefined ? 0.5 : weight; - - var w = 2 * p - 1; - var a = color1.alpha() - color2.alpha(); - - var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - return this - .rgb( - w1 * color1.red() + w2 * color2.red(), - w1 * color1.green() + w2 * color2.green(), - w1 * color1.blue() + w2 * color2.blue() - ) - .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); - }, - - toJSON: function () { - return this.rgb(); - }, - - clone: function () { - // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, - // making the final build way to big to embed in Chart.js. So let's do it manually, - // assuming that values to clone are 1 dimension arrays containing only numbers, - // except 'alpha' which is a number. - var result = new Color(); - var source = this.values; - var target = result.values; - var value, type; - - for (var prop in source) { - if (source.hasOwnProperty(prop)) { - value = source[prop]; - type = ({}).toString.call(value); - if (type === '[object Array]') { - target[prop] = value.slice(0); - } else if (type === '[object Number]') { - target[prop] = value; - } else { - console.error('unexpected color value:', value); - } - } - } - - return result; - } - }; - - Color.prototype.spaces = { - rgb: ['red', 'green', 'blue'], - hsl: ['hue', 'saturation', 'lightness'], - hsv: ['hue', 'saturation', 'value'], - hwb: ['hue', 'whiteness', 'blackness'], - cmyk: ['cyan', 'magenta', 'yellow', 'black'] - }; - - Color.prototype.maxes = { - rgb: [255, 255, 255], - hsl: [360, 100, 100], - hsv: [360, 100, 100], - hwb: [360, 100, 100], - cmyk: [100, 100, 100, 100] - }; - - Color.prototype.getValues = function (space) { - var values = this.values; - var vals = {}; - - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = values[space][i]; - } - - if (values.alpha !== 1) { - vals.a = values.alpha; - } - - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; - }; - - Color.prototype.setValues = function (space, vals) { - var values = this.values; - var spaces = this.spaces; - var maxes = this.maxes; - var alpha = 1; - var i; - - if (space === 'alpha') { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (i = 0; i < space.length; i++) { - values[space][i] = vals[space.charAt(i)]; - } - - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - - for (i = 0; i < space.length; i++) { - values[space][i] = vals[chans[i]]; - } - - alpha = vals.alpha; - } - - values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); - - if (space === 'alpha') { - return false; - } - - var capped; - - // cap values of the space prior converting all values - for (i = 0; i < space.length; i++) { - capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); - values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname !== space) { - values[sname] = convert[space][sname](values[space]); - } - } - - return true; - }; - - Color.prototype.setSpace = function (space, args) { - var vals = args[0]; - - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - - // color.rgb(10, 10, 10) - if (typeof vals === 'number') { - vals = Array.prototype.slice.call(args); - } - - this.setValues(space, vals); - return this; - }; - - Color.prototype.setChannel = function (space, index, val) { - var svalues = this.values[space]; - if (val === undefined) { - // color.red() - return svalues[index]; - } else if (val === svalues[index]) { - // color.red(color.red()) - return this; - } - - // color.red(100) - svalues[index] = val; - this.setValues(space, svalues); - - return this; - }; - - if (typeof window !== 'undefined') { - window.Color = Color; - } - - module.exports = Color; + /* MIT license */ + var convert = __webpack_require__(8); + var string = __webpack_require__(10); + + var Color = function (obj) { + if (obj instanceof Color) { + return obj; + } + if (!(this instanceof Color)) { + return new Color(obj); + } + + this.valid = false; + this.values = { + rgb: [0, 0, 0], + hsl: [0, 0, 0], + hsv: [0, 0, 0], + hwb: [0, 0, 0], + cmyk: [0, 0, 0, 0], + alpha: 1 + }; + + // parse Color() argument + var vals; + if (typeof obj === 'string') { + vals = string.getRgba(obj); + if (vals) { + this.setValues('rgb', vals); + } else if (vals = string.getHsla(obj)) { + this.setValues('hsl', vals); + } else if (vals = string.getHwb(obj)) { + this.setValues('hwb', vals); + } + } else if (typeof obj === 'object') { + vals = obj; + if (vals.r !== undefined || vals.red !== undefined) { + this.setValues('rgb', vals); + } else if (vals.l !== undefined || vals.lightness !== undefined) { + this.setValues('hsl', vals); + } else if (vals.v !== undefined || vals.value !== undefined) { + this.setValues('hsv', vals); + } else if (vals.w !== undefined || vals.whiteness !== undefined) { + this.setValues('hwb', vals); + } else if (vals.c !== undefined || vals.cyan !== undefined) { + this.setValues('cmyk', vals); + } + } + }; + + Color.prototype = { + isValid: function () { + return this.valid; + }, + rgb: function () { + return this.setSpace('rgb', arguments); + }, + hsl: function () { + return this.setSpace('hsl', arguments); + }, + hsv: function () { + return this.setSpace('hsv', arguments); + }, + hwb: function () { + return this.setSpace('hwb', arguments); + }, + cmyk: function () { + return this.setSpace('cmyk', arguments); + }, + + rgbArray: function () { + return this.values.rgb; + }, + hslArray: function () { + return this.values.hsl; + }, + hsvArray: function () { + return this.values.hsv; + }, + hwbArray: function () { + var values = this.values; + if (values.alpha !== 1) { + return values.hwb.concat([values.alpha]); + } + return values.hwb; + }, + cmykArray: function () { + return this.values.cmyk; + }, + rgbaArray: function () { + var values = this.values; + return values.rgb.concat([values.alpha]); + }, + hslaArray: function () { + var values = this.values; + return values.hsl.concat([values.alpha]); + }, + alpha: function (val) { + if (val === undefined) { + return this.values.alpha; + } + this.setValues('alpha', val); + return this; + }, + + red: function (val) { + return this.setChannel('rgb', 0, val); + }, + green: function (val) { + return this.setChannel('rgb', 1, val); + }, + blue: function (val) { + return this.setChannel('rgb', 2, val); + }, + hue: function (val) { + if (val) { + val %= 360; + val = val < 0 ? 360 + val : val; + } + return this.setChannel('hsl', 0, val); + }, + saturation: function (val) { + return this.setChannel('hsl', 1, val); + }, + lightness: function (val) { + return this.setChannel('hsl', 2, val); + }, + saturationv: function (val) { + return this.setChannel('hsv', 1, val); + }, + whiteness: function (val) { + return this.setChannel('hwb', 1, val); + }, + blackness: function (val) { + return this.setChannel('hwb', 2, val); + }, + value: function (val) { + return this.setChannel('hsv', 2, val); + }, + cyan: function (val) { + return this.setChannel('cmyk', 0, val); + }, + magenta: function (val) { + return this.setChannel('cmyk', 1, val); + }, + yellow: function (val) { + return this.setChannel('cmyk', 2, val); + }, + black: function (val) { + return this.setChannel('cmyk', 3, val); + }, + + hexString: function () { + return string.hexString(this.values.rgb); + }, + rgbString: function () { + return string.rgbString(this.values.rgb, this.values.alpha); + }, + rgbaString: function () { + return string.rgbaString(this.values.rgb, this.values.alpha); + }, + percentString: function () { + return string.percentString(this.values.rgb, this.values.alpha); + }, + hslString: function () { + return string.hslString(this.values.hsl, this.values.alpha); + }, + hslaString: function () { + return string.hslaString(this.values.hsl, this.values.alpha); + }, + hwbString: function () { + return string.hwbString(this.values.hwb, this.values.alpha); + }, + keyword: function () { + return string.keyword(this.values.rgb, this.values.alpha); + }, + + rgbNumber: function () { + var rgb = this.values.rgb; + return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; + }, + + luminosity: function () { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + var rgb = this.values.rgb; + var lum = []; + for (var i = 0; i < rgb.length; i++) { + var chan = rgb[i] / 255; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); + } + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + + contrast: function (color2) { + // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + var lum1 = this.luminosity(); + var lum2 = color2.luminosity(); + if (lum1 > lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function (color2) { + var contrastRatio = this.contrast(color2); + if (contrastRatio >= 7.1) { + return 'AAA'; + } + + return (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + dark: function () { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.values.rgb; + var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + light: function () { + return !this.dark(); + }, + + negate: function () { + var rgb = []; + for (var i = 0; i < 3; i++) { + rgb[i] = 255 - this.values.rgb[i]; + } + this.setValues('rgb', rgb); + return this; + }, + + lighten: function (ratio) { + var hsl = this.values.hsl; + hsl[2] += hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + darken: function (ratio) { + var hsl = this.values.hsl; + hsl[2] -= hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + saturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] += hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + desaturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] -= hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + whiten: function (ratio) { + var hwb = this.values.hwb; + hwb[1] += hwb[1] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + blacken: function (ratio) { + var hwb = this.values.hwb; + hwb[2] += hwb[2] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + greyscale: function () { + var rgb = this.values.rgb; + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + this.setValues('rgb', [val, val, val]); + return this; + }, + + clearer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha - (alpha * ratio)); + return this; + }, + + opaquer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha + (alpha * ratio)); + return this; + }, + + rotate: function (degrees) { + var hsl = this.values.hsl; + var hue = (hsl[0] + degrees) % 360; + hsl[0] = hue < 0 ? 360 + hue : hue; + this.setValues('hsl', hsl); + return this; + }, + + /** + * Ported from sass implementation in C + * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + */ + mix: function (mixinColor, weight) { + var color1 = this; + var color2 = mixinColor; + var p = weight === undefined ? 0.5 : weight; + + var w = 2 * p - 1; + var a = color1.alpha() - color2.alpha(); + + var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + return this + .rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue() + ) + .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); + }, + + toJSON: function () { + return this.rgb(); + }, + + clone: function () { + // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, + // making the final build way to big to embed in Chart.js. So let's do it manually, + // assuming that values to clone are 1 dimension arrays containing only numbers, + // except 'alpha' which is a number. + var result = new Color(); + var source = this.values; + var target = result.values; + var value, type; + + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + value = source[prop]; + type = ({}).toString.call(value); + if (type === '[object Array]') { + target[prop] = value.slice(0); + } else if (type === '[object Number]') { + target[prop] = value; + } else { + console.error('unexpected color value:', value); + } + } + } + + return result; + } + }; + + Color.prototype.spaces = { + rgb: ['red', 'green', 'blue'], + hsl: ['hue', 'saturation', 'lightness'], + hsv: ['hue', 'saturation', 'value'], + hwb: ['hue', 'whiteness', 'blackness'], + cmyk: ['cyan', 'magenta', 'yellow', 'black'] + }; + + Color.prototype.maxes = { + rgb: [255, 255, 255], + hsl: [360, 100, 100], + hsv: [360, 100, 100], + hwb: [360, 100, 100], + cmyk: [100, 100, 100, 100] + }; + + Color.prototype.getValues = function (space) { + var values = this.values; + var vals = {}; + + for (var i = 0; i < space.length; i++) { + vals[space.charAt(i)] = values[space][i]; + } + + if (values.alpha !== 1) { + vals.a = values.alpha; + } + + // {r: 255, g: 255, b: 255, a: 0.4} + return vals; + }; + + Color.prototype.setValues = function (space, vals) { + var values = this.values; + var spaces = this.spaces; + var maxes = this.maxes; + var alpha = 1; + var i; + + this.valid = true; + + if (space === 'alpha') { + alpha = vals; + } else if (vals.length) { + // [10, 10, 10] + values[space] = vals.slice(0, space.length); + alpha = vals[space.length]; + } else if (vals[space.charAt(0)] !== undefined) { + // {r: 10, g: 10, b: 10} + for (i = 0; i < space.length; i++) { + values[space][i] = vals[space.charAt(i)]; + } + + alpha = vals.a; + } else if (vals[spaces[space][0]] !== undefined) { + // {red: 10, green: 10, blue: 10} + var chans = spaces[space]; + + for (i = 0; i < space.length; i++) { + values[space][i] = vals[chans[i]]; + } + + alpha = vals.alpha; + } + + values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); + + if (space === 'alpha') { + return false; + } + + var capped; + + // cap values of the space prior converting all values + for (i = 0; i < space.length; i++) { + capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); + values[space][i] = Math.round(capped); + } + + // convert to all the other color spaces + for (var sname in spaces) { + if (sname !== space) { + values[sname] = convert[space][sname](values[space]); + } + } + + return true; + }; + + Color.prototype.setSpace = function (space, args) { + var vals = args[0]; + + if (vals === undefined) { + // color.rgb() + return this.getValues(space); + } + + // color.rgb(10, 10, 10) + if (typeof vals === 'number') { + vals = Array.prototype.slice.call(args); + } + + this.setValues(space, vals); + return this; + }; + + Color.prototype.setChannel = function (space, index, val) { + var svalues = this.values[space]; + if (val === undefined) { + // color.red() + return svalues[index]; + } else if (val === svalues[index]) { + // color.red(color.red()) + return this; + } + + // color.red(100) + svalues[index] = val; + this.setValues(space, svalues); + + return this; + }; + + if (typeof window !== 'undefined') { + window.Color = Color; + } + + module.exports = Color; /***/ }, @@ -42976,6 +42984,96 @@ return /******/ (function(modules) { // webpackBootstrap function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + exports.default = _vue2.default.extend({ + render: function render(createElement) { + return createElement('div', [createElement('canvas', { + attrs: { + id: this.chartId, + width: this.width, + height: this.height + }, + ref: 'canvas' + })]); + }, + + props: { + chartId: { + default: 'horizontalbar-chart', + type: String + }, + width: { + default: 400, + type: Number + }, + height: { + default: 400, + type: Number + } + }, + + data: function data() { + return { + defaultOptions: { + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + }, + gridLines: { + display: false + } + }], + xAxes: [{ + gridLines: { + display: false + }, + categoryPercentage: 0.5, + barPercentage: 0.2 + }] + } + } + }; + }, + + + methods: { + renderChart: function renderChart(data, options, type) { + var chartOptions = (0, _options.mergeOptions)(this.defaultOptions, options); + this._chart = new _chart2.default(this.$refs.canvas.getContext('2d'), { + type: 'horizontalBar', + data: data, + options: chartOptions + }); + this._chart.generateLegend(); + } + }, + beforeDestroy: function beforeDestroy() { + this._chart.destroy(); + } + }); + +/***/ }, +/* 383 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _vue = __webpack_require__(2); + + var _vue2 = _interopRequireDefault(_vue); + + var _chart = __webpack_require__(4); + + var _chart2 = _interopRequireDefault(_chart); + + var _options = __webpack_require__(162); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + exports.default = _vue2.default.extend({ render: function render(createElement) { return createElement('div', [createElement('canvas', { @@ -43028,7 +43126,7 @@ return /******/ (function(modules) { // webpackBootstrap }); /***/ }, -/* 383 */ +/* 384 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -43117,7 +43215,7 @@ return /******/ (function(modules) { // webpackBootstrap }); /***/ }, -/* 384 */ +/* 385 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -43190,7 +43288,7 @@ return /******/ (function(modules) { // webpackBootstrap }); /***/ }, -/* 385 */ +/* 386 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -43263,7 +43361,7 @@ return /******/ (function(modules) { // webpackBootstrap }); /***/ }, -/* 386 */ +/* 387 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -43336,7 +43434,7 @@ return /******/ (function(modules) { // webpackBootstrap }); /***/ }, -/* 387 */ +/* 388 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -43427,7 +43525,7 @@ return /******/ (function(modules) { // webpackBootstrap }); /***/ }, -/* 388 */ +/* 389 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -43436,11 +43534,11 @@ return /******/ (function(modules) { // webpackBootstrap value: true }); - var _reactiveData = __webpack_require__(389); + var _reactiveData = __webpack_require__(390); var _reactiveData2 = _interopRequireDefault(_reactiveData); - var _reactiveProp = __webpack_require__(393); + var _reactiveProp = __webpack_require__(394); var _reactiveProp2 = _interopRequireDefault(_reactiveProp); @@ -43452,12 +43550,12 @@ return /******/ (function(modules) { // webpackBootstrap }; /***/ }, -/* 389 */ +/* 390 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _stringify = __webpack_require__(390); + var _stringify = __webpack_require__(391); var _stringify2 = _interopRequireDefault(_stringify); @@ -43504,36 +43602,36 @@ return /******/ (function(modules) { // webpackBootstrap } }; -/***/ }, -/* 390 */ -/***/ function(module, exports, __webpack_require__) { - - module.exports = { "default": __webpack_require__(391), __esModule: true }; - /***/ }, /* 391 */ /***/ function(module, exports, __webpack_require__) { - var core = __webpack_require__(392) + module.exports = { "default": __webpack_require__(392), __esModule: true }; + +/***/ }, +/* 392 */ +/***/ function(module, exports, __webpack_require__) { + + var core = __webpack_require__(393) , $JSON = core.JSON || (core.JSON = {stringify: JSON.stringify}); module.exports = function stringify(it){ // eslint-disable-line no-unused-vars return $JSON.stringify.apply($JSON, arguments); }; /***/ }, -/* 392 */ +/* 393 */ /***/ function(module, exports) { var core = module.exports = {version: '2.4.0'}; if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef /***/ }, -/* 393 */ +/* 394 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _stringify = __webpack_require__(390); + var _stringify = __webpack_require__(391); var _stringify2 = _interopRequireDefault(_stringify); diff --git a/src/BaseCharts/Bar.js b/src/BaseCharts/Bar.js index edccfe7..6bb8a9b 100644 --- a/src/BaseCharts/Bar.js +++ b/src/BaseCharts/Bar.js @@ -65,7 +65,7 @@ export default Vue.extend({ let chartOptions = mergeOptions(this.defaultOptions, options) this._chart = new Chart( this.$refs.canvas.getContext('2d'), { - type: type || 'bar', + type: 'bar', data: data, options: chartOptions } diff --git a/src/BaseCharts/HorizontalBar.js b/src/BaseCharts/HorizontalBar.js new file mode 100644 index 0000000..aec801f --- /dev/null +++ b/src/BaseCharts/HorizontalBar.js @@ -0,0 +1,79 @@ +import Vue from 'vue' +import Chart from 'chart.js' +import { mergeOptions } from '../helpers/options' + +export default Vue.extend({ + render: function (createElement) { + return createElement( + 'div', + [ + createElement( + 'canvas', { + attrs: { + id: this.chartId, + width: this.width, + height: this.height + }, + ref: 'canvas' + } + ) + ] + ) + }, + + props: { + chartId: { + default: 'horizontalbar-chart', + type: String + }, + width: { + default: 400, + type: Number + }, + height: { + default: 400, + type: Number + } + }, + + data () { + return { + defaultOptions: { + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + }, + gridLines: { + display: false + } + }], + xAxes: [ { + gridLines: { + display: false + }, + categoryPercentage: 0.5, + barPercentage: 0.2 + }] + } + } + } + }, + + methods: { + renderChart (data, options, type) { + let chartOptions = mergeOptions(this.defaultOptions, options) + this._chart = new Chart( + this.$refs.canvas.getContext('2d'), { + type: 'horizontalBar', + data: data, + options: chartOptions + } + ) + this._chart.generateLegend() + } + }, + beforeDestroy () { + this._chart.destroy() + } +}) diff --git a/src/examples/HorizontalBarExample.js b/src/examples/HorizontalBarExample.js new file mode 100644 index 0000000..da82590 --- /dev/null +++ b/src/examples/HorizontalBarExample.js @@ -0,0 +1,16 @@ +import HorizontalBarChart from '../BaseCharts/HorizontalBar' + +export default HorizontalBarChart.extend({ + mounted () { + this.renderChart({ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + datasets: [ + { + label: 'Data One', + backgroundColor: '#f87979', + data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11] + } + ] + }, {responsive: true, maintainAspectRatio: false}) + } +}) diff --git a/src/index.js b/src/index.js index 825f2f6..fad2508 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ import Bar from './BaseCharts/Bar' +import HorizontalBar from './BaseCharts/HorizontalBar' import Doughnut from './BaseCharts/Doughnut' import Line from './BaseCharts/Line' import Pie from './BaseCharts/Pie' @@ -9,6 +10,7 @@ import mixins from './mixins/index.js' const VueCharts = { Bar, + HorizontalBar, Doughnut, Line, Pie, @@ -23,6 +25,7 @@ export default VueCharts export { VueCharts, Bar, + HorizontalBar, Doughnut, Line, Pie, diff --git a/test/unit/specs/HorizontalBar.spec.js b/test/unit/specs/HorizontalBar.spec.js new file mode 100644 index 0000000..34c7600 --- /dev/null +++ b/test/unit/specs/HorizontalBar.spec.js @@ -0,0 +1,64 @@ +import Vue from 'vue' +import HorizontalBarChart from 'src/examples/HorizontalBarExample' + +describe('HorizontalBarChart', () => { + let el + + beforeEach(() => { + el = document.createElement('div') + }) + + it('should render a canvas', () => { + const vm = new Vue({ + render: function (createElement) { + return createElement( + HorizontalBarChart + ) + }, + components: { HorizontalBarChart } + }).$mount(el) + + expect(vm.$el.querySelector('#horizontalbar-chart')).not.to.be.an('undefined') + expect(vm.$el.querySelector('canvas')).not.to.be.an('undefined') + expect(vm.$el.querySelector('canvas')).not.to.be.an('null') + expect(vm.$el.querySelector('canvas')).to.exist + }) + + it('should change id based on prop', () => { + const vm = new Vue({ + render: function (createElement) { + return createElement( + HorizontalBarChart, { + props: { + chartId: 'horizontalbarchartprop' + } + } + ) + }, + components: { HorizontalBarChart } + }).$mount(el) + + expect(vm.$el.querySelector('#horizontalbarchartprop')).not.to.be.an('undefined') + }) + + it('should destroy chart instance', (done) => { + const vm = new Vue({ + render: function (createElement) { + return createElement( + HorizontalBarChart + ) + }, + components: { HorizontalBarChart } + }).$mount(el) + + expect(vm.$children[0]._chart.chart.ctx).not.to.be.null + + vm.$destroy() + + vm.$nextTick(() => { + vm.$forceUpdate() + expect(vm.$children[0]._chart.chart.ctx).to.be.null + done() + }) + }) +})