Cannot read property 'canvas' of undefined - javascript

I am trying to use chartsjs to make a pie chart. I have followed the steps in the chartjs documentation and I have included chart.js and the canvas element. i added the script that should create the chart as the example provided in the chartjs documentation. I am getting the following error:
Uncaught TypeError: Cannot read property 'canvas' of undefined
Does anywhone know how to fix this? What am I doing wrong?
Thanx in advance!
HERE IS THE CODE:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="<?php echo base_url(); ?>media/js/chart.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>media/js/jquery.js"></script>
</head>
<canvas id="myChart" width="400" height="400"></canvas>
<script type="text/javascript">
$(function() {
options = {
//Boolean - Show a backdrop to the scale label
scaleShowLabelBackdrop: true,
//String - The colour of the label backdrop
scaleBackdropColor: "rgba(255,255,255,0.75)",
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero: true,
//Number - The backdrop padding above & below the label in pixels
scaleBackdropPaddingY: 2,
//Number - The backdrop padding to the side of the label in pixels
scaleBackdropPaddingX: 2,
//Boolean - Show line for each value in the scale
scaleShowLine: true,
//Boolean - Stroke a line around each segment in the chart
segmentShowStroke: true,
//String - The colour of the stroke on each segement.
segmentStrokeColor: "#fff",
//Number - The width of the stroke value in pixels
segmentStrokeWidth: 2,
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect.
animationEasing: "easeOutBounce",
//Boolean - Whether to animate the rotation of the chart
animateRotate: true,
//Boolean - Whether to animate scaling the chart from the centre
animateScale: false,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
data = [
{
value: 300,
color: "#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}
];
ctx = $("#myChart").get(0).getContext("2d");
myNewChart = new Chart(ctx[0]).Pie(data, options);
});
</script>
</html>

The problem lies on this line here:
myNewChart = new Chart(ctx[0]).Pie(data, options);
And in specifically ctx[0]. When you defined ctx here:
ctx = $("#myChart").get(0).getContext("2d");
ctx is an object called CanvasRenderingContext2D, which haves properties. You are trying to treat it as an Array when it's not. ctx[0] is therefore undefined. So the solution is actually simple, as you have found out.
Change ctx[0] to ctx, and you have your nice animated pie chart.
ctx = $("#myChart").get(0).getContext("2d");
myNewChart = new Chart(ctx).Pie(data, options);
Fiddle Here

My solution is a little different, as I wanted to have the chart change dynamically (in my application, it's moving with a slider) but avoid the awful flickering.
After standard instantiation, I update on slider drag like so:
var chartData = getChartData();
for(var i=0; i<chartData.length; i++)
{
barChart.datasets[0].bars[i].value = chartData[i];
}
barChart.update();
This animates teh change nicely, but after the animation is finished, in order to keep the weird flickering from happening when the user hovers the mouse over (the tooltip is also essential for me), I destroy and recreate the chart on mouse up as follows:
if(barChart) {
barChart.clear();
barChart.destroy();
}
chartDataObject = getChartData();
var chartData = {
labels: getChartLabels(),
datasets: [
{
label: "label",
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: chartDataObject
}
]
};
var chartContext = $("#visualizeEfficacyBar").get(0).getContext("2d");
barChart = new Chart(chartContext).Bar(chartData, { tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>", responsive : true , animate : false, animationSteps : 1 });
The important thing here is not to animate the recreation cause it leads to a very awkward visual effect, setting animate : false did not do the trick, but animationSteps : 1 did. Now no flickering, the chart is recreated and the user is none the wiser.

Related

How to display Tooltip without hovering pie chart with Chart.JS

I'm using AdminLTE and chart.js for pie charts. The question is, can i make the text visible for each arc in the pie chart without hovering mouse?
I don't use legends because some chart have a lot of labels in it.
If you have any other ways to show the all text labels i would appreciate it.
This is my current script for all my pie charts
<script>
$(function () {
//-------------
//- PIE CHART -
//-------------
// Get context with jQuery - using jQuery's .get() method.
var pieChartCanvas = $('#pieChart').get(0).getContext('2d')
var pieChart = new Chart(pieChartCanvas)
var PieData = [<?php echo $isiData; ?>]
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : '#fff',
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 0, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 150,
//String - Animation easing effect
animationEasing : 'easeOutBack',
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
//Boolean - whether to make the chart responsive to window resizing
responsive : true,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio : true,
//String - A legend template
legendTemplate : '<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
}
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
pieChart.Doughnut(PieData, pieOptions)
})
</script>
<canvas id="pieChart" style="height:400px;"></canvas>
I've had a great time on google with this problem..
Basically the way other developers solve your problem was creating a plugin which makes all the tooltips show up after the render
I found a fiddle that fixes this problem..
The fiddle is not mine..
Credits goes to Suhaib Janjua
// Show tooltips always even the stats are zero
Chart.pluginService.register({
beforeRender: function(chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function(dataset, i) {
chart.getDatasetMeta(i).data.forEach(function(sector, j) {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function(chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function(tooltip) {
tooltip.initialize();
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
// Show tooltips always even the stats are zero
var canvas = $('#myCanvas2').get(0).getContext('2d');
var doughnutChart = new Chart(canvas, {
type: 'doughnut',
data: {
labels: [
"Success",
"Failure"
],
datasets: [{
data: [45, 9],
backgroundColor: [
"#1ABC9C",
"#566573"
],
hoverBackgroundColor: [
"#148F77",
"#273746"
]
}]
},
options: {
// In options, just use the following line to show all the tooltips
showAllTooltips: true
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<canvas id="myCanvas2" width="350" height="296"></canvas>
</div>
I use onclick event and bootstrap modal for this issue and disabled Tooltip.
,onClick: function(c,i) {
e = i[0];
var x_value = this.data.labels[e._index];
var ID = x_value;
var Type =1;
$.ajax({
url: 'getsearchresults.asmx/ChartDetayGetir',
data: "{ 'ID': '" + ID + "',type:'"+Type+"'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
document.getElementById("modalheader").innerHTML = x_value;
document.getElementById("modalbody").innerHTML = data.d;
$('#myModal').modal();
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert('Failure');
}
});
}

Print pie chart in chartjs

I am having a problem with chartjs. I just
want to print what is inside div#browser with a pie chart. The chart
was fine and animated but the problem is during I print it the pie
chart disappears but when I refresh again it it was just fine. The
other charts works fine in printing except the pie chart. I believe
its reason is in the animation or something
The chartjs script
<script>
var pieChartCanvas = $("#pieChart").get(0).getContext("2d");
var pieChart = new Chart(pieChartCanvas);
var PieData = [
{
value: 700,
color: "#f56954",
highlight: "
#f56954",
label: "Chrome"
},
{
value: 500,
color: "#00a65a",
highlight: "#00a65a",
label: "IE"
},
{
value: 400,
color: "#f39c12",
highlight: "#f39c12",
label: "FireFox"
},
{
value: 600,
color: "#00c0ef",
highlight: "#00c0ef",
label: "Safari"
},
{
value: 300,
color: "#3c8dbc",
highlight: "#3c8dbc",
label: "Opera"
},
{
value: 100,
color: "#d2d6de",
highlight: "#d2d6de",
label: "Navigator"
}
];
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth: 1,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//Boolean - whether to make the chart responsive to window resizing
responsive: true,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: false,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>",
//String - A tooltip template
tooltipTemplate: "<%=value %> <%=label%> users"
};
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
pieChart.Doughnut(PieData, pieOptions);
</script>
The html
<div id="browser">
<h3 class="box-title">Browser Usage</h3>
<a onclick="printContent('browser')">Print</a>
<div class="chart-responsive">
<canvas id="pieChart" height="150"></canvas>
</div>
</div>
Print script
<script>
function printContent(el){
var restorepage = document.body.innerHTML;
var printcontent = document.getElementById(el).innerHTML;
document.body.innerHTML = printcontent;
window.print();
document.body.innerHTML = restorepage;
}
</script>
Try using the .toDataURL() method on your canvas. This method returns a URL containing your chart as an image.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
Grab your pie chart's canvas and convert it to an image: document.getElementbyId('pieChart').toDataURL;
Assign the generated chart image URL to a variable, let's keep using printContents in this case: let **printContents** = document.getElementbyId('pieChart').toDataURL;
Initiate an html document on the fly and append the previously created image URL as an <img> element's source, using template literals to embed the printContents variable: let html = <html><head><title></title></head><body><img src=${printContent}></body></html>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
-Execute the print job (Chrome) by writing the previously constructed html doc to the print window on the fly:
let **printWindow** = window.open('', 'Print-Preview', 'height=900,width=200');
printWindow.document.open();
printwindow.document.write(html);
printWindow.document.close();
Yes, it has to do with the animation. You need to check for the animation being complete. Under options add:
animation: {
onComplete: done
}
and then create a function "done" where you handle the printing.
function done() {
}

Chromium Error :- 6 Charts.js/Chartnew.js

I am trying to use the Charts.js library in my android app inside a webview. I tried changing it to chartsnew.js library too, but I get the same error and the chart does not load in my app.
D/chromium: Unknown chromium error: -6
I have tried searching all forums and questions posted before, tried double checking that the URL to my file is correct and that the JavaScript is also enabled inside.
The app originally used an ajax request to pull data, but since things were not working I tried putting the static data. The graphs load and show if I open the file directly in chrome. But shows a blank canvas in android webview.
HTML File attached :
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../general/js/ChartNew.js"></script>
<script src="../general/js/shapesInChart.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<canvas id="myChart" width="400" height="400"></canvas>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
options = {
//Boolean - If we show the scale above the chart data
scaleOverlay : false,
//Boolean - If we want to override with a hard coded scale
scaleOverride : false,
//** Required if scaleOverride is true **
//Number - The number of steps in a hard coded scale
scaleSteps : null,
//Number - The value jump in the hard coded scale
scaleStepWidth : null,
//Number - The scale starting value
scaleStartValue : null,
//String - Colour of the scale line
scaleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the scale line
scaleLineWidth : 1,
//Boolean - Whether to show labels on the scale
scaleShowLabels : false,
//Interpolated JS string - can access value
scaleLabel : "<%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily : "'Arial'",
//Number - Scale label font size in pixels
scaleFontSize : 12,
//String - Scale label font weight style
scaleFontStyle : "normal",
//String - Scale label font colour
scaleFontColor : "#666",
///Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 1,
//Boolean - Whether to animate the chart
animation : true,
//Number - Number of animation steps
animationSteps : 60,
//String - Animation easing effect
animationEasing : "easeOutQuart",
//Function - Fires when the animation is complete
onAnimationComplete : null
};
var data = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : [28,48,40,19,96,27,100]
}
]
}
ctx = $("#myChart").get(0).getContext("2d");
myNewChart = new Chart(ctx).Bar(data, options);
});
</script>
</html>
EDIT 1 :
ok So I was not able to load the local HTML file inside the android web-view, no matter what I tried. But then I still moved ahead and tried to modify my code to get the dynamic data from an ajax request. Surprisingly, it has started working on the dynamic data
Here is my code for the dynamic pull :
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../general/js/Chart.js"></script>
<script src="../general/js/Chartjs.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<canvas id="myChart" width="350" height="350"></canvas>
<script type="text/javascript" charset="utf-8">
var id=replaceName;
var regDate = replaceDate;
$(document).ready(function() {
$.ajax({
url:"<serverurl>customer/betGetBloodPressure.jsp",
data:{"id":id,"regDate":regDate},
type:"post",
dataType:"jsonp",
jsonp: "callback",
success: function(res) {
options = {
//Boolean - If we show the scale above the chart data
scaleOverlay : false,
//Boolean - If we want to override with a hard coded scale
scaleOverride : true,
//** Required if scaleOverride is true **
//Number - The number of steps in a hard coded scale
scaleSteps : 3,
//Number - The value jump in the hard coded scale
scaleStepWidth : 50,
//Number - The scale starting value
scaleStartValue : 0,
//String - Colour of the scale line
scaleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the scale line
scaleLineWidth : 1,
//Boolean - Whether to show labels on the scale
scaleShowLabels : true,
//Interpolated JS string - can access value
scaleLabel : "<%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily : "'sans-serif'",
//Number - Scale label font size in pixels
scaleFontSize : 12,
//String - Scale label font weight style
scaleFontStyle : "normal",
//String - Scale label font colour
scaleFontColor : "#666",
///Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 0,
//Boolean - Whether to animate the chart
animation : true,
//Number - Number of animation steps
animationSteps : 60,
//String - Animation easing effect
animationEasing : "easeOutQuart",
//Function - Fires when the animation is complete
onAnimationComplete : null,
spaceBetweenBar : 0 ,
// String or array - fill color when hovered
hoverBackgroundColor: "rgba(255,99,132,0.4)",
// String or array - border color when hovered
hoverBorderColor: "rgba(255,99,132,1)"
};
var data = {
labels : ['MIN BP', 'AVERAGE BP', 'MAX BP'],
datasets :
[
{
label: 'Max Average Of Age #',
fillColor: '#a280ff',
data: [parseInt(res.aoa_lower_low),parseInt(res.aoa_avg_low),parseInt(res.aoa_higer_low)],
yAxisID: "y-axis-0"
},
{
label: 'My Info. #',
fillColor: '#7c4dff',
data: [parseInt(res.my_low),parseInt(res.my_avg),parseInt(res.my_high)]
},
{
label: 'Min Average Of Age #',
fillColor: '#6933ff',
data: [parseInt(res.aoa_lower_high),parseInt(res.aoa_avg_high),parseInt(res.aoa_higer_high)]
}
]
};
scaleSteps = 10;
ctx = $("#myChart").get(0).getContext("2d");
myNewChart = new Chart(ctx).Bar(data,options);
}
});
});
</script>
</html>
Now am struggling with one last problem, as seen in the screenshot my graph appears, but am not able to show the label values which can show me what each of my color indicates defined as the "label" parameter in the above code inside the datasets. Looks like I am missing something I need to define in my options, but not able to find out what. Please help
Graph pulled from AJAX Request
okay so I finally found the solution to the problem of my second EDIT in which label values descriptions for my color was not showing up.
Just added :
multiTooltipTemplate: "<%= datasetLabel %> - <%= value %>"
to my options. And awesome it works now. :)
Working Sample Image

Customizing Chart.js troubleshoot

Have some trouble with Chart.js
1) is it possible to move bottom labels on top of the chart?
2) is it possible to hide left labels with first grey line?
3) is it possible to set up permanent tooltips(to show temperature) on every point instead of hover tooltips?
Here is my chart http://jsfiddle.net/JohnnyJuarez/ojc09hv4/:
<canvas id="weeksChart" width="651" height="335"></canvas>
var dayTemperatureArray = [-5, 14, 15, 15, 17, 18, 19, 21, 22, 25, 24, 20, 19, 16];
var nightTemperatureArray = [-10, 4, 5, 6, 8, 11, 12, 15, 17, 15, 13, 12, 11, 9];
var dataWeeks = {
labels: ["16.02", "17.02", "18.02", "19.02", "20.02", "21.02", "22.02", "23.02", "24.02", "25.02", "26.02", "27.02", "28.02", "01.03"],
datasets: [
{
label: "Days temperature chart",
fillColor: "transparent",
strokeColor: "rgba(244, 6, 6, 1)",
data: dayTemperatureArray
},
{
label: "Nights temperature chart",
strokeColor: "#3f6bf5",
data: nightTemperatureArray
}
]
};
var ctx = document.getElementById("weeksChart").getContext("2d");
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
responsive: true,
pointDot: true,
datasetStrokeWidth: 0.5,
scaleSteps: 2,
scaleLabel: "<%=value + '°'%>",
tooltipTemplate: "<%= value %>",
showTooltips: true
});
Thanx a lot in advance!
p.s. please avoid jquery, if it's possible :-)
Let's start with the easiest one first
2) is it possible to hide left labels with first grey line?
I assume you meant the y axis labels. You can set the scaleShowLabels option to false in the chart options to hide the y axis labels
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
scaleShowLabels: false,
...
1) is it possible to move bottom labels on top of the chart?
I assume you mean the x axis labels. Chart.js doesn't have a direct option to do this. However you can hide the actual x axis labels and draw the x axis labels at the top of the chart by yourself.
Again, Chart.js doesn't have an option to hide x axis labels, but luckily there is an option to control the scale font color. Just set it to transparent and your original x axis labels are now hidden!
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
scaleFontColor: "transparent",
...
Now the drawing of the x axis labels at the top of the chart. To save us the trouble of extending the chart, we can add a post animation event handler and do this in that, like so
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
onAnimationComplete: function () {
animationComplete.apply(this)
}
...
with
var animationComplete = function () {
var self = this;
Chart.helpers.each(self.datasets[0].points, function (point, index) {
self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
self.chart.ctx.textAlign = 'center';
self.chart.ctx.textBaseline = "middle";
self.chart.ctx.fillStyle = "#666";
self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
});
};
We just loop through all points in one of the dataset and add the labels (scale.startPoint is the top edge of the chart area)
Note - why do we set the font, alignment, etc. every iteration? That's for when we add the tooltips.
3) is it possible to set up permanent tooltips(to show temperature) on every point instead of hover tooltips?
The first step would be to actually show the tooltips. This is fairly simple, though a bit tedious. We loop through all the x axis point, build the label (by going through each dataset) and then construct a tooltip (fortunately, we can use Chart.MultiTooltip function for this.
We add it into the same loop we used to construct the new x axis labels. Since we need to color our tooltips, we need to get and store the set of colors in an array (which we pass on to the MultiTooltip function - we need to do this only once, so we take it out of the loop.
The modified animationComplete function is now this
var animationComplete = function () {
var self = this;
var tooltipColors = []
Chart.helpers.each(self.datasets, function (dataset) {
tooltipColors.push({
fill: dataset.strokeColor,
stroke: dataset.strokeColor
})
});
Chart.helpers.each(self.datasets[0].points, function (point, index) {
var labels = []
var total = 0;
Chart.helpers.each(self.datasets, function (dataset) {
labels.push(dataset.points[index].value)
total += Number(dataset.points[index].y);
});
new Chart.MultiTooltip({
x: point.x,
y: total / 2,
xPadding: self.options.tooltipXPadding,
yPadding: self.options.tooltipYPadding,
xOffset: self.options.tooltipXOffset,
fillColor: self.options.tooltipFillColor,
textColor: self.options.tooltipFontColor,
fontFamily: self.options.tooltipFontFamily,
fontStyle: self.options.tooltipFontStyle,
fontSize: self.options.tooltipFontSize,
titleTextColor: self.options.tooltipTitleFontColor,
titleFontFamily: self.options.tooltipTitleFontFamily,
titleFontStyle: self.options.tooltipTitleFontStyle,
titleFontSize: self.options.tooltipTitleFontSize,
cornerRadius: self.options.tooltipCornerRadius,
labels: labels,
legendColors: tooltipColors,
legendColorBackground: self.options.multiTooltipKeyBackground,
title: point.label,
chart: self.chart,
ctx: self.chart.ctx,
custom: self.options.customTooltips
}).draw()
self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
self.chart.ctx.textAlign = 'center';
self.chart.ctx.textBaseline = "middle";
self.chart.ctx.fillStyle = "#666";
self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
});
};
It looks complex, but all we are doing is passing a options that we copy from the chart instance options to the MultiTooltip function.
The tooltips all show up when the animation is complete. HOWEVER, once you move your mouse over the chart they all up and disappear! That's because the chart instance listens for multiple events to decide whether to start checking if tooltips should be shown - one of these is mousemove (and that causes it to redraw the chart, wiping out all our hard drawn tooltips and, if we are lucky, it draws a tooltip based on the point our mouse is hovering over)
This is a configurable option. So, all we have to do is remove all such events.
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
tooltipEvents: []
...
Working fiddle - http://jsfiddle.net/fuodxsfv/
Unless your chart is wide enough, you will have tooltips (mostly the middle 2 ones) overlap (of course you could incorporate logic into the above loop to handle that), but anyhoo, those were actually meant to be tooltips!

How to add jqplot pie chart labels with lines?

I have a pie chart and I can add labels for it normal way.But I want to add labels with line as following.
I took this image from web as a example. here is my code ,
drawPieCharts = function(dev,title,data){
$('#'+dev).empty();
var plot = $.jqplot(dev, [data], {
title: {
text: title,
fontWeight: 'bold',
fontSize : '16',
show: true
},
grid: {
drawBorder: false,
drawGridlines: false,
background: '#ffffff',
shadow:false,
//diameter : 30
},
axesDefaults: {
},
highlighter: {
show: true,
formatString:'%s , P%',
tooltipLocation:'n',
useAxesFormatters:false
},
seriesDefaults:{
renderer:$.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true,
dataLabelThreshold: 0,
dataLabelPositionFactor: 1.05,
dataLabels : mapSeperater(data)[0],
padding: 2
}
},
});
}
And also I have another problem I want to bold the title of the chart and in this way it doesn't work. Is there a way to do that?
Thank you.
i'm looking for the same, not successful yet.
but for the title maybe you can try to style the div with the class "jqplot-title", that's where the title is rendered.
in jquery would be something like that:
$(".jqplot-title").wrap("<b></b>")
EDIT:
sorry i had no time to jsfiddle it, but you can try it and get the idea. looks a little awful but you can make it better.
what i did was putting labels of the slices outside the pie and draw some lines from the center to these labels.
..i came with something like this:
series: [{
renderer: $.jqplot.PieRenderer,
rendererOptions: {
diameter: 140,
showDataLabels: true,
dataLabelThreshold: 0, //minimum area to show a label, (i want all the labels)
dataLabelPositionFactor: 2.3, //in function of the radius, how far show the label
dataLabels: 'label',
dataLabelFormatString: '%s',
//(just more options, etc, etc)
plot = $.jqplot("myDivHere", [data], options).replot(); // <-- that's for me
// ******************************
// HERE COMES THE MAGIC:
//
var w = $("#myDivHere .jqplot-series-shadowCanvas").width();
var h = $("#myDivHere .jqplot-series-shadowCanvas").height();
x1 = (w/2);
y1 = (h/2);
var canvas = $("#myDivHere .jqplot-series-shadowCanvas")[0];
var context = canvas.getContext('2d');
$(".jqplot-pie-series.jqplot-data-label").each(
function(){
var l = $(this).position().left;
var t = $(this).position().top;
console.log("x1, y1 are: ["+x1+", "+y1+"]\n l, t are ["+l+", "+t+"]");
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(l, t);
context.stroke();
});
I have no more time to work on this this week, so you could use it as awful it is and make it better. or wait for a better solution to show up.
Greetings!!
Ahh, and if you can make it better, please share it with me.

Categories