Non numeric y (#2849)

* Category scale can now read from the xLabels and yLabels properties.

* Update docs with section regarding the data object.

* Add sample file with non numeric Y and fix animations
This commit is contained in:
Evert Timberg 2016-07-09 11:22:25 -04:00 committed by Tanner Linsley
parent 72813d5112
commit b6686f00f4
5 changed files with 186 additions and 8 deletions

View File

@ -5,6 +5,17 @@ anchor: chart-configuration
Chart.js provides a number of options for changing the behaviour of created charts. These configuration options can be changed on a per chart basis by passing in an options object when creating the chart. Alternatively, the global configuration can be changed which will be used by all charts created after that point.
### Chart Data
To display data, the chart must be passed a data object that contains all of the information needed by the chart. The data object can contain the following parameters
Name | Type | Description
--- | --- | ----
datasets | Array[object] | Contains data for each dataset. See the documentation for each chart type to determine the valid options that can be attached to the dataset
labels | Array[string] | Optional parameter that is used with the [category axis](#scales-category-scale).
xLabels | Array[string] | Optional parameter that is used with the category axis and is used if the axis is horizontal
yLabels | Array[string] | Optional parameter that is used with the category axis and is used if the axis is vertical
### Creating a Chart with Options
To create a chart with configuration options, simply pass an object containing your configuration to the constructor. In the example below, a line chart is created and configured to not be responsive.

View File

@ -115,7 +115,7 @@ var chartInstance = new Chart(ctx, {
### Category Scale
The category scale will be familiar to those who have used v1.0. Labels are drawn in from the labels array included in the chart data.
The category scale will be familiar to those who have used v1.0. Labels are drawn from one of the label arrays included in the chart data. If only `data.labels` is defined, this will be used. If `data.xLabels` is defined and the axis is horizontal, this will be used. Similarly, if `data.yLabels` is defined and the axis is vertical, this property will be used. Using both `xLabels` and `yLabels` together can create a chart that uses strings for both the X and Y axes.
#### Configuration Options

View File

@ -0,0 +1,92 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
//return 0;
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'line',
data: {
xLabels: ["January", "February", "March", "April", "May", "June", "July"],
yLabels: ['', 'Request Added', 'Request Viewed', 'Request Accepted', 'Request Solved', 'Solving Confirmed'],
datasets: [{
label: "My First dataset",
data: ['', 'Request Added', 'Request Added', 'Request Added', 'Request Viewed', 'Request Viewed', 'Request Viewed'],
fill: false,
borderDash: [5, 5],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
type: 'category',
position: 'left',
display: true,
scaleLabel: {
display: true,
labelString: 'Request State'
},
ticks: {
reverse: true
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@ -9,33 +9,44 @@ module.exports = function(Chart) {
};
var DatasetScale = Chart.Scale.extend({
/**
* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use tose
* else fall back to data.labels
* @private
*/
getLabels: function() {
var data = this.chart.data;
return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
},
// Implement this so that
determineDataLimits: function() {
var me = this;
var labels = me.getLabels();
me.minIndex = 0;
me.maxIndex = me.chart.data.labels.length - 1;
me.maxIndex = labels.length - 1;
var findIndex;
if (me.options.ticks.min !== undefined) {
// user specified min value
findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.min);
findIndex = helpers.indexOf(labels, me.options.ticks.min);
me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
}
if (me.options.ticks.max !== undefined) {
// user specified max value
findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.max);
findIndex = helpers.indexOf(labels, me.options.ticks.max);
me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
}
me.min = me.chart.data.labels[me.minIndex];
me.max = me.chart.data.labels[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 === me.chart.data.labels.length - 1) ? me.chart.data.labels : me.chart.data.labels.slice(me.minIndex, me.maxIndex + 1);
me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
},
getLabelForIndex: function(index) {
@ -48,6 +59,12 @@ module.exports = function(Chart) {
// 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 !== undefined) {
var labels = me.getLabels();
var idx = labels.indexOf(value);
index = idx !== -1 ? idx : index;
}
if (me.isHorizontal()) {
var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
var valueWidth = innerWidth / offsetAmt;
@ -95,6 +112,9 @@ module.exports = function(Chart) {
}
return value;
},
getBasePixel: function() {
return this.bottom;
}
});

View File

@ -48,7 +48,7 @@ describe('Category scale tests', function() {
expect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));
});
it('Should generate ticks from the data labales', function() {
it('Should generate ticks from the data labels', function() {
var scaleID = 'myScale';
var mockData = {
@ -75,6 +75,61 @@ describe('Category scale tests', function() {
expect(scale.ticks).toEqual(mockData.labels);
});
it('Should generate ticks from the data xLabels', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
xLabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: {},
options: config,
chart: {
data: mockData
},
id: scaleID
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.xLabels);
});
it('Should generate ticks from the data xLabels', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
yLabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
config.position = 'left'; // y axis
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: {},
options: config,
chart: {
data: mockData
},
id: scaleID
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.yLabels);
});
it ('should get the correct label for the index', function() {
var scaleID = 'myScale';