Luego de de nuestra extensa búsqueda de datos resolvimos esta incógnita que pueden tener algunos de nuestros usuarios. Te compartimos la solución y nuestro deseo es servirte de gran ayuda.
Solución:
EDITAR 2: Ok, en realidad necesitaba una funcionalidad como esta en un proyecto en el que estoy trabajando, así que hice una compilación personalizada de chart.js para incluir esta funcionalidad. o https://github.com/leighquince/Chart.js
Es una combinación de las dos soluciones a continuación, pero vinculada al núcleo de CHart.js, por lo que no es necesario especificar escalas y gráficos personalizados.
Tanto los gráficos de líneas como los de barras tienen una nueva opción llamada
labelsFilter:function(label, index){return false;)
por defecto, esto simplemente volverá false por lo que se mostrarán todas las etiquetas en el eje x, pero si se pasa un filtro como una opción, se filtrarán las etiquetas
así que aquí hay un ejemplo con barra y línea
var ctx = document.getElementById("chart").getContext("2d");
var data =
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
datasets: [
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
]
;
var myLineChart = new Chart(ctx).Line(data,
labelsFilter: function (value, index)
return (index + 1) % 5 !== 0;
);
RESPUESTA ORIGINAL
Puede anular la función de dibujo de escala para lograr esto. Lo único que no me gusta de esto es que se aplicará a todos sus gráficos, por lo que la otra opción es tener un tipo de gráfico personalizado que haga uso del dibujo anulado.
EDICIÓN 1: me acabo de dar cuenta de que se puede lograr el mismo efecto utilizando el valor del índice en lugar de la etiqueta y esto se puede aplicar a todos los tipos de etiquetas, no solo a los numéricos, esto se aplica a ambos ejemplos y podría cambiarse fácilmente. Aquí está el segundo ejemplo que usa el índice en lugar de la etiqueta http://jsfiddle.net/leighking2/n9c8jx55/
1o – Anulación de la función de dibujo de escala http://jsfiddle.net/leighking2/96grgz0d/
El único cambio aquí es antes de dibujar la etiqueta del eje x, probamos si la etiqueta es un número y si su resto cuando se divide por 5 no es igual a 0 (por lo que cualquier número no es divisible por 5) si coincide con ambos criterios, no lo hacemos. dibuja la etiqueta
Chart.Scale = Chart.Scale.extend(
draw : function()
console.log(this);
var helpers = Chart.helpers;
var each = helpers.each;
var aliasPixel = helpers.aliasPixel;
var toRadians = helpers.radians;
var ctx = this.ctx,
yLabelGap = (this.endPoint - this.startPoint) / this.steps,
xStart = Math.round(this.xScalePaddingLeft);
if (this.display)
ctx.fillStyle = this.textColor;
ctx.font = this.font;
each(this.yLabels,function(labelString,index)
var yLabelCenter = this.endPoint - (yLabelGap * index),
linePositionY = Math.round(yLabelCenter);
ctx.textAlign = "right";
ctx.textBaseline = "middle";
if (this.showLabels)
ctx.fillText(labelString,xStart - 10,yLabelCenter);
ctx.beginPath();
if (index > 0)
// This is a grid line in the centre, so drop that
ctx.lineWidth = this.gridLineWidth;
ctx.strokeStyle = this.gridLineColor;
else
// This is the first line on the scale
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
linePositionY += helpers.aliasPixel(ctx.lineWidth);
ctx.moveTo(xStart, linePositionY);
ctx.lineTo(this.width, linePositionY);
ctx.stroke();
ctx.closePath();
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
ctx.beginPath();
ctx.moveTo(xStart - 5, linePositionY);
ctx.lineTo(xStart, linePositionY);
ctx.stroke();
ctx.closePath();
,this);
each(this.xLabels,function(label,index)
//================================
//test to see if we draw the label
//================================
if(typeof label === "number" && label%5 != 0)
return;
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
// Check to see if line/bar here and decide where to place the line
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
isRotated = (this.xLabelRotation > 0);
ctx.beginPath();
if (index > 0)
// This is a grid line in the centre, so drop that
ctx.lineWidth = this.gridLineWidth;
ctx.strokeStyle = this.gridLineColor;
else
// This is the first line on the scale
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
ctx.moveTo(linePos,this.endPoint);
ctx.lineTo(linePos,this.startPoint - 3);
ctx.stroke();
ctx.closePath();
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
// Small lines at the bottom of the base grid line
ctx.beginPath();
ctx.moveTo(linePos,this.endPoint);
ctx.lineTo(linePos,this.endPoint + 5);
ctx.stroke();
ctx.closePath();
ctx.save();
ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
ctx.rotate(toRadians(this.xLabelRotation)*-1);
ctx.textAlign = (isRotated) ? "right" : "center";
ctx.textBaseline = (isRotated) ? "middle" : "top";
ctx.fillText(label, 0, 0);
ctx.restore();
,this);
);
entonces podemos usar los gráficos como de costumbre. Declarar datos
var ctx = document.getElementById("chart").getContext("2d");
var data =
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
datasets: [
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 34, 21, 11, 11, 34, 34, 12, 24, 45, 65, 34, 21, 11, 11, 34, 34, 12, 24, 45, 65, 34, 21, 11, 11, 34, 34, 12, 24, 45]
, ]
;
dibujar gráfico
var myLineChart = new Chart(ctx).Line(data);
2do gráfico personalizado + escala personalizada + función de filtro http://jsfiddle.net/leighking2/6xej5ek3/
En este método, todavía necesitamos crear un objeto de escala personalizado, pero en lugar de aplicarlo a todos los gráficos que creamos, podemos optar por aplicarlo solo a los que hemos declarado. Además, en este ejemplo también podemos hacer que el filtro sea una función que se aplique en el tiempo de ejecución para que podamos hacer que cada gráfico filtre las etiquetas de manera diferente
primero el objeto de escala
Chart.CustomScale = Chart.Scale.extend(
draw: function ()
console.log(this);
var helpers = Chart.helpers;
var each = helpers.each;
var aliasPixel = helpers.aliasPixel;
var toRadians = helpers.radians;
var ctx = this.ctx,
yLabelGap = (this.endPoint - this.startPoint) / this.steps,
xStart = Math.round(this.xScalePaddingLeft);
if (this.display)
ctx.fillStyle = this.textColor;
ctx.font = this.font;
each(this.yLabels, function (labelString, index)
var yLabelCenter = this.endPoint - (yLabelGap * index),
linePositionY = Math.round(yLabelCenter);
ctx.textAlign = "right";
ctx.textBaseline = "middle";
if (this.showLabels)
ctx.fillText(labelString, xStart - 10, yLabelCenter);
ctx.beginPath();
if (index > 0)
// This is a grid line in the centre, so drop that
ctx.lineWidth = this.gridLineWidth;
ctx.strokeStyle = this.gridLineColor;
else
// This is the first line on the scale
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
linePositionY += helpers.aliasPixel(ctx.lineWidth);
ctx.moveTo(xStart, linePositionY);
ctx.lineTo(this.width, linePositionY);
ctx.stroke();
ctx.closePath();
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
ctx.beginPath();
ctx.moveTo(xStart - 5, linePositionY);
ctx.lineTo(xStart, linePositionY);
ctx.stroke();
ctx.closePath();
, this);
each(this.xLabels, function (label, index)
//======================================================
//apply the filter the the label if it is a function
//======================================================
if (typeof this.labelsFilter === "function" && this.labelsFilter(label))
return;
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
// Check to see if line/bar here and decide where to place the line
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
isRotated = (this.xLabelRotation > 0);
ctx.beginPath();
if (index > 0)
// This is a grid line in the centre, so drop that
ctx.lineWidth = this.gridLineWidth;
ctx.strokeStyle = this.gridLineColor;
else
// This is the first line on the scale
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
ctx.moveTo(linePos, this.endPoint);
ctx.lineTo(linePos, this.startPoint - 3);
ctx.stroke();
ctx.closePath();
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.lineColor;
// Small lines at the bottom of the base grid line
ctx.beginPath();
ctx.moveTo(linePos, this.endPoint);
ctx.lineTo(linePos, this.endPoint + 5);
ctx.stroke();
ctx.closePath();
ctx.save();
ctx.translate(xPos, (isRotated) ? this.endPoint + 12 : this.endPoint + 8);
ctx.rotate(toRadians(this.xLabelRotation) * -1);
ctx.textAlign = (isRotated) ? "right" : "center";
ctx.textBaseline = (isRotated) ? "middle" : "top";
ctx.fillText(label, 0, 0);
ctx.restore();
, this);
);
ahora el gráfico personalizado que hará uso de esta escala, es bastante molesto tener que anular toda la función buildscale
Chart.types.Line.extend(
name: "LineAlt",
initialize: function (data) ,
buildScale: function (labels)
var helpers = Chart.helpers;
var self = this;
var dataTotal = function ()
var values = [];
self.eachPoints(function (point)
values.push(point.value);
);
return values;
;
var scaleOptions =
templateString: this.options.scaleLabel,
height: this.chart.height,
width: this.chart.width,
ctx: this.chart.ctx,
textColor: this.options.scaleFontColor,
fontSize: this.options.scaleFontSize,
//======================================================
//pass this new options to the scale object
//======================================================
labelsFilter: this.options.labelsFilter,
fontStyle: this.options.scaleFontStyle,
fontFamily: this.options.scaleFontFamily,
valuesCount: labels.length,
beginAtZero: this.options.scaleBeginAtZero,
integersOnly: this.options.scaleIntegersOnly,
calculateYRange: function (currentHeight)
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly);
helpers.extend(this, updatedRanges);
,
xLabels: labels,
font: helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth: this.options.scaleLineWidth,
lineColor: this.options.scaleLineColor,
gridLineWidth: (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor: (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
showLabels: this.options.scaleShowLabels,
display: this.options.showScale
;
if (this.options.scaleOverride)
helpers.extend(scaleOptions,
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
);
//======================================================
//Use the new Custom Scal that will make use of a labelsFilter function
//======================================================
this.scale = new Chart.CustomScale(scaleOptions);
);
entonces podemos usarlo como de costumbre. Declare los datos pero esta vez pase una nueva opción para labelsFilter que es una función para aplicar el filtrado de las etiquetas x
var ctx = document.getElementById("chart").getContext("2d");
var data =
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
labelsFilter: function (label)
//return true if this label should be filtered out
return label % 5 !== 0;
,
datasets: [
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 34, 21, 11, 11, 34, 34, 12, 24, 45, 65, 34, 21, 11, 11, 34, 34, 12, 24, 45, 65, 34, 21, 11, 11, 34, 34, 12, 24, 45]
, ]
;
luego dibuje el gráfico usando nuestro nuevo nombre de gráfico personalizado
var myLineChart = new Chart(ctx).LineAlt(data);
En general, aunque es un poco más complicado, prefiero el segundo método, ya que significa que se puede aplicar un filtro personalizado a cada gráfico que declaro.
Eres capaz de añadir valor a nuestro contenido informacional colaborando tu experiencia en las referencias.