Related
So, I have a form with a starting date, an end date and a selector so you can choose which server (selected by id) you'd like to select data from, and returns a json string with the day, temperature and server id. everything works just fine here.
My issue comes when I tried to make it so when you don't select a server, it gives you all data from all servers (select stuff from table where id like '%'). I adapted my chart generating function to this:
function generateChart(data) {
var results = JSON.parse(data);
if (results.error == true) {
var errCode = results.code;
var errText = results.text;
defineError(errCode, errText);
}
else {
var chartjsTemp = [];
var chartjsDate = [];
if (results.length > 1) {
for (var i = 1; i < results.length; i++) {
chartjsTemp.push(results[i].probeTemp);
chartjsDate.push(results[i].dateProbe);
}
}
else {
alert ("No results!");
}
var ctx = document.getElementById('myChart').getContext('2d');
var button = $("#submitButton");
submitButton.addEventListener("click", function(){
myChart.destroy();
});
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: chartjsDate,
datasets: [{
label: 'temp',
data: chartjsTemp,
backgroundColor: "rgba(240,240,240,0.5)"
}]
}
});
}
}
I don't know how to adapt the datasets part so if I have an unknown number of servers with different values for data, (might return 3 servers or 5 different servers, depending on the database used) to be generated automatically instead of having to do a dataset for every existing server (which means I'd have to do a function for each database with each server).
Edit: This is an example of what happens if I leave it like this (which obviously is not good): http://imgur.com/a/IgH2c
Edit 2: Okay, doing a for loop like this:
for (i=0; i >= chartjsId.length; i++) {
datasets: [{
label: chartjsId[i],
data: chartjsTemp,
backgroundColor: "rgba(240,240,240,0.5)"
}]
}
didn't work much at all. I get a slim framework error.
What I understand, you have draw all the charts you want and know you want to hide all other and show the selected ones.
We can achieve this through Legends, when user click on the legend its display will toggle from graph.
Or we can achieve like this jsFiddle
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "First",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,20,20,1)",
pointColor: "rgba(220,20,20,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 90]
}, {
label: "Second",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(15,187,25,1)",
pointColor: "rgba(15,187,25,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [38, 55, 50, 65, 35, 67, 54]
}]
};
var options = {
// String - Template string for single tooltips
tooltipTemplate: "<%if (label){%><%=label %>: <%}%><%= value + ' %' %>",
// String - Template string for multiple tooltips
multiTooltipTemplate: "<%= value + ' %' %>",
};
var ctx = document.getElementById("myChart").getContext("2d");
window.myLineChart = new Chart(ctx).Line(data, options);
window.myLineChart.store = new Array();
$('#selectbox').change(function () {
var label = $('#selectbox').val();
var chart = window.myLineChart;
var store = chart.store;
var finded = false;
//Restore all
for (var i = 0; i < store.length; i++) {
var restored = store.splice(i, 1)[0][1];
chart.datasets.push(restored);
}
//Если нет, то добавляем в стор
if (label!='All') {
console.log('Start search dataset with label = ' + label);
for (var i = 0; i < chart.datasets.length; i++) {
if (chart.datasets[i].label === label) {
chart.store.push([label, chart.datasets.splice(i, 1)[0]]);
}
}
}
chart.update();
});
My Code:
<div><canvas id="canvas_line" height="200" width="800"></canvas></div>
<div><canvas id="canvas_bar" height="200" width="800"></canvas></div>
<script>
var lineChartData = {
labels : ["14:00","15:00","16:00","17:00","18:00","19:00","20:00","22:00"],
datasets : [
{
label: "CPU IDLE",
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 : [85,35,65,59,90,81,56,55,40,100]
}
]
}
var barChartData = {
labels : ["12:00","13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","22:00"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [85,35,65,59,90,81,56,55,40,100]
}
]
}
var ctx_line = document.getElementById("canvas_line").getContext("2d");
window.myLine = new Chart(ctx_line).Line(lineChartData, {
responsive: true
});
var ctx_bar = document.getElementById("canvas_bar").getContext("2d");
window.myLine = new Chart(ctx_bar).Bar(barCharData, {
responsive: true
});
</script>
It looks like this, everything is grey.
But I'd like to change the lineChart's pointColor and barChart's fillcolor to red if its data is above 80, the data below 80 are still grey.
I want it like this, but I don't know how to use different colors in a canvas.
<!DOCTYPE html>
<html>
<head>
<title>123</title>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="http://apps.bdimg.com/libs/Chart.js/0.2.0/Chart.min.js"></script>
</head>
<body>
<canvas id="chartCanvas" height="200" width="800"></canvas>
<script>
$(document).ready(function() {
var chartData = {
labels: ["12:00","13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","22:00"],
datasets: [
{
data : [85,35,65,59,90,81,56,55,40,100],
fillColor: 'rgba(220,220,220,0.2)',
strokeColor: 'rgba(220,220,220,1)'
}
]
}
var chartCanvas = document.getElementById("chartCanvas").getContext("2d");
var barChart = new Chart(chartCanvas).Bar(chartData, {responsive: true});
// Set warning color
var bars = barChart.datasets[0].bars;
for(var i = 0; i < bars.length ; i++) {
if(bars[i].value > 80) {
bars[i].fillColor = "rgba(255, 0, 0, 0.2)";
bars[i].strokeColor = "rgba(220, 0, 0, 0.5)";
}
}
// Update the chart
barChart.update();
});
</script>
</body>
</html>
You have to loop to all the bars/points of your chart, check if the value is over 80 and set the color.
Here is an example for the bar chart:
var bars = barChart.datasets[0].bars;
for(var i = 0; i < bars.length; i++) {
if(bars[i].value > 80) {
bars[i].fillColor = "rgba(255, 0, 0, 0.2)";
bars[i].strokeColor = "rgba(220, 0, 0, 0.5)";
}
}
// Update the chart
barChart.update();
Check out this fiddle for a working demo.
To set the color on a line chart you just have to iterate over the points instead of the bars:
var points = lineChart.datasets[0].points;
And of course set the pointColor or whatever you want.
Hi I'm creating some Charts for my server monitoring. I'm getting the Data with Php and pass it over as an Array to the javasccript:
<script>
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var obj = JSON.parse('<?php echo json_encode($names) ?>');
var datenbarchart = obj.join(",");
var obj1 = JSON.parse('<?php echo json_encode($nameserver) ?>');
var barChartData = {
labels : [ obj1[0], obj1[1], obj1[2], obj1[3], obj1[4], obj1[5], obj1[6]],
datasets : [
{
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 : [datenbarchart]
}
]
}
window.onload = function(){
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, {
responsive : true
});
}
</script>
The problem part is, where I try to separate the first array with the join Method to get a String separated by ",":
var datenbarchart = obj.join(",");
When I pass this over to the Chartjs Data where normally the Data looks like that: data: [60,50,40,50] It doesn't show any Data in the Chart. Isn't it possible to do that with a string, because it takes the whole string for every bar?
According to http://www.chartjs.org/docs/
data field is an Array so your syntax should be:
var datenbarchart = obj;
...
var barChartData = {
labels : [ obj1[0], obj1[1], obj1[2], obj1[3], obj1[4], obj1[5], obj1[6]],
datasets : [
{
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 : datenbarchart
}
]
}
I'm trying to make a Graph which has to show the Account movement from each Customer.
What I'm trying to do
I've tree lines ;
First line : The minimum balance, if the customer has less than the min. balance, his balance will auto load from his bank account.
Second Line : The current balance
Third Line: The maximum balance : If the customer has more than the max. balance he will become the difference from the system on his bank account.
My Problem
Link to the picture : chartjs tooltip problem
As you see in the tooltip are the all 3 values. The values of the straight lines are irrelevant for the customer because the Limits (max and min are setted from the customer his own) .
To achieve this you can extend the line graph to add an option to show/hide tool-tips on a per dataset basses. The annoying thing is there are only a few changes but whole methods have to be overridden to get the changes in there so the below looks like a lot but its basically 3 changes to the following methods
Initialize - added option to store showTooltip option in each point
getPointsAtEvent - added check to make sure we want to disaply a tool tip when getting points
showTooltip - added check again to make sure we want to dispaly a tool tip
to then use it the chart is set up the same but instead you make it a LineTooltip (thats what i have called the extended chart) and pass anextra option in the datasets call showToolip.
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)",
showTooltip: false, //NEW OPTION DON"T NEED TO INCLUDE IT IF YOU WANT TO DISPLAY BUT WON"T HURT IF YOU DO
data: [15, 10, 10, 10, 10, 10, 10]
}, {
label: "My second 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)",
showTooltip: false, //NEW OPTION DON"T NEED TO INCLUDE IT IF YOU WANT TO DISPLAY BUT WON"T HURT IF YOU DO
data: [100, 100, 100, 100, 100, 100, 100]
}, {
label: "My third dataset",
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: [28, 48, 40, 19, 86, 27, 90]
}]
i have added bigger comment banners in the below code to try and highlight where the changes got made. I have also added this feature to my fork of chartjs as this could be useful to more people https://github.com/leighquince/Chart.js, using this you can just use a normal line chart and add the showTooltip
Below is the example of extending the Line into a custom chart to include this feature, ive called in LineTooltip as but could be called anything you like that.
Chart.types.Line.extend({
name: "LineTooltip",
/*
* we have to add one item in the init so need to rewrite it again here with the one edit
*/
initialize: function(data) {
//have to get the helpers as we are using this outside chart where it was declared
var helpers = Chart.helpers;
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.PointClass = Chart.Point.extend({
strokeWidth: this.options.pointDotStrokeWidth,
radius: this.options.pointDotRadius,
display: this.options.pointDot,
hitDetectionRadius: this.options.pointHitDetectionRadius,
ctx: this.chart.ctx,
inRange: function(mouseX) {
return (Math.pow(mouseX - this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius, 2));
}
});
this.datasets = [];
//Set up tooltip events on the chart
if (this.options.showTooltips) {
helpers.bindEvents(this, this.options.tooltipEvents, function(evt) {
var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
this.eachPoints(function(point) {
point.restore(['fillColor', 'strokeColor']);
});
helpers.each(activePoints, function(activePoint) {
activePoint.fillColor = activePoint.highlightFill;
activePoint.strokeColor = activePoint.highlightStroke;
});
this.showTooltip(activePoints);
});
}
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets, function(dataset) {
var datasetObject = {
label: dataset.label || null,
fillColor: dataset.fillColor,
strokeColor: dataset.strokeColor,
pointColor: dataset.pointColor,
pointStrokeColor: dataset.pointStrokeColor,
showTooltip: dataset.showTooltip,
points: []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data, function(dataPoint, index) {
//Add a new point for each piece of data, passing any required data to draw.
datasetObject.points.push(new this.PointClass({
/*
* set wether to show the tooltip or not, left this as being able to be undfined
* and default to true
*/
showTooltip: dataset.showTooltip === undefined ? true : dataset.showTooltip,
value: dataPoint,
label: data.labels[index],
datasetLabel: dataset.label,
strokeColor: dataset.pointStrokeColor,
fillColor: dataset.pointColor,
highlightFill: dataset.pointHighlightFill || dataset.pointColor,
highlightStroke: dataset.pointHighlightStroke || dataset.pointStrokeColor
}));
}, this);
this.buildScale(data.labels);
this.eachPoints(function(point, index) {
helpers.extend(point, {
x: this.scale.calculateX(index),
y: this.scale.endPoint
});
point.save();
}, this);
}, this);
this.render();
},
/*
* need to edit how points at event works so it only uses points that we want to show the tool tip for
*/
getPointsAtEvent: function(e) {
//have to get the helpers as we are using this outside chart where it was declared
var helpers = Chart.helpers;
var pointsArray = [],
eventPosition = helpers.getRelativePosition(e);
helpers.each(this.datasets, function(dataset) {
helpers.each(dataset.points, function(point) {
if (point.inRange(eventPosition.x, eventPosition.y) && point.showTooltip) pointsArray.push(point);
});
}, this);
return pointsArray;
},
/*
* also need to change how the core showTooltip functions as otherwise, it trys to be helpful
* and grab any points it thinks also need to be displayed
*/
showTooltip: function(ChartElements, forceRedraw) {
//have to get the helpers as we are using this outside chart where it was declared
var helpers = Chart.helpers;
var each = helpers.each;
var indexOf = helpers.indexOf;
var min = helpers.min;
var max = helpers.min;
// Only redraw the chart if we've actually changed what we're hovering on.
if (typeof this.activeElements === 'undefined') this.activeElements = [];
var isChanged = (function(Elements) {
var changed = false;
if (Elements.length !== this.activeElements.length) {
changed = true;
return changed;
}
each(Elements, function(element, index) {
if (element !== this.activeElements[index]) {
changed = true;
}
}, this);
return changed;
}).call(this, ChartElements);
if (!isChanged && !forceRedraw) {
return;
} else {
this.activeElements = ChartElements;
}
this.draw();
if (ChartElements.length > 0) {
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
if (this.datasets && this.datasets.length > 1) {
var dataArray,
dataIndex;
for (var i = this.datasets.length - 1; i >= 0; i--) {
dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
dataIndex = indexOf(dataArray, ChartElements[0]);
if (dataIndex !== -1) {
break;
}
}
var tooltipLabels = [],
tooltipColors = [],
medianPosition = (function(index) {
// Get all the points at that particular index
var Elements = [],
dataCollection,
xPositions = [],
yPositions = [],
xMax,
yMax,
xMin,
yMin;
helpers.each(this.datasets, function(dataset) {
dataCollection = dataset.points || dataset.bars || dataset.segments;
/*
*check to make sure we want to show the point
*/
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue() && (dataCollection[dataIndex].showTooltip === undefined || dataCollection[dataIndex].showTooltip)) {
Elements.push(dataCollection[dataIndex]);
}
});
helpers.each(Elements, function(element) {
xPositions.push(element.x);
yPositions.push(element.y);
//Include any colour information about the element
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
tooltipColors.push({
fill: element._saved.fillColor || element.fillColor,
stroke: element._saved.strokeColor || element.strokeColor
});
}, this);
yMin = min(yPositions);
yMax = max(yPositions);
xMin = min(xPositions);
xMax = max(xPositions);
return {
x: (xMin > this.chart.width / 2) ? xMin : xMax,
y: (yMin + yMax) / 2
};
}).call(this, dataIndex);
new Chart.MultiTooltip({
x: medianPosition.x,
y: medianPosition.y,
xPadding: this.options.tooltipXPadding,
yPadding: this.options.tooltipYPadding,
xOffset: this.options.tooltipXOffset,
fillColor: this.options.tooltipFillColor,
textColor: this.options.tooltipFontColor,
fontFamily: this.options.tooltipFontFamily,
fontStyle: this.options.tooltipFontStyle,
fontSize: this.options.tooltipFontSize,
titleTextColor: this.options.tooltipTitleFontColor,
titleFontFamily: this.options.tooltipTitleFontFamily,
titleFontStyle: this.options.tooltipTitleFontStyle,
titleFontSize: this.options.tooltipTitleFontSize,
cornerRadius: this.options.tooltipCornerRadius,
labels: tooltipLabels,
legendColors: tooltipColors,
legendColorBackground: this.options.multiTooltipKeyBackground,
title: ChartElements[0].label,
chart: this.chart,
ctx: this.chart.ctx
}).draw();
} else {
each(ChartElements, function(Element) {
var tooltipPosition = Element.tooltipPosition();
new Chart.Tooltip({
x: Math.round(tooltipPosition.x),
y: Math.round(tooltipPosition.y),
xPadding: this.options.tooltipXPadding,
yPadding: this.options.tooltipYPadding,
fillColor: this.options.tooltipFillColor,
textColor: this.options.tooltipFontColor,
fontFamily: this.options.tooltipFontFamily,
fontStyle: this.options.tooltipFontStyle,
fontSize: this.options.tooltipFontSize,
caretHeight: this.options.tooltipCaretSize,
cornerRadius: this.options.tooltipCornerRadius,
text: template(this.options.tooltipTemplate, Element),
chart: this.chart
}).draw();
}, this);
}
}
return this;
},
});
var ctx = document.getElementById("chart").getContext("2d");
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
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)",
showTooltip: false, //TO USE JUST ADD THIS NEW OPTION ONLY REALLY NEEDS TO PRESENT IF SETTING TO FALSE
data: [15, 10, 10, 10, 10, 10, 10]
}, {
label: "My second 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)",
showTooltip: false, //TO USE JUST ADD THIS NEW OPTION ONLY REALLY NEEDS TO PRESENT IF SETTING TO FALSE
data: [100, 100, 100, 100, 100, 100, 100]
}, {
label: "My third dataset",
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: [28, 48, 40, 19, 86, 27, 90]
}]
};
var myBarChart = new Chart(ctx).LineTooltip(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<canvas id="chart" width="600px"></canvas>
and a fiddle if you find that easy to view http://jsfiddle.net/leighking2/1Lammwpt/
I would like to display chart.js's bar chart inside a tooltip.
Is this possible?
$(function() {
$( document ).tooltip({
track: true,
content:function () {var temp = $(this).prop('title');
temp = theBigArray[temp] //THIS IS THE JSON DATA CONTAINER FOR EACH SENTENCE
var barChartData = {
labels : ["Future","Present","Past"],
datasets : [
{
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 : [temp[2], temp[3], temp[4]]
}
]
}
var ctx = document.getElementById("canvas").getContext("2d");
var myTable = new Chart(ctx).Bar(barChartData, {
responsive : false
});
return '<canvas id="canvas"></canvas>';
}
});
When "canvas" is under , and displayed on html, it works fine. But, it fails to show inside the tooltip javascript when I return the content of the tooltip with div.
You need to create the canvas element before you call getElementById on it. Also, the canvas element needs to be sized for Chart.js to work properly.
Use this
$(function() {
$( document ).tooltip({
track: true,
open: function (event, ui) {
$('.ui-tooltip-content > div').append($("#canvas"))
},
content: function () {
var temp = $(this).prop('title');
var temp = theBigArray[temp] //THIS IS THE JSON DATA CONTAINER FOR EACH SENTENCE
var barChartData = {
labels: ["Future", "Present", "Past"],
datasets: [
{
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: [temp[2], temp[3], temp[4]]
}
]
}
$('body').append($("<canvas id='canvas' width='200' height='100'></canvas>"))
var ctx = document.getElementById("canvas").getContext("2d");
var myTable = new Chart(ctx).Bar(barChartData, {
responsive: false,
animation: false
});
return '<div></div>';
}
})
});
with CSS
<style>
body > #canvas {
position: fixed;
visibility: hidden;
}
</style>