Chartjs line graph goes over panel - javascript

I am currently using chartjs for graphs and I want to be able to display these in a bootstrap panel. I have managed to get the graph on however the graph seems to go over the panel body a little bit.
<div class="panel panel-default" draggable="true">
<div class="panel-heading">
<h3 class="panel-title">
Panel title
<span class="glyphicon glyphicon-pencil panel-icons"></span>
<span class="glyphicon glyphicon-zoom-in panel-icons"></span>
<span class="glyphicon glyphicon-trash panel-icons"></span>
</h3>
</div>
<div class="panel-body">
<canvas id="chartjs"></canvas>
</div>
</div>
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
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, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
function loadChart() {
var context = $('#chartjs').get(0).getContext("2d");
window.myLine = new Chart(context).Line(data, {
responsive: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
});
}
window.onload = loadChart();
this is what it currently looks like
Chart Image.
I am unsure on how to get the graph within the bounds of the panel. If more information is needed I would be happy to provide more.

Just add some padding-right to the canvas element. That should give you enough space to fit the canvas right in to the panel-body.
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
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, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
function loadChart() {
var context = $('#chartjs').get(0).getContext("2d");
window.myLine = new Chart(context).Line(data, {
responsive: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
});
}
window.onload = loadChart();
canvas {
padding: 0 30px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<div class="col-sm-6">
<div class="panel panel-default" draggable="true">
<div class="panel-heading">
<h3 class="panel-title">
Panel title
<span class="glyphicon glyphicon-pencil panel-icons"></span>
<span class="glyphicon glyphicon-zoom-in panel-icons"></span>
<span class="glyphicon glyphicon-trash panel-icons"></span>
</h3>
</div>
<div class="panel-body">
<canvas id="chartjs"></canvas>
</div>
</div>
</div>

Related

Chart responsively

I have a line chart. But my chart is not responsive. How can I make it responsive?
Here is my script code:
$(document).ready(function(){
var data = <?php echo json_encode($data) ?>;
var id = [];
var akim = [];
for(var i in data) {
id.push(data[i].id);
akim.push(data[i].akim);
}
var chartdata = {
labels: id,
datasets: [
{
label: "akim",
fill: false,
lineTension: 0.1,
backgroundColor: "rgba(211, 72, 54, 1)",
borderColor: "rgba(211, 72, 54, 1)",
pointHoverBackgroundColor: "rgba(211, 72, 54, 1)",
pointHoverBorderColor: "rgba(211, 72, 54, 1)",
data: akim
}
]
};
var ctx = $("#mycanvas");
var LineGraph = new Chart(ctx, {
type: 'line',
data: chartdata
});
});
And here is my drawing code:
<div class="box box-primary">
<div class="box-header with-border">
<i class="fa fa-bar-chart-o"></i>
<h3 class="box-title">Dakikalık Gösterim</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
<div class="box-body">
<div class="chart-container">
<canvas id="mycanvas"></canvas>
</div>
</div>
<!-- /.box-body-->
</div>
But it shows like this.
What should I do to make it responsive?
My CSS code is in pixel format. I changed it. And It becomes normal.
<style>.chart-container {width: 100%;height: auto;}</style>

Dynamic ChartJS Chart Updated in Rails with AJAX

I am using Rails 5 and the latest ChartJS library (http://www.chartjs.org/docs/).
What I want to accomplish is to GET the latest 20 items from the SensorReading model and update the Chart with setInterval and AJAX.
I've built the AJAX call and I've loaded the Chart but I fail in two things.
First of of all I get a Syntax Error when reading data from Rails:
SyntaxError: expected expression, got '&'
var labels = ["2016-07-03 10:33:49 +0300", "2016-07-03 10:3
No matter what I tried, they keep to appear with " instead of quotes.
Secondly I am unable to update the Chart, as I need a handler available for the Chart itself to call .update() on it.
index.html.erb
<h1>Dashboard</h1>
<div class="ui divider"></div>
<div class="ui padded grid">
<div class="four wide column">
<div class="ui statistic">
<div class="value">
<%= #temperature %>.C
</div>
<div class="label">
TEMPERATURE
</div>
</div>
<br>
<div class="ui statistic">
<div class="value">
<%= #humidity %>%
</div>
<div class="label">
HUMIDITY
</div>
</div>
</div>
<div class="twelve wide column">
<div class="ui segment">
<div class="line-chart" style="max-height: 400px; display:block;">
<canvas id="updating-chart"></canvas>
</div>
</div>
</div>
</div>
<br>
<script>
var labels = <%= #sensor_readings.map(&:created_at) %>;
var canvas = document.getElementById('updating-chart'),
ctx = canvas.getContext('2d'),
startingData = {
labels: labels,
datasets: [
{
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: <%= #sensor_readings.map(&:temperature) %>
},
{
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: <%= #sensor_readings.map(&:humidity) %>
}
]
},
latestLabel = startingData.labels[6];
// Reduce the animation steps for demo clarity.
var myLiveChart = new Chart(ctx , {
type: "line",
data: startingData,
animationSteps: 15
});
setInterval(function(){
// Add two random numbers for each dataset
//myLiveChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLiveChart.update(); // Calling update now animates the position of March from 90 to 50.
}, 5000);
</script>
dashboard.js
var ready = function(){
setInterval(refreshSensorReadings, 3000);
function refreshSensorReadings(){
console.log("--> Called");
$.rails.ajax({
type: "GET",
dataType: 'script',
url: "/sensor_readings_chart_data.js",
success: function(result){
//$('.line-chart').html(result);
console.log(result);
}
});
};
};
$(document).on('turbolinks:load', ready);
route
get 'sensor_readings_chart_data', to: 'sensor_readings#chart_data'
sensor_readings_controller.rb
def chart_data
#sensor_readings = SensorReading.last(20)
respond_to do |format|
format.json { head :no_content }
format.js
end
end
Any advice will be appreaciated.
Try the html_safe method:
Marks a string as trusted safe. It will be inserted into HTML with no
additional escaping performed. It is your responsibilty to ensure that
the string contains no malicious content. This method is equivalent to
the raw helper in views. It is recommended that you use sanitize
instead of this method. It should never be called on user input.
datasets: [
{
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: <%= #sensor_readings.map(&:temperature).html_safe %>
},
{
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: <%= #sensor_readings.map(&:humidity).html_safe %>
}
]

Charts.js & Bootstrap Accordion

I have been trying to understand why Charts.js wouldn't draw a chart if it's inside a Bootstrap Accordion.
After many attempts I managed to understand why it's not drawing the chart! it's because the panel is basically hiding the canvas so Charts.js doesn't draw it.
Can anyone help me come up with a solution to this?
I've also tried to draw the chart only when the Bootstrap event shown.bs.collapse is active, doesn't work.
Here's a jsfiddle I've created to illustrate the problem:
If you want to reproduce the problem simply add in to the class in line <div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
I got it to work with the following code:
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Collapsible Group Item #1
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<canvas id="q_chart" width="400" height="400"></canvas>
</div>
</div>
</div>
</div>
and javascript
var ctx = document.getElementById("q_chart").getContext("2d");
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
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, 59, 80, 81, 56, 55, 40]
}, {
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}]
};
var MyNewChart=null;
$('#collapseOne').on('shown.bs.collapse', function () {
setTimeout(function() {
if(MyNewChart == null)
MyNewChart = new Chart(ctx).Bar(data);
},200);
});
I did some testing and found that you can call MyNewChart.update() instead of recreating the chart on a timeout as the verified answer does. The first transition is a bit rough (maybe because a transition is happening as it's created) but after that the transitions are smooth.
Example JSFiddle: https://jsfiddle.net/akh9cnx5/
<div class="container">
<button type="button" class="col-12 btn btn-light mb-2" data-toggle="collapse" data-target="#viewgraph" aria-expanded="false" aria-controls="viewgraph">View Graph</button>
<div id="viewgraph" class="collapse mb-2">
<div class="card card-body">
<div class="d-flex justify-content-center">
<div class="col-12 col-sm-8">
<canvas id="graph"></canvas>
</div>
</div>
</div>
</div>
</div>
and javascript
var ctx = document.getElementById('graph').getContext('2d');
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
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, 59, 80, 81, 56, 55, 40]
}, {
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}]
};
var myNewChart = new Chart(ctx, {
type: 'bar',
data: data
});
$("#viewgraph").on('shown.bs.collapse', function () {
myNewChart.update();
});
For anyone coming to this later, I had the same issue but preferred not to rely on a timer delay as offered in the accepted answer. The following is what worked for me using Bootstrap 3.3.7 with the shown event:
shown.bs.collapse
$('#accordion').on('shown.bs.collapse', function (e) {
switch (e.target.id)
{
case "panel1": ShowChart1(); break;
case "panel2": ShowChart2(); break;
case "panel3": ShowChart3(); break;
case "panel4": ShowChart4(); break;
default: ShowDefault();
}
})
Hopes this helps
btw - this is the above code working: greatdata.com/stats/newyork_ny

