Chart.js only displays on refresh in Rails app - javascript

I've managed to create a chart in my Rails app using Chart.js, however for some reason, the graph doesn't display when the view loads for the first time. If I refresh the page, it displays correctly and I can't work out why. Any suggestions?
statement.html.erb:
....
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="height:350px">
<canvas id="canvas"></canvas>
</div>
<script type="text/javascript">
var data = [
{
value: gon.creditTotal,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: gon.assetTotal ,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
}
];
var ctx = document.getElementById("canvas").getContext("2d");
var myChart = new Chart(ctx).Pie(data);
</script>
note: I've tried wrapping the javascript inside the following but I still get the same issue:
window.onload = function(){
***here***
}
application.js:
//= require jquery
//= require bootstrap
//= require jquery_ujs
//= require jquery.ui.all
//= require Chart
//= require turbolinks
//= require jquery.turbolinks
//= require_tree .
Gemfile:
gem 'rails', '4.2.2'
gem 'bootstrap-sass', '3.2.0.0'
gem 'sass-rails', '5.0.2'
gem 'uglifier', '2.5.3'
gem 'coffee-rails', '4.1.0'
gem 'jquery-rails', '4.0.3'
gem 'jquery-ui-rails', '~> 4.2.1'
gem 'turbolinks', '2.3.0'
gem 'jquery-turbolinks'
gem 'jbuilder', '2.2.3'
gem 'sdoc', '0.4.0', group: :doc
gem 'chart-js-rails'
gem 'gon'

this is how I got working my chart.js with turbolinks
var ready = function() {
$.ajax({
url: "myurl.json",
type: "get",
async: true,
datatype : 'string'
}).done (function (data) {
var years = [];
var obstaravania = [];
var trzby = [];
var zisk = [];
var obstarcolor=[];
var trzbycolor=[];
var ziskcolor=[];
for(var i in data) {
years.push(data[i].year);
obstaravania.push(data[i].obstaravanie);
trzby.push(data[i].trzby);
zisk.push(data[i].zisk);
obstarcolor.push('#c0392b');
trzbycolor.push('#337ab7');
ziskcolor.push('#27ae60');
}
var chartdata = {
labels: years,
datasets : [
{
label: 'Obstarávania',
backgroundColor: obstarcolor,
labelColor: [ '#c0392b'],
data: obstaravania
},
{
label: 'Tržby',
backgroundColor:trzbycolor,
labelColor: [ '#337ab7'],
data: trzby
},
{
label: 'Zisk',
backgroundColor:ziskcolor,
labelColor: [ '#27ae60'],
data: zisk
}
]
};
var barOptions = {
responsive: true
};
var ctx2 = $("#mychart");
var newchart = new Chart(ctx2, {type: 'bar', data: chartdata, options:barOptions});
});
//});
};
$(".contractors.showcontractor").ready(ready);
document.addEventListener('turbolinks:before-cache', function() {
if ($('#mychart').width >1) {newchart.destroy() ;}
});
$(".contractors.showcontractor").on('turbolinks:ready', ready);

Related

ChartJs Doughnut parsing datasets

