'use strict'; module.exports = function(Chart) { // Default config for a category scale var defaultConfig = { position: 'bottom' }; var DatasetScale = Chart.Scale.extend({ /** * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those * else fall back to data.labels * @private */ getLabels: function() { var data = this.chart.data; return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels; }, determineDataLimits: function() { var me = this; var labels = me.getLabels(); me.minIndex = 0; me.maxIndex = labels.length - 1; var findIndex; if (me.options.ticks.min !== undefined) { // user specified min value findIndex = labels.indexOf(me.options.ticks.min); me.minIndex = findIndex !== -1 ? findIndex : me.minIndex; } if (me.options.ticks.max !== undefined) { // user specified max value findIndex = labels.indexOf(me.options.ticks.max); me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex; } me.min = labels[me.minIndex]; me.max = labels[me.maxIndex]; }, buildTicks: function() { var me = this; var labels = me.getLabels(); // If we are viewing some subset of labels, slice the original array me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1); }, getLabelForIndex: function(index, datasetIndex) { var me = this; var data = me.chart.data; var isHorizontal = me.isHorizontal(); if (data.yLabels && !isHorizontal) { return me.getRightValue(data.datasets[datasetIndex].data[index]); } return me.ticks[index - me.minIndex]; }, // Used to get data value locations. Value can either be an index or a numerical value getPixelForValue: function(value, index, datasetIndex, includeOffset) { var me = this; // 1 is added because we need the length but we have the indexes var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1); // If value is a data object, then index is the index in the data array, // not the index of the scale. We need to change that. var valueCategory; if (value !== undefined && value !== null) { valueCategory = me.isHorizontal() ? value.x : value.y; } if (valueCategory !== undefined || (value !== undefined && isNaN(index))) { var labels = me.getLabels(); value = valueCategory || value; var idx = labels.indexOf(value); index = idx !== -1 ? idx : index; } if (me.isHorizontal()) { var valueWidth = me.width / offsetAmt; var widthOffset = (valueWidth * (index - me.minIndex)); if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) { widthOffset += (valueWidth / 2); } return me.left + Math.round(widthOffset); } var valueHeight = me.height / offsetAmt; var heightOffset = (valueHeight * (index - me.minIndex)); if (me.options.gridLines.offsetGridLines && includeOffset) { heightOffset += (valueHeight / 2); } return me.top + Math.round(heightOffset); }, getPixelForTick: function(index, includeOffset) { return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset); }, getValueForPixel: function(pixel) { var me = this; var value; var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1); var horz = me.isHorizontal(); var valueDimension = (horz ? me.width : me.height) / offsetAmt; pixel -= horz ? me.left : me.top; if (me.options.gridLines.offsetGridLines) { pixel -= (valueDimension / 2); } if (pixel <= 0) { value = 0; } else { value = Math.round(pixel / valueDimension); } return value; }, getBasePixel: function() { return this.bottom; } }); Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig); };