Chart.js not showing in my view

I have an app running with angular.js and one of my view should load an chart. I'm using chart.js for it, but for some reason it's not working and no error is shown on my console.
Here is my function that creates the chart:
$scope.writeBatteryChart = function(){
console.log("Function was called");
var data = {
labels: ["10:30am", "11:00am", "11:30am", "12:00pm", "12:30pm", "01:00pm", "01:30pm"],
datasets: [
{
label: "Battery",
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, 59, 80, 81, 56, 55, 40]
}
]
};
var options = {
responsive: true,
bezierCurve : false
}
var ctx = document.getElementById("myChart").getContext("2d");
var myLineChart = new Chart(ctx).Line(data, options);
}
Here's the HTML where the chart should appear:
<div class="row">
<div class="col-md-8 col-sm-8 col-xs-8" style="padding-left: 0px;">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Battery <i class="fi-battery-half"></i></h3>
</div>
<div class="panel-body">
<canvas id="myChart" height="300"></canvas>
</div>
</div>
</div>
<div class="col-md-4 col-sm-4 col-xs-4" style="padding-left: 0px; padding-right: 0px;">
</div>
</div>
and I'm also loading the latest version of the Chart.js:
<!--Chart plugin -->
<script src="bower_components/Chart.js/Chart.js" language="javascript"></script>
One thing that I noticed is that the canvas is being rendered with 0 dimensions:
Does someone can see where I'm doing something wrong?
The problem: I was calling the function before the canvas be loaded on the view, so I used a setTimeout() to call the writeBatteryChart() with a delay in order to wait the canvas be rendered.
You have to add your rendered things inside of canvas. Hope it will help Link

How to display angular js bar graph in modal popups

Hi I am trying to display angular js bar chart in modal popup (jquery modal), But its not working. I have tried with the below code.
<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content widg_larg">
<div class="title">Modal Title
<span class="pull-right cursor_pointer">
<i class="fa fa-times" data-dismiss="modal" aria-label="Close"></i>
</span>
<div ng-controller="testConrtoller">
<canvas class="chart chart-bar" data="data"
labels="labels" width="400" height="400"></canvas>
</div>
</div>
</div>
</div>
</div>
and js code is
app.controller("testController", function ($scope, $http) {
$scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
$scope.series = ['Series A', 'Series B'];
$scope.data = [
[65, 59, 80, 81, 56, 55, 40],
[28, 48, 40, 19, 86, 27, 90]
];
$scope.onClick = function (points, evt) {
console.log(points, evt);
};
});
But its not working is there any other way to work with it.

Categories