Category scale supports min / max

This commit is contained in:
Evert Timberg 2016-04-02 23:05:48 -04:00
parent 95bd0a54dd
commit 9ee70d6d48
2 changed files with 153 additions and 5 deletions

View File

@ -10,7 +10,24 @@ module.exports = function(Chart) {
var DatasetScale = Chart.Scale.extend({
buildTicks: function(index) {
this.ticks = this.chart.data.labels;
this.startIndex = 0;
this.endIndex = this.chart.data.labels.length;
var findIndex;
if (this.options.ticks.min !== undefined) {
// user specified min value
findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.min)
this.startIndex = findIndex !== -1 ? findIndex : this.startIndex;
}
if (this.options.ticks.max !== undefined) {
// user specified max value
findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.max);
this.endIndex = findIndex !== -1 ? findIndex : this.endIndex;
}
// If we are viewing some subset of labels, slice the original array
this.ticks = (this.startIndex === 0 && this.endIndex === this.chart.data.labels.length) ? this.chart.data.labels : this.chart.data.labels.slice(this.startIndex, this.endIndex + 1);
},
getLabelForIndex: function(index, datasetIndex) {
@ -19,10 +36,13 @@ module.exports = function(Chart) {
// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
// 1 is added because we need the length but we have the indexes
var offsetAmt = Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var valueWidth = innerWidth / Math.max((this.chart.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var widthOffset = (valueWidth * index) + this.paddingLeft;
var valueWidth = innerWidth / offsetAmt;
var widthOffset = (valueWidth * (index - this.startIndex)) + this.paddingLeft;
if (this.options.gridLines.offsetGridLines && includeOffset) {
widthOffset += (valueWidth / 2);
@ -31,8 +51,8 @@ module.exports = function(Chart) {
return this.left + Math.round(widthOffset);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
var valueHeight = innerHeight / Math.max((this.chart.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var heightOffset = (valueHeight * index) + this.paddingTop;
var valueHeight = innerHeight / offsetAmt;
var heightOffset = (valueHeight * (index - this.startIndex)) + this.paddingTop;
if (this.options.gridLines.offsetGridLines && includeOffset) {
heightOffset += (valueHeight / 2);
@ -40,6 +60,9 @@ module.exports = function(Chart) {
return this.top + Math.round(heightOffset);
}
},
getPixelForTick: function(index, includeOffset) {
return this.getPixelForValue(this.ticks[index], index + this.startIndex, null, includeOffset);
}
});

View File

@ -156,6 +156,68 @@ describe('Category scale tests', function() {
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(557);
});
it ('Should get the correct pixel for a value when horizontal and zoomed', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
config.gridLines.offsetGridLines = true;
config.ticks.min = "tick2";
config.ticks.max = "tick4";
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: mockContext,
options: config,
chart: {
data: mockData
},
id: scaleID
});
var minSize = scale.update(600, 100);
expect(scale.width).toBe(600);
expect(scale.height).toBe(28);
expect(scale.paddingTop).toBe(0);
expect(scale.paddingBottom).toBe(0);
expect(scale.paddingLeft).toBe(28);
expect(scale.paddingRight).toBe(28);
expect(scale.labelRotation).toBe(0);
expect(minSize).toEqual({
width: 600,
height: 28,
});
scale.left = 5;
scale.top = 5;
scale.right = 605;
scale.bottom = 33;
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(124);
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(396);
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(486);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(33);
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(577);
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(577);
});
it ('should get the correct pixel for a value when vertical', function() {
var scaleID = 'myScale';
@ -215,4 +277,67 @@ describe('Category scale tests', function() {
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(199);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(199);
});
it ('should get the correct pixel for a value when vertical and zoomed', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
config.gridLines.offsetGridLines = true;
config.ticks.min = "tick2";
config.ticks.max = "tick4";
config.position = "left";
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: mockContext,
options: config,
chart: {
data: mockData
},
id: scaleID
});
var minSize = scale.update(100, 200);
expect(scale.width).toBe(70);
expect(scale.height).toBe(200);
expect(scale.paddingTop).toBe(6);
expect(scale.paddingBottom).toBe(6);
expect(scale.paddingLeft).toBe(0);
expect(scale.paddingRight).toBe(0);
expect(scale.labelRotation).toBe(0);
expect(minSize).toEqual({
width: 70,
height: 200,
});
scale.left = 5;
scale.top = 5;
scale.right = 75;
scale.bottom = 205;
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(11);
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(42);
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(136);
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(168);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 1, 0, false)).toBe(11);
expect(scale.getPixelForValue(0, 1, 0, true)).toBe(11);
expect(scale.getPixelForValue(0, 3, 0, false)).toBe(199);
expect(scale.getPixelForValue(0, 3, 0, true)).toBe(199);
});
});