I‘m trying to create a doughnut chart with custom objects as data. I don’t know if it is a bug or am I stupid. 😩
If the type of the chart is „bar“ everything is working as expected but if I change it to doughnut the chart area is empty.
Here is the code for the bar chart:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
label: '# of Votes',
data: [{vX:12, n:'vx'}, {vX:13, n:'vx2'}],
parsing:{
yAxisKey:'vX',
xAxisKey: 'n'
},
borderWidth: 1
}]
},
options: {
}
});
and that‘s my doughnut:
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [{
label: '# of Votes',
data: [{vX:12, n:'vx'}, {vX:13, n:'vx2'}],
parsing:{
yAxisKey:'vX',
},
borderWidth: 1
}]
},
options: {
}
});
Is parsing not supported for doughnut charts? I can‘t find information about this in the docs.
thanks, Christian
Regarding data structures, the Chart.js documentation says:
For a pie (and doughnut) chart, datasets need to contain an array of data points. The data points should be a number (...)
Therefore, parsing doesn't make sense and is probably not supported. The problem can be solved by mapping your data to labels and data as follows.
var data = [{vX:12, n:'vx'}, {vX:13, n:'vx2'}];
new Chart('myChart', {
type: 'doughnut',
data: {
labels: data.map(v => v.n),
datasets: [{
label: '# of Votes',
data: data.map(v => v.vX),
borderWidth: 1
}]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart"></canvas>
At the moment chart.js does not support object notation with parsing for pie/doughnut charts.
There has been a pr for this a few days ago which is merged into the master so as soon as a new version of chart.js releases, anything beyond version 3.5.1 will have this change in it and then you can use your object.
Otherwise you can take the route #uminder suggested and map the data yourself
As mentioned by Christian, It's available since 3.6.0 (2021-10-24, see https://github.com/chartjs/Chart.js/issues/9440) with sth. like this:
options: {
parsing: {
key: "the-label-key',
}
}
ref official doc: https://www.chartjs.org/docs/latest/general/data-structures.html

Show data values in Chart.js bars (version 3)

There is a thread with many answers on this topic (Show values on top of bars in chart.js), but it's all about version 2.x
getDatasetMeta() has been deprecated:
https://www.chartjs.org/docs/3.0.2/getting-started/v3-migration.html
The "datalabels" plugin has not been ported to 3.x:
https://github.com/chartjs/chartjs-plugin-datalabels
Have you found any working solutions? How can data values be displayed on top of vertical barcharts (or next to horizontal barcharts)?
You can use the beta of the datalabels plugin.
Documentation: https://v2_0_0-rc_1--chartjs-plugin-datalabels.netlify.app/
Script tag: <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0-rc/dist/chartjs-plugin-datalabels.min.js"></script>
Install command: npm i chartjs-plugin-datalabels#next
Live example:
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.3.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0-rc"></script>
<canvas id="myChart" width="850" height="520"></canvas>
<script>
var ctx = document.getElementById('myChart');
Chart.register(ChartDataLabels); // first way of registering the plugin, registers them for all your charts
var myChart = new Chart(ctx, {
type: 'bar',
plugins: [ChartDataLabels], // second way of registering plugin, register plugin for only this chart
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
data: [12, 19, 3, 5, 2, 3],
label: 'Advisor Closed MTD',
backgroundColor: 'rgb(192,111,94)',
barThickness: 25,
datalabels: {
color: '#FFCE56'
}
}],
},
options: {
responsive: false,
plugins: {
datalabels: {
anchor: 'end', // remove this line to get label in middle of the bar
align: 'end',
formatter: (val) => (`${val}%`),
labels: {
value: {
color: 'blue'
}
}
}
}
}
});
</script>

JavaScript code(JQuery) not display in rails app

I want to display chart in view in rails app. use this link http://jsfiddle.net/zz7pB/ contain chart
in application.html.erb and try it in view
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
in application.js
//= require_tree
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require chart ---> name of controller
chart.js in app -> assets -> javascripts
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$('#container').highcharts({
chart: {
type: 'line',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint([x, y], true, true);
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
}]
});
});
});
in index.html.erb
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
i want display this chart in my app this all information. This live chart
when inspect element display div put not contain chart.
i read this Where should I place my jQuery code in my Ruby on Rails applications? but not solve it
This error appear in the console in the browser
EDITED:
Step 1
I created a new rails application and, Jquery-rails Gem added to the Gemfile.
Gemfile
gem 'jquery-rails', '~> 4.3', '>= 4.3.1'
application.js
//= require jquery
//= require jquery_ujs
And then run bundle install
Step 2
Downloaded HighchartJs and ExportingJs files and placed in assets/javascripts/plugins folder. And, These libraries are imported to application.js as below.
application.js
//= require plugins/highcharts
//= require plugins/exporting
Step 3
Created chart.js file and imported to application.js
//= require chart
Then paste your Js code in this file. All should work now.
Tips Please follow more tutorials to learn how to debug javascript with browser console.

highcharts error 17 when creating a heatmap

