Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 49 additions & 39 deletions src/scales/scale.category.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

var helpers = require('../helpers/index');
var Scale = require('../core/core.scale');

var defaultConfig = {
Expand All @@ -10,31 +11,43 @@ module.exports = Scale.extend({
determineDataLimits: function() {
var me = this;
var labels = me._getLabels();
me.minIndex = 0;
me.maxIndex = labels.length - 1;
var ticksOpts = me.options.ticks;
var min = ticksOpts.min;
var max = ticksOpts.max;
var minIndex = 0;
var maxIndex = labels.length - 1;
var findIndex;

if (me.options.ticks.min !== undefined) {
if (min !== undefined) {
// user specified min value
findIndex = labels.indexOf(me.options.ticks.min);
me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
findIndex = labels.indexOf(min);
if (findIndex >= 0) {
minIndex = findIndex;
}
}

if (me.options.ticks.max !== undefined) {
if (max !== undefined) {
// user specified max value
findIndex = labels.indexOf(me.options.ticks.max);
me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
findIndex = labels.indexOf(max);
if (findIndex >= 0) {
maxIndex = findIndex;
}
}

me.min = labels[me.minIndex];
me.max = labels[me.maxIndex];
me.minIndex = minIndex;
me.maxIndex = maxIndex;
me.min = labels[minIndex];
me.max = labels[maxIndex];
},

buildTicks: function() {
var me = this;
var labels = me._getLabels();
var minIndex = me.minIndex;
var maxIndex = me.maxIndex;

// 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);
me.ticks = (minIndex === 0 && maxIndex === labels.length - 1) ? labels : labels.slice(minIndex, maxIndex + 1);
},

getLabelForIndex: function(index, datasetIndex) {
Expand All @@ -49,61 +62,58 @@ module.exports = Scale.extend({
},

// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: function(value, index) {
getPixelForValue: function(value, index, datasetIndex) {
var me = this;
var offset = me.options.offset;

// 1 is added because we need the length but we have the indexes
var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1);
var offsetAmt = Math.max(me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1), 1);

var isHorizontal = me.isHorizontal();
var valueDimension = (isHorizontal ? me.width : me.height) / offsetAmt;
var valueCategory, labels, idx, pixel;

if (!helpers.isNullOrUndef(index) && !helpers.isNullOrUndef(datasetIndex)) {
value = me.chart.data.datasets[datasetIndex].data[index];
}

// 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 (!helpers.isNullOrUndef(value)) {
valueCategory = isHorizontal ? value.x : value.y;
}
if (valueCategory !== undefined || (value !== undefined && isNaN(index))) {
var labels = me._getLabels();
value = valueCategory || value;
var idx = labels.indexOf(value);
labels = me._getLabels();
value = helpers.valueOrDefault(valueCategory, value);
idx = labels.indexOf(value);
index = idx !== -1 ? idx : index;
}

if (me.isHorizontal()) {
var valueWidth = me.width / offsetAmt;
var widthOffset = (valueWidth * (index - me.minIndex));

if (offset) {
widthOffset += (valueWidth / 2);
}

return me.left + widthOffset;
}
var valueHeight = me.height / offsetAmt;
var heightOffset = (valueHeight * (index - me.minIndex));
pixel = valueDimension * (index - me.minIndex);

if (offset) {
heightOffset += (valueHeight / 2);
pixel += valueDimension / 2;
}

return me.top + heightOffset;
return (isHorizontal ? me.left : me.top) + pixel;
},

getPixelForTick: function(index) {
return this.getPixelForValue(this.ticks[index], index + this.minIndex, null);
return this.getPixelForValue(this.ticks[index], index + this.minIndex);
},

getValueForPixel: function(pixel) {
var me = this;
var offset = me.options.offset;
var offsetAmt = Math.max(me._ticks.length - (offset ? 0 : 1), 1);
var isHorizontal = me.isHorizontal();
var valueDimension = (isHorizontal ? me.width : me.height) / offsetAmt;
var value;
var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
var horz = me.isHorizontal();
var valueDimension = (horz ? me.width : me.height) / offsetAmt;

pixel -= horz ? me.left : me.top;
pixel -= isHorizontal ? me.left : me.top;

if (offset) {
pixel -= (valueDimension / 2);
pixel -= valueDimension / 2;
}

if (pixel <= 0) {
Expand Down
153 changes: 153 additions & 0 deletions test/specs/scale.category.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,157 @@ describe('Category scale tests', function() {
expect(yScale.getPixelForValue(0, 1, 0)).toBeCloseToPixel(107);
expect(yScale.getPixelForValue(0, 3, 0)).toBeCloseToPixel(407);
});

it('Should get the correct pixel for an object value when horizontal', function() {
var chart = window.acquireChart({
type: 'line',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: [
{x: 0, y: 10},
{x: 1, y: 5},
{x: 2, y: 0},
{x: 3, y: 25},
{x: 0, y: 78}
]
}],
labels: [0, 1, 2, 3]
},
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'category',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'linear'
}]
}
}
});

var xScale = chart.scales.xScale0;
expect(xScale.getPixelForValue({x: 0, y: 10}, 0, 0)).toBeCloseToPixel(29);
expect(xScale.getPixelForValue({x: 3, y: 25}, 3, 0)).toBeCloseToPixel(506);
expect(xScale.getPixelForValue({x: 0, y: 78}, 4, 0)).toBeCloseToPixel(29);
});

it('Should get the correct pixel for an object value when vertical', function() {
var chart = window.acquireChart({
type: 'line',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: [
{x: 0, y: 2},
{x: 1, y: 4},
{x: 2, y: 0},
{x: 3, y: 3},
{x: 0, y: 1}
]
}],
labels: [0, 1, 2, 3],
yLabels: [0, 1, 2, 3, 4]
},
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'category',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'category',
position: 'left'
}]
}
}
});

var yScale = chart.scales.yScale0;
expect(yScale.getPixelForValue({x: 0, y: 2}, 0, 0)).toBeCloseToPixel(257);
expect(yScale.getPixelForValue({x: 0, y: 1}, 4, 0)).toBeCloseToPixel(144);
});

it('Should get the correct pixel for an object value in a bar chart', function() {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: [
{x: 0, y: 10},
{x: 1, y: 5},
{x: 2, y: 0},
{x: 3, y: 25},
{x: 0, y: 78}
]
}],
labels: [0, 1, 2, 3]
},
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'category',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'linear'
}]
}
}
});

var xScale = chart.scales.xScale0;
expect(xScale.getPixelForValue(null, 0, 0)).toBeCloseToPixel(89);
expect(xScale.getPixelForValue(null, 3, 0)).toBeCloseToPixel(449);
expect(xScale.getPixelForValue(null, 4, 0)).toBeCloseToPixel(89);
});

it('Should get the correct pixel for an object value in a horizontal bar chart', function() {
var chart = window.acquireChart({
type: 'horizontalBar',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: [
{x: 10, y: 0},
{x: 5, y: 1},
{x: 0, y: 2},
{x: 25, y: 3},
{x: 78, y: 0}
]
}],
labels: [0, 1, 2, 3]
},
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'linear',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'category'
}]
}
}
});

var yScale = chart.scales.yScale0;
expect(yScale.getPixelForValue(null, 0, 0)).toBeCloseToPixel(88);
expect(yScale.getPixelForValue(null, 3, 0)).toBeCloseToPixel(426);
expect(yScale.getPixelForValue(null, 4, 0)).toBeCloseToPixel(88);
});
});