how to give break line in data label , Till what i have done below is link and i have pasted code here also.
And i am using custom datalabel and i want to add break line
https://jsfiddle.net/0x3ct8aq/4/
<script>
onComplete () {
const chartInstance = this.chart;
const ctx = chartInstance.ctx;
const dataset = this.data.datasets[0];
const meta = chartInstance.controller.getDatasetMeta(0);
Chart.helpers.each(meta.data.forEach((bar, index) => {
const label = this.data.customlabels[index];
const labelPositionX = 20;
const labelWidth = ctx.measureText(label).width + labelPositionX;
ctx.textBaseline = 'bottom';
ctx.textAlign = 'center';
ctx.fillStyle = '#fff';
console.log(label.x);
ctx.fillText(label, bar._model.x, bar._model.y);
}));
}
}
},
});
</script>
Inside the animation.onComplete() function, you can reverse() the labels array, then draw individual tokens using forEach() as follows:
label.reverse().forEach((l, i) => ctx.fillText(l, bar._model.x, bar._model.y - (i * 16)))
Please have a look at your amended JSFiddle
Related
trying to extend a chart, so that i can draw lines up to the data point, but this is happening before the default animation. it would look smoother if it applied after.
i have got most of it to work.. but how do i get this to apply after chart animation.
var originalLineDraw = Chart.controllers.line.prototype.draw;
Chart.helpers.extend(Chart.controllers.line.prototype, {
draw: function () {
originalLineDraw.apply(this, arguments);
var chart = this.chart;
var ctx = chart.chart.ctx;
var index = chart.config.data.lineAtIndex;
if (index) {
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-1']
var points = this.chart.getDatasetMeta(this.index).data;
for (var i = 0; i < points.length; i++) {
// var point_x = points[i]._model.x;
var point_y = points[i]._model.y;
ctx.beginPath();
ctx.setLineDash([5, 5]);/*dashes are 5px and spaces are 3px*/
ctx.moveTo(xaxis.getPixelForValue(undefined, i), point_y);
ctx.strokeStyle = '#fff';
ctx.lineTo(xaxis.getPixelForValue(undefined, i), yaxis.bottom);
ctx.stroke();
}
}
}
});
Update...
altho the darw is incorrect it still is playing after animation
var verticalLinePlugin = {
renderVerticalLine: function (chartInstance) {
var chart = chartInstance;
var ctx = chart.chart.ctx;
var maxpoint = [];
//loop the datasets
for (var y = 0; y < chart.config.data.datasets.length; y++) {
var dataset = chart.config.data.datasets[y];
if (dataset.hidden)
continue;
var points = chart.getDatasetMeta(y).data;
for (var i = 0; i < points.length; i++) {
var point_y = points[i]._model.y;
if (point_y < 0)
continue;
var point = maxpoint[i];
if (point == undefined) {
maxpoint.push({ id: i, y: point_y });
} else {
if (point.y > point_y) {
point.y = point_y;
}
}
}
}
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-1']
chart.data.datasets.forEach(function (dataset, i) {
var ds = dataset;
var meta = chart.getDatasetMeta(i);
meta.data.forEach(function (element, index) {
var value = maxpoint[i];
ctx.beginPath();
ctx.setLineDash([5, 5]);
ctx.moveTo(xaxis.getPixelForValue(undefined, i), value.y);
ctx.strokeStyle = '#fff';
ctx.lineTo(xaxis.getPixelForValue(undefined, i), yaxis.bottom);
ctx.stroke();
});
});
},
afterRender: function (chart) {
this.renderVerticalLine(chart);
}
};
Chart.plugins.register(verticalLinePlugin);
I made some small changes (non-intuitive!), and the vertical lines now appear after the animation.
Get the x values from the metadata instead of the data.
Either:
var x_point = element._model.x;
or:
var position = element.tooltipPosition();
var x_point = position.x;
Wrap the drawing in if(!hidden){}, then the vertical lines will disapear and reappear with the data. (The ternary assignment fixes a clash if the data starts hidden)
Do you need the value=max[i]? If just drawing the line up to the points, can get the y_point the same as for x.
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-1'];
chart.data.datasets.forEach(function (dataset, i) {
var meta = chart.getDatasetMeta(i);
var hidden = (meta.hidden != undefined) ? meta.hidden : dataset.hidden
if(!hidden){
meta.data.forEach(function (element, index) {
//var value = maxpoint[i];
var x_point = element._model.x;
var y_point = element._model.y;
ctx.beginPath();
ctx.save();
ctx.setLineDash([5, 5])
ctx.strokeStyle = '#fff';
ctx.moveTo(x_point, y_point); // or value.y
ctx.lineTo(x_point, yaxis.bottom)
ctx.stroke();
ctx.restore();
});
}
});
I have a mixed chart of bar and line graphs. Both are showing their data labels but I only want the bar graph to show its own data labels and not the line graph.
I've got this code from How to show data values or index labels in ChartJs (Latest Version)
How should I tweak it?
animation: {
onComplete: function() {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.data.datasets.forEach(function (dataset)
{
for( var i = 0; i < dataset.data.length; i++ )
{
for(var key in dataset._meta)
{
var model = dataset._meta[key].data[i]._model;
ctx.fillText(dataset.data[i], model.x, model.y+15);
}
}
});
}
}
I was able to generate pie chart successfully. However, when I was trying to add a select event listener to the pie chart, it is not triggering the function at all.
function handlePieChartResponse(response)
{
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var dataTable = response.getDataTable();
if (dataTable.getNumberOfRows() <= 0) {
document.getElementById('dummyTableRow').innerHTML = '<span>No data found</span>';
return;
}
var chartOptions = DEFAULT_PIE_CHART_OPTIONS;
//var chartOverallPmmLevelCalculated = new google.visualization.ChartWrapper({
// 'chartType': 'PieChart',
// 'containerId': 'chartOverallPmmLevelCalculatedHtml',
// options: chartOptions
//});
var chartRecentPmmLevelCalculated = new google.visualization.PieChart(document.getElementById('chartOverallPmmLevelCalculatedHtml'));
chartRecentPmmLevelCalculated.draw(dataTable, chartOptions);
google.visualization.events.addListener(chartRecentPmmLevelCalculated, 'ready', function () { drawPieChart(); });
google.visualization.events.addListener(chartRecentPmmLevelCalculated, 'select', function () { selectHandler(); });
function drawPieChart() {
var responseDataTable = response.getDataTable();
var chartDataTable = new google.visualization.DataTable();
chartDataTable.addColumn('string', 'LEVEL');
chartDataTable.addColumn('number', 'SCORE');
var chartDataTableRow = new Array();
var rowCounter;
var levelValue;
for (rowCounter = 0; rowCounter < responseDataTable.getNumberOfRows() ; rowCounter++) {
var seek = 0 * 1;
levelValue = responseDataTable.getValue(rowCounter, 0);
chartDataTableRow[seek++] = "LEVEL " + levelValue;
chartDataTableRow[seek++] = responseDataTable.getValue(rowCounter, 1);
chartDataTable.addRow(chartDataTableRow);
}
chartDataTable.sort([{ column: 1 }]);
chartOverallPmmLevelCalculated.setDataTable(chartDataTable);
chartOverallPmmLevelCalculated.draw();
}
handlePieChartResponse.drawPieChart = drawPieChart;
}
function selectHandler() {
alert("This alert triggered from pie chart");
var selectedItem = chartRecentPmmLevelCalculated.getSelection();
if (selectedItem) {
var levelSelected = chartOverallPmmLevelCalculated.getValue(selectedItem.row, 0);
alert(levelSelected);
}
}
I attached 2 images that include before and after the click. I was expecting alert message once select on pie chart slice. But no alert is present and the function call is not triggered.
problem has to do with scope
selectHandler is outside of the function handlePieChartResponse
so it can't be found
just move it inside handlePieChartResponse
then set the event, like so...
...addListener(chartRecentPmmLevelCalculated, 'select', selectHandler);
Can you help me how to extend Chart.js v2.0. I need to draw some horizontal lines in the charts, something similar to: http://jsfiddle.net/vsh6tcfd/3/
var originalLineDraw = Chart.controllers.bar.prototype.draw;
Chart.helpers.extend(Chart.controllers.bar.prototype, {
draw: function() {
originalLineDraw.apply(this, arguments);
var chart = this.chart;
var ctx = chart.chart.ctx;
var index = chart.config.data.lineAtIndex;
if (index) {
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-0'];
ctx.save();
ctx.beginPath();
ctx.moveTo(xaxis.getPixelForValue(undefined, index), yaxis.left);
ctx.strokeStyle = '#ff0000';
ctx.lineTo(xaxis.getPixelForValue(undefined, index), yaxis.right);
ctx.stroke();
ctx.restore();
}
}
});
var config = {
type: type,
data: jQuery.extend(true, {}, data),
options: this.chartdata.options,
lineAtIndex: 2
};
new Chart(ctx, config);
Options
With chart.js you have 2 options.
You could create a mix chart types (Example Here). This would allow you to add a line charts to create your lines.
You could create a plugin (See Example Below).
Option 2 would be the one I recommend as it allows you to have more control over the appearance of the lines.
The Fix
demo of the plugin
Chart.js now supports plugins. This allows you to add any features you want to your charts!
To create a plugin you will need to run code after an event has occurred and modify the chart/canvas as needed.
The following code should give you a good starting point:
var horizonalLinePlugin = {
afterDraw: function(chartInstance) {
var yValue;
var yScale = chartInstance.scales["y-axis-0"];
var canvas = chartInstance.chart;
var ctx = canvas.ctx;
var index;
var line;
var style;
if (chartInstance.options.horizontalLine) {
for (index = 0; index < chartInstance.options.horizontalLine.length; index++) {
line = chartInstance.options.horizontalLine[index];
if (!line.style) {
style = "rgba(169,169,169, .6)";
} else {
style = line.style;
}
if (line.y) {
yValue = yScale.getPixelForValue(line.y);
} else {
yValue = 0;
}
ctx.lineWidth = 3;
if (yValue) {
ctx.beginPath();
ctx.moveTo(0, yValue);
ctx.lineTo(canvas.width, yValue);
ctx.strokeStyle = style;
ctx.stroke();
}
if (line.text) {
ctx.fillStyle = style;
ctx.fillText(line.text, 0, yValue + ctx.lineWidth);
}
}
return;
}
}
};
Chart.pluginService.register(horizonalLinePlugin);
I'm using Chartjs to draw some bar charts, I would like to show on the top of each bar the related value, I have not seen any parameters allowing to do that in the documentation.
Is there any way to do that?
You can try
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.bars.forEach(function (bar) {
ctx.fillText(bar.value, bar.x, bar.y - 5);
});
})
}
used following link
http://jsfiddle.net/TZq6q/304/
set "inGraphDataShow: true" in your code it will display all values on top of bar