I'm trying to generate a heatmap using data inserted by gon.
The frame for the chart is generated correctly in the browser, but the chart is missing, just blank.
and in the console I get:
Uncaught Highcharts error #17: www.highcharts.com/errors/17
which seems to be generated by the initSeries method in highcharts after a comment mentioning:
// No such series type
I'm using RoR4, with this in the Gemfile:
gem "highcharts-rails", "~> 3.0.0"
and this in the application.js:
//= require jquery
//= require jquery_ujs
//= require tether
//= require bootstrap-sprockets
//= require highcharts
//= require highcharts/highcharts-more
//= require turbolinks
//= require_tree .
my SLIM:
td
.card
.card-img-top(data-template-chart=true data-id=template.to_param)
my includes (from the compiled HTML):
<script src="/assets/highcharts.self-d34c91baaad4188e2d81d954aa38de43ec4916882f39d2d908f86d47a6e942b0.js?body=1" data-turbolinks-track="true"></script>
<script src="/assets/highcharts/highcharts-more.self-995bc649d8f9f68a0bb6bfb3242b35a20c494d716164fa0c93a74630b291113b.js?body=1" data-turbolinks-track="true"></script>
Inspecting the "sources" in the browser I can see both files being loaded
my coffeescript:
$(window).bind 'page:change', ->
initPage()
initPage= ->
$('[data-template-chart]').each( ->
curId = $(this).data("id")
data = gon.templates[curId]
$(this).highcharts
chart:
height: 150
width: 150
title: text: ''
xAxis:
showLastLabel: false
tickLength: 16
yAxis:
title: text: null
labels: format: '{value}:00'
minPadding: 0
maxPadding: 0
startOnTick: false
endOnTick: false
tickPositions: [0, 6, 12, 18, 24]
tickWidth: 1
min: 0
max: 23
reversed: true
colorAxis:
stops: [
[0, '#3060cf']
[0.5, '#fffbbc']
[0.9, '#c4463a']
[1, '#c4463a']
]
min: -15
max: 25
startOnTick: false
endOnTick: false
# labels: format: value
series: [
{
type: 'heatmap'
data: csv: data
borderWidth: 0
nullColor: '#EFEFEF'
colsize: 24 * 365
}
]
)
I'm guessing the issue is with the highcharts-more library, which is being loaded in the browser, but it doesn't seem to be available, and I'm guessing it's a problem with the javascript generated by coffeescript.
This is the compiled version:
(function() {
var initPage, update_form;
$(function() {
return initPage();
});
$(window).bind('page:change', function() {
return initPage();
});
update_form = function() {
var chart, end_quote, extremes, start_quote;
chart = $('#template_chart').highcharts();
extremes = chart.xAxis[0].getExtremes();
start_quote = Math.ceil(extremes.min);
end_quote = Math.floor(extremes.max);
$('#template_match_start_quote_id').val(gon.ids[start_quote]);
return $('#template_match_end_quote_id').val(gon.ids[end_quote]);
};
initPage = function() {
$('select[flexible_select]').flexible_select();
return $('#template_chart').each(function() {
var categories, prices;
prices = gon.prices;
categories = gon.ids;
return $(this).highcharts({
chart: {
zoomType: "x",
events: {
redraw: function() {
return update_form();
}
}
},
title: {
text: null
},
xAxis: {
categories: categories,
labels: {
enabled: false
}
},
yAxis: {
title: {
text: "Price",
style: {
color: Highcharts.getOptions().colors[1]
}
},
opposite: true
},
tooltip: {
shared: true
},
legend: {
enabled: false
},
credits: {
href: "http://www.pattern4all.com",
text: "source: www.pattern4all.com"
},
series: [
{
name: "Price",
data: prices,
type: "line",
marker: {
enabled: false
},
tooltip: {
valuePrefix: "$"
},
style: {
color: Highcharts.getOptions().colors[1]
}
}
]
});
});
};
}).call(this);
Turns out that:
I needed to add
//= require highcharts/modules/heatmap
to my application.js I thought it was a redundant inclusion, but apparently it's not.
Also the GEM readme, at: https://github.com/PerfectlyNormal/highcharts-rails mentions to install: gem "highcharts-rails", "~> 3.0.0" but 3.0.0 is not the latest version, I updated the gem inclusion to: gem "highcharts-rails", "~> 4.1.9", which is currently the latest, and the problem seems fixed.
Even removing completely the version specification would work:
gem "highcharts-rails"
getting the project to use the latest version.
I'm going to make a pull request to update the readme.

ReferenceError: HighCharts is not defined

I'm rendering a chart using highstocks on my rails application on a index.html.erb file, however when I try to load the chart, I get the following error on the firebug console,
ReferenceError: HighCharts is not defined
new HighCharts.Chart({
My index.html.erb file is as follows
<div id="quotes_chart", style="width=560px; height:300px;">
<script>
$(function(){
new HighCharts.Chart({
chart : {
renderTo: "quotes_chart"
},
title : {
text: "Daily trades"
},
xAxis : {
type: "datetime"
},
yAxis : {
title: {
text: "Shillings"
}
},
tooltip : {
formatter: function(){
return HighCharts.dateFormat("%B %e, %Y", this.x) + ': ' + "Kshs" + Highcharts.numberFormat(this.y, 2);
}
},
series: [
<% { "Telecommunication" => StockQuote.telecomm, "Agriculture" => StockQuote.agric }.each do |name, prices|
%>
{
name: <%= name %>,
pointInterval: <%= 1.day * 1000 %>,
pointStart: <%= 2.weeks.ago.to_i * 1000 %>,
data: <%= (2.weeks.ago.to_date..Date.today).map { |date| StockQuote.price_on(date).to_f}.inspect%>
},
<% end %>
]
});
});
</script>
</div>
In my application.html.erb is as follows:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="components/highstock/highstock.js"></script>
<%= javascript_include_tag "jquery-1.11.0.min", "highcharts" %>
In my app assests/javascripts folder I have both the jquery-1.11.0.min.js and highcharts.js files as downloaded from highcharts.com
What might I be doing wrong?
var chart=null;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
},
title: {
text: '${model.title}'
}
...
Set the chart to null because this error can occur due to multiple declaration that you may not be aware of. Assumption is all imports are correct
You need to load Highcharts only once, not twice as you have. So, I recommend to use only:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="components/highstock/highstock.js"></script>
Because Highstock includes all Highcharts options. Morever please take care about correct paths to your files, because it looks like a problem only with it.

Categories