create highcharts using data from table - ruby-on-rails-4

I am trying to use data from the table to create a bar graph using high-charts in rails.I have a table named school and it contains two columns i.e,name and attendance.I want to show student name on x-axis and attendance on y-axis.My JavaScript code is:
$(function () {
// Create the chart
$('#student')high-charts({
chart: {
type: 'column'
},
title: {
text: 'student details'
},
x Axis: {
type: 'category'
},
y Axis: {
title: {
text: 'Total attendance'
}
},
legend: {
enabled: false
},
plot-options: {
series: {
border-width: 0,
data-labels: {
enabled: true,
format: '{point.y:.1f}%'
}
}
},
tool-tip: {
header-format: '<span style="font-size:11px">{series.name}</span> <Br>',
point-format: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<BR/>'
},
series: [ {
name: 'Stu',
id: 'Stu',
data: [
[<%= #students.each do |s|%>
'<%= s.name %>',
<%= s.attendance%>
<%end%>
]
]
}
in my HTML i have :
<div class="col-md-8">
<div class="x_panel">
<div id="student" style="min-width: 310px; height: 400px; margin: 0 auto">
</div>
</div>
</div>
I was unable to load the bar graph.Please help

try this
$(function () {
// Create the chart
new Highcharts.Chart({
chart: { renderTo: 'student' },
title: {
text: 'student details'
},
x Axis: {
type: 'category'
},
y Axis: {
title: {
text: 'Total attendance'
}
},
legend: {
enabled: false
},
plot-options: {
series: {
border-width: 0,
data-labels: {
enabled: true,
format: '{point.y:.1f}%'
}
}
},
tool-tip: {
header-format: '<span style="font-size:11px">{series.name}</span> <
Br>',
point-format: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<BR/>'
},
series: [ {
name: 'Stu',
id: 'Stu',
data: [
[<%= #students.each do |s|%>
'<%= s.name %>',
<%= s.attendance%>
<%end%>
]
]
}
Create a new highchart and render div in chart

Related

Bar graph not taking 100%

I have a problem when generating a bar chart :
I don't understand why 50%+50% doesn't smoke 100% of the seat? Config seems to be good ? Did i miss something?
Here the code :
new Chart(draw, {
type: 'bar',
data: {
labels: [currentYear],
datasets: [
{
label: 'Legend 1',
data: [50],
backgroundColor: '#fdfd96', // yellow
},
{
label: 'Legend 2',
data: [50],
backgroundColor: '#77b5fe', // blue
},
],
},
options: {
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
},
},
animation: {
onComplete: function () {
saveChartAsImage(
this.toBase64Image(),
currentYear,
companyId,
'actif',
manualMode,
);
},
},
},
});
Your code and configuration looks correct and works ( demo seen below ) but if you want to be on the save side yo can add the properties max:100 to the y axis, this could fix the hight issue.
Here the demo:
const data = {
labels: [2022],
datasets: [{
label: 'Legend 1',
data: [50],
backgroundColor: '#fdfd96', // yellow
},
{
label: 'Legend 2',
data: [50],
backgroundColor: '#77b5fe', // blue
},],
};
const config = {
type: 'bar',
data: data,
options: {
maintainAspectRatio: false,
animation: {
onComplete: function () {
let img = document.createElement('img')
let url = this.toBase64Image()
img.src = url
document.querySelector('#imagePreview').append(img);
}
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
max:100
},
}}
};
var cart = new Chart(
document.getElementById('chart'),
config
);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart" style="height:184px; width:350px;">
<canvas id="chart" ></canvas>
</div>
<b> preview Image </b>
<div id="imagePreview"></div>
Update screenshot of result:
Update:
After testing the assumtion must be, that the save function is defective or there is some sort of race condition with a different chart. Since createing a image onComplete creates a correct images, in the updated demo.
I'm assuming the wrong visuals have to to with the animation, not being finished when the image is created, if this is so, one could workaround this fact (or just to test the theory), with using a timeout for creating the image, something like this
onComplete: function () {
setTimeout( () => {
saveChartAsImage(
this.toBase64Image(),
currentYear,
companyId,
'actif',
manualMode,
);
}, 1000); // <-- One Second should be enough for the animation to end
}

Multiple bar charts side by side chartjs

I'm trying to create a bar chart that is grouped by the dataset rather than the label in chartjs3 and I'm having no luck. Before I switch over to building in D3, I wanted to check if this achievable within the confines of ChartJS.
Here is a link to a fiddle where I've been playing around with using different dataset structures and options from the Bar chart docs. I suspect that this is outside of the scope of the charting library, or is within the scope, but requires some custom components to be made – I would appreciate if anyone could direct me on what in particular I would need to extend (e.g. is it a case of a custom axes? or more?).
https://jsfiddle.net/f34ucs76/2/
const data = {
labels: [
'2000','2010','2020',
// 'Frogs','Monkeys','Squirrels','Bats'
],
datasets: [
{
label: 'Frogs',
data: [30.2,20.8,36.2],
backgroundColor: 'red',
//stack: 'Frogs',
},
{
label: 'Monkeys',
data: [16.3,13.0,22.3],
backgroundColor: 'blue',
//stack: 'Monkeys',
},
{
label: 'Squirrels',
data: [5.8,3.1,14.9],
backgroundColor: 'cyan',
//stack:'Squirrels',
},
{
label: 'Bats',
data: [0.1,3.6,2.6],
backgroundColor: 'aquamarine',
//stack:'Bats',
},
],
}
const options = {
maintainAspectRatio: false,
responsive: true,
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
title: {
display: false,
},
subtitle: {
display: true,
align: 'start',
text: ['Source: Animals Index, June 2022'],
font: {
size: 12,
style: 'italic',
},
position: 'bottom',
padding: {
top: 20,
},
},
legend: {
display: true,
position: 'bottom',
},
tooltip: {
enabled: true,
},
},
scales: {
x: {
grid: {
display: false,
},
},
y: {
title: {
display: true,
text: 'Horsepower',
},
},
},
}
const mychart = new Chart(
document.getElementById('mychart'),
{
type: 'bar',
data: data,
options: options,
}
);
Your problem can be solved with Chart.js but the labels and the single dataset need to be generated.
Further you need to define your own legend by defining a plugins.legend.labels.generateLabels together with with a plugins.legend.labels.onClick function.
For further information, consult the Legend page from the Chart.js. documentation.
Please take a look at your amended and runnable code below and see how it works.
const baseData = {
labels: ['2000','2010','2020'],
datasets: [
{ label: 'Frogs', data: [30.2, 20.8, 36.2], bgColor: 'red', hidden: false },
{ label: 'Monkeys', data: [16.3, 13.0, 22.3], bgColor: 'blue', hidden: false },
{ label: 'Squirrels', data: [5.8,3.1, 14.9], bgColor: 'cyan', hidden: false },
{ label: 'Bats', data: [0.1, 3.6, 2.6], bgColor: 'aquamarine', hidden: false }
]
};
const iLastDs = baseData.datasets.length - 1;
const data = {
labels: baseData.datasets
.map(() => baseData.labels)
.map((labels, i) => i < iLastDs ? [...labels, null] : labels)
.flatMap(v => v),
datasets: [{
data: baseData.datasets
.map(ds => ds.data)
.map((data, i) => i < iLastDs ? [...data, null] : data)
.flatMap(v => v),
backgroundColor: baseData.datasets
.map(ds => ds.data.map(v => ds.bgColor))
.map((bgColors, i) => i < iLastDs ? [...bgColors, null] : bgColors)
.flatMap(v => v),
categoryPercentage: 1,
barPercentage: 0.9
}]
};
const options = {
maintainAspectRatio: true,
responsive: true,
interaction: {
intersect: true,
mode: 'index',
},
plugins: {
legend: {
position: 'bottom',
labels: {
generateLabels: chart => baseData.datasets.map((ds, i) => ({
datasetIndex: i,
text: ds.label,
fillStyle: ds.bgColor,
strokeStyle: 'lightgray',
hidden: baseData.datasets[i].hidden
}))
},
onClick: (event, legendItem, legend) => {
baseData.datasets[legendItem.datasetIndex].hidden = !baseData.datasets[legendItem.datasetIndex].hidden;
const iFirstValue = legendItem.datasetIndex + legendItem.datasetIndex * baseData.labels.length;
for (let i = iFirstValue; i < iFirstValue + baseData.labels.length; i++) {
legend.chart.toggleDataVisibility(i);
}
legend.chart.update();
}
},
tooltip: {
callbacks: {
title: ctx => {
const dsIndex = Math.floor(ctx[0].dataIndex / baseData.datasets.length);
return baseData.datasets[dsIndex].label + ' / ' + ctx[0].label;
}
}
}
},
scales: {
x: {
grid: {
display: false
}
},
y: {
title: {
display: true,
text: 'Horsepower',
}
}
}
};
new Chart('mychart', {
type: 'bar',
data,
options
});
span {
font-style: italic;
font-size: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<canvas id="mychart" height="100"></canvas>
<span>Source: Animals Index, June 2022</span>

Why do I have the issue 'property assigment expected' when I want to display a chart on my web page using highcharts

I have an issue when I want to display a chart on my web page using django and highcharts. This is my detail.html file.
I have an error called property assignment expected on the side of my curly brackets here :
_dateList={{dateList|safe}};
_price={{price.room.actual_rate.amount}};
_availability={{availability}};
Here is the all file
<h1>{{property.name}}</h1>
<h2>{{roomtype.name}}</h2>
<div id="container"></div>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script>
_dateList={{dateList|safe}};
_price={{price.room.actual_rate.amount}};
_availability={{availability}};
Highcharts.chart('container', {
title: {
text: 'Pricing model prevision'
},
xAxis: {
categories: _dateList
},
yAxis: [{
title: {
text: 'Price',
style: {
color: Highcharts.getOptions().colors[2]
}
},
labels: {
style: {
color: Highcharts.getOptions().colors[2]
}
}
}, {
title:{
text:'Occupancy',
style:{
color: Highcharts.getOptions().colors[0]
}
},
labels:{
style:{
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}],
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
pointStart: 2010
}
},
series: [{
name: 'price',
data: _price
}, {
name: 'availabilty',
data: _availability
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
</script>
<ul>
{% for day in dayList %}
{% if day.availability.room %}
<li>{{day.date}}:{{day.allotment}}:{{day.pricing.room.actual_rate.amount}} </li>
{% else %}
<li>{{day.date}}:0 </li>
{% endif %}
{% endfor %}
</ul>
Can you help me with this issue?
thank you for your help,
Best
If you add quotation marks, as shown below, it should work:
_dateList='{{dateList|safe}}';
Without quotation marks, it is interpreted as a variable. With quotation marks, it is interpreted as a string.

Show Dates in x-axis when using chart.js

I am using chart.js library. I am creating a graph and want to show dates in x-axis like here: http://www.chartjs.org/samples/latest/scales/time/line.html
I have provided the same configuration (except the date format of graph data) for graph as the above example provides but my graph showing time i.e 2 am, 2 am, .. instead of dates i.e 2018-02-01, 2018-02-10, ...
For date formatting i am using the moment.js library recommended by Chart.js
I am using following code:
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var timeFormat = 'YYYY-MM-DD';
var config = {
type: 'line',
data: {
datasets: [{
label: "Thi is graph label",
backgroundColor: "rgb(54, 162, 235)",
borderColor: "rgb(255, 159, 64)",
fill: false,
data: [{
x: moment("2010-03-01").format(timeFormat),
y: 0.668525
}, {
x: moment("2010-03-02").format(timeFormat),
y: 0.668827
}],
}]
},
options: {
title: {
text: "This is title"
},
scales: {
xAxes: [{
type: "time",
time: {
parser: timeFormat,
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
},],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
}
};
window.onload = function () {
var ctx = document.getElementById("canvas").getContext("2d");
console.log(config);
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>
<html>
<head>
<title>Line Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var timeFormat = 'MM/DD/YYYY HH:mm';
function newDate(days) {
return moment().add(days, 'd').toDate();
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
labels: [ // Date Objects
newDate(0),
newDate(1),
newDate(2),
newDate(3),
newDate(4),
newDate(5),
newDate(6)
],
datasets: [{
label: 'My First dataset',
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: 'My Second dataset',
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: 'Dataset with point data',
backgroundColor: color(window.chartColors.green).alpha(0.5).rgbString(),
borderColor: window.chartColors.green,
fill: false,
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}, {
x: newDateString(7),
y: randomScalingFactor()
}, {
x: newDateString(15),
y: randomScalingFactor()
}],
}]
},
options: {
title: {
text: 'Chart.js Time Scale'
},
scales: {
xAxes: [{
type: 'time',
time: {
format: timeFormat,
// round: 'day'
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.forEach(function(dataObj, j) {
if (typeof dataObj === 'object') {
dataObj.y = randomScalingFactor();
} else {
dataset.data[j] = randomScalingFactor();
}
});
});
window.myLine.update();
});
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: newColor,
backgroundColor: color(newColor).alpha(0.5).rgbString(),
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myLine.update();
});
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push(newDate(config.data.labels.length));
for (var index = 0; index < config.data.datasets.length; ++index) {
if (typeof config.data.datasets[index].data[0] === 'object') {
config.data.datasets[index].data.push({
x: newDate(config.data.datasets[index].data.length),
y: randomScalingFactor(),
});
} else {
config.data.datasets[index].data.push(randomScalingFactor());
}
}
window.myLine.update();
}
});
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
You need to set:
scales: {
xAxes: [
{
.....
ticks: {
source: 'date'
},
}
......
],

ExtJs List not showed in a container

I have a container with three items:
ombrelloneButton = Ext.create('Ext.Button', {
id: 'btnOmbr',
iconMask: true,
iconCls: 'action',
text: 'Ombrellone'
});
lettinoButton = Ext.create('Ext.Button', {
id: 'btnLett',
iconMask: true,
iconCls: 'action',
text: 'Lettino'
});
toolbarPostazione = Ext.create('Ext.Toolbar',{
layout: {
pack: 'center'
}, // layout
ui: 'plain',
items: [ombrelloneButton,
lettinoButton]
});
Ext.define('appTrial.view.Postazione.Postazione',{
extend: 'Ext.form.Panel',
xtype: 'Postazione',
alias: 'widget.Postazione',
controllers:['AssociaAttivitaController'],
models : ['appTrial.model.AttivitaModel'],
config : {
id : 'PostazioneId',
title : 'Welcome',
resizable : false,
collapsible : true,
bodyPadding : '5',
buttonAlign : 'center',
border : false,
trackResetOnLoad : true,
items : [{
docked: 'top',
xtype: 'titlebar',
title: 'Welcome to My New App!!!'
},
{
xtype: 'container',
name: 'mainContainer',
id: 'postazioneContainer',
layout: {
type: 'vbox',
align: 'center',
pack: 'center'
},
//width : '100%',
items : [{
layout: {
pack: 'center'
},
html :'<p style="color: red; text-align: center; font-size: 20px" >Complimenti!</p><br><p style="text-align: center; font-size: 16px">Sei stato associato alla attivita '+dummyAttivita.get('nomeAttivita')+'!</p>' +
'<br><p style="text-align: center; font-size: 16px">Ora associa la tua postazione:</p>',
margin: '80 0 50 0'
},
toolbarPostazione,
{
xtype: 'PostazioniList',
title:'PostazioniAssociate',
id: 'PostazioniAssociate'
}
]
}]
}
});
The first two of them are showed (html text and toolbar), while the PostazioniList is not showed.
It is done like this (List.js):
Ext.define('appTrial.view.Postazione.List', {
extend: 'Ext.List',
xtype: 'PostazioniList',
alias: 'widget.PostazioniList',
itemTpl: '<div>{tipoPostazione} num.{numPostazione}</div>',
data: [{
tipoPostazione: 'Ombrellone',
numPostazione: '5'
},
{
tipoPostazione: 'Ombrellone',
numPostazione: '37'
},
{
tipoPostazione: 'Lettino',
numPostazione: '46d'
}]
});
Could it be a html problem?
I don't understand also why I don't get any error, just it is hidden...
Thanks in advance