label on the x-axis does not show completely in Chart.js - javascript

I have a data from the backend(flask-sqlalchemy with mysql) in which data contains date in integer for week, month and year that looks like this:
in this case the x represents the week of the year:
let month_true = [
{
bob: {
"base-certificate": 60,
"case-certificate": 1,
"standard-certificate": 7,
},
x: 9,
},
{
bob: {
"base-certificate": 30,
"case-certificate": 4,
"standard-certificate": 5,
},
x: 11,
},
];
The first thing I did was to map the data and change the x into a readable format for Javascript and chart.js, using a function that converts week of the year number to actual date:
the function:
function getDateOfWeek(w, y) {
var d = 1 + (w - 1) * 7; // 1st of January + 7 days for each week
return new Date(y, 0, d);
}
Mapping through the data:
let newData = month_true.map(function (m) {
let dateObject = new Date();
let year = dateObject.getFullYear();
const weekDate = getDateOfWeek(m.x, year);
let r = new Date(Date.parse(weekDate));
const newd = {
x: r.setHours(0, 0, 0, 0),
base: m.bob["base-certificate"],
case: m.bob["case-certificate"],
standard: m.bob["standard-certificate"],
};
return newd;
});
let newdate = newData.map(function (d) {
return d.x;
});
now construct the chart:
let ctx = document.getElementById("chart").getContext("2d");
let config = {
//labels: newdate,
type: "bar",
data: {
datasets: [
{
label: "base",
data: newData,
parsing: {
xAxisKey: "x",
yAxisKey: "base",
},
},
{
label: "Case",
data: newData,
parsing: {
xAxisKey: "x",
yAxisKey: "case",
},
},
{
label: "Standard",
data: newData,
parsing: {
xAxisKey: "x",
yAxisKey: "standard",
},
},
],
},
options: {
scales: {
x: {
ticks: {
beginAtZero: true,
},
offset: true,
type: "time",
time: {
//isoWeekday: true,
unit: "week",
},
},
},
},
};
let myChart = new Chart(ctx, config);
It got plotted but the x-axis is not showing the second label:
enter image description here
what can I can do tomake the labels appear completely?

This is because by default the time scale auto generates ticks, if you dont want to include the labels from your data you need to set ticks.source to data:
options: {
scales: {
x: {
type: 'time',
ticks: {
source: 'data'
}
}
}
}

Related

Handle Date Gaps in Chart JS

I am plotting a graph using chart js. I have a couple of inconsistent data. For instance, the example data I have shared starts with 1909 and the next is 1960. In other cases, they are properly displayed: 1980, 1981, 1982...
Is there a way for me to handle specific data with gaps? For instance, have the year displayed sequentially.
const ctx = canvas.getContext("2d");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
label: "Country Population",
data: data,
}, ],
},
options: {
scales: {
x: {
title: {
display: true,
text: "Year",
},
xAxes: [{
type: 'time',
time: {
unit: 'year'
}
}]
},
y: {
title: {
display: true,
text: "Population",
},
},
},
},
});
How library you are using time and chart? I use chart(v3.8) and luxon(time) seems to work
const exampleData = [{
"x": +new Date('1909'),
"y": 48900202
},
{
"x": +new Date('1960'),
"y": 889030
},
{
"x": +new Date('1961'),
"y": 890203
},
{
"x": +new Date('1983'),
"y": 8904
},
]
const chartCfg = {
type: 'line',
data: {
datasets: [{
borderColor: 'green',
backgroundColor: 'green',
borderWidth: 1,
pointStyle: 'cross',
data: exampleData,
label: 'example',
}, ],
},
options: {
maintainAspectRatio: false,
animation: false,
parsing: false,
interaction: {
mode: 'index',
},
scales: {
x: {
type: 'time',
time: {
displayFormats: {
year: 'yyyy',
},
},
},
},
},
};
const chartCtx = document.getElementById('chart').getContext('2d');
const chart = new Chart(chartCtx, chartCfg);
chart.canvas.parentNode.style.height = '300px';
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.4.0/luxon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-luxon/1.1.0/chartjs-adapter-luxon.min.js"></script>
<canvas id="chart""></canvas>

Display ChartJS Data only when X is bigger than

I am trying to display data in a line chart from ChartJS, but my goal is to show only values after a specific year.
data: [
{
year: '1750',
value: 237.4646065136893,
},
{
year: '1755',
value: 275.8525403240655,
},
{
year: '1760',
value: 306.9496192507874,
},
{
year: '1790',
value: 330,
},
]
And I just want to show data later than 1755. My options scales config is the one below:
scales: {
xAxes: [
{
type: 'time',
time: {
format: 'YYYY',
stepSize: 5,
},
},
],
},
Do you know if there is a way to set some minX >= "1750"
You can filter the data and use the filtered data to feed the chart.
With Array.prototype.filter:
var newData = data.filter(function (el) {
return el.year >= 1755
});

How to feed hour and minute data into chartJS

I'm trying to make a line chart using Chart.js. My data is of the form:
var result = [{x:"18:00",y:"230"},{x:"19:00",y:"232"},{x:"20:00",y:"236"},{x:"22:00",y:"228"}];
Where x represents the time with hours and minutes. I fed the data like this
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["00:00","01:00","02:00","03:00","04:00","05:00","06:00","07:00","08:00","09:00","10:00","11:00","12:00","13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","21:00","22:00","23:00","24:00"],
datasets: [{
label: 'Voltage Fluctuation',
data: result,
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
position: 'bottom',
unit: 'minute',
time: {
displayFormats: {
hour: 'HH:mm'
}
}
}],
},
}
});
And I'm getting an empty chart. Where am I going wrong? I feel I'm doing something wrong with my labels since they don't show up on the chart but I don't understand how. Is there any way I can feed datalabels with momentjs?
You cannot just pass the result array to data, as it isn't in correct format. data property expects an array of numbers. So, you need to parse the labels (using moment.js) and data from result array before using them for the chart.
Here is how labels and data should be parsed from the result array and fed to the chart :
var result = [{ x: "18:00", y: "230" }, { x: "19:00", y: "232" }, { x: "20:00", y: "236" }, { x: "22:00", y: "228" }];
// parse labels and data
var labels = result.map(e => moment(e.x, 'HH:mm'));
var data = result.map(e => +e.y);
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Voltage Fluctuation',
data: data,
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'hour',
displayFormats: {
hour: 'HH:mm'
}
}
}]
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="myChart"></canvas>

How to Draw Gantt chart using chart js or other libraries

I want to draw Gantt chart like below
There is no option to draw Gantt chart in chart js. is it possible?? if not possible please suggest me some charting libraries to draw graph like this
I suggest you Scatter Chart. In Scatter Charts, you can draw multiple independent lines. As you can see from the below image.
[Sample Code]
var scatterChart = new Chart(ctx1, {
type: 'line',
data: {
datasets: [
{
label: 'Scatter Dataset',
backgroundColor: "rgba(246,156,85,1)",
borderColor: "rgba(246,156,85,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 0,
y: 9
}, {
x: 3,
y: 9
}
]
},
{
backgroundColor: "rgba(208,255,154,1)",
borderColor: "rgba(208,255,154,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 3,
y: 7
}, {
x: 5,
y: 7
}
]
},
{
label: 'Scatter Dataset',
backgroundColor: "rgba(246,156,85,1)",
borderColor: "rgba(246,156,85,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 5,
y: 5
}, {
x: 10,
y: 5
}
]
},
{
backgroundColor: "rgba(208,255,154,1)",
borderColor: "rgba(208,255,154,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 10,
y: 3
}, {
x: 13,
y: 3
}
]
}
]
},
options: {
legend : {
display : false
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks : {
beginAtzero :true,
stepSize : 1
}
}],
yAxes : [{
scaleLabel : {
display : false
},
ticks : {
beginAtZero :true,
max : 10
}
}]
}
}
});
Rest the configuration like colors or if you want to hide the y axes do it as your project required.
EDIT this method would not work efficiently for more complicated cases where multiple bars need to be shown for a single Y value.
I would go with a stacked horizontalbar chart of two datasets. The first dataset would be transparent and used to offset the second dataset which is your actual data. The code below prevents tooltip from appearing for the first dataset as well.
http://codepen.io/pursianKatze/pen/OmbWvZ?editors=1111
[SAMPLE CODE]
var barOptions_stacked = {
hover :{
animationDuration:10
},
scales: {
xAxes: [{
label:"Duration",
ticks: {
beginAtZero:true,
fontFamily: "'Open Sans Bold', sans-serif",
fontSize:11
},
scaleLabel:{
display:false
},
gridLines: {
},
stacked: true
}],
yAxes: [{
gridLines: {
display:false,
color: "#fff",
zeroLineColor: "#fff",
zeroLineWidth: 0
},
ticks: {
fontFamily: "'Open Sans Bold', sans-serif",
fontSize:11
},
stacked: true
}]
},
legend:{
display:false
},
};
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ["1", "2", "3", "4"],
datasets: [{
data: [50,150, 300, 400, 500],
backgroundColor: "rgba(63,103,126,0)",
hoverBackgroundColor: "rgba(50,90,100,0)"
},{
data: [100, 100, 200, 200, 100],
backgroundColor: ['red', 'green', 'blue', 'yellow'],
}]
},
options: barOptions_stacked,
});
// this part to make the tooltip only active on your real dataset
var originalGetElementAtEvent = myChart.getElementAtEvent;
myChart.getElementAtEvent = function (e) {
return originalGetElementAtEvent.apply(this, arguments).filter(function (e) {
return e._datasetIndex === 1;
});
}
.graph_container{
display:block;
width:600px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.js"></script>
<html>
<body>
<div class="graph_container">
<canvas id="myChart"></canvas>
</div>
</body>
</html>
Another open source option is Frappé Gantt
You can try this library jQuery.Gantt. It is very useful and provide lots of options to draw Gantt Chart
An easy solution to this is to use quickchart.io
The good support people at quickchart.io were kind enough to send me an example that includes dates on the x-axis unlike some of the answers above. You can access the example here.
If you would then like to embed a Gantt chart into Gmail email you would first need to send the HTML to a service such as htmlcsstoimage.com
I think it's easier with Highcharts.
Check out their documentation.
It's really easy to use when it comes to project management charts.
Here is a JSFiddle link to example usage.
var today = new Date(),
day = 1000 * 60 * 60 * 24,
// Utility functions
dateFormat = Highcharts.dateFormat,
defined = Highcharts.defined,
isObject = Highcharts.isObject;
// Set to 00:00:00:000 today
today.setUTCHours(0);
today.setUTCMinutes(0);
today.setUTCSeconds(0);
today.setUTCMilliseconds(0);
today = today.getTime();
Highcharts.ganttChart('container', {
series: [{
name: 'Offices',
data: [{
name: 'New offices',
id: 'new_offices',
owner: 'Peter'
}, {
name: 'Prepare office building',
id: 'prepare_building',
parent: 'new_offices',
start: today - (2 * day),
end: today + (6 * day),
completed: {
amount: 0.2
},
owner: 'Linda'
}, {
name: 'Inspect building',
id: 'inspect_building',
dependency: 'prepare_building',
parent: 'new_offices',
start: today + 6 * day,
end: today + 8 * day,
owner: 'Ivy'
}, {
name: 'Passed inspection',
id: 'passed_inspection',
dependency: 'inspect_building',
parent: 'new_offices',
start: today + 9.5 * day,
milestone: true,
owner: 'Peter'
}, {
name: 'Relocate',
id: 'relocate',
dependency: 'passed_inspection',
parent: 'new_offices',
owner: 'Josh'
}, {
name: 'Relocate staff',
id: 'relocate_staff',
parent: 'relocate',
start: today + 10 * day,
end: today + 11 * day,
owner: 'Mark'
}, {
name: 'Relocate test facility',
dependency: 'relocate_staff',
parent: 'relocate',
start: today + 11 * day,
end: today + 13 * day,
owner: 'Anne'
}, {
name: 'Relocate cantina',
dependency: 'relocate_staff',
parent: 'relocate',
start: today + 11 * day,
end: today + 14 * day
}]
}, {
name: 'Product',
data: [{
name: 'New product launch',
id: 'new_product',
owner: 'Peter'
}, {
name: 'Development',
id: 'development',
parent: 'new_product',
start: today - day,
end: today + (11 * day),
completed: {
amount: 0.6,
fill: '#e80'
},
owner: 'Susan'
}, {
name: 'Beta',
id: 'beta',
dependency: 'development',
parent: 'new_product',
start: today + 12.5 * day,
milestone: true,
owner: 'Peter'
}, {
name: 'Final development',
id: 'finalize',
dependency: 'beta',
parent: 'new_product',
start: today + 13 * day,
end: today + 17 * day
}, {
name: 'Launch',
dependency: 'finalize',
parent: 'new_product',
start: today + 17.5 * day,
milestone: true,
owner: 'Peter'
}]
}],
tooltip: {
pointFormatter: function () {
var point = this,
format = '%e. %b',
options = point.options,
completed = options.completed,
amount = isObject(completed) ? completed.amount : completed,
status = ((amount || 0) * 100) + '%',
lines;
lines = [{
value: point.name,
style: 'font-weight: bold;'
}, {
title: 'Start',
value: dateFormat(format, point.start)
}, {
visible: !options.milestone,
title: 'End',
value: dateFormat(format, point.end)
}, {
title: 'Completed',
value: status
}, {
title: 'Owner',
value: options.owner || 'unassigned'
}];
return lines.reduce(function (str, line) {
var s = '',
style = (
defined(line.style) ? line.style : 'font-size: 0.8em;'
);
if (line.visible !== false) {
s = (
'<span style="' + style + '">' +
(defined(line.title) ? line.title + ': ' : '') +
(defined(line.value) ? line.value : '') +
'</span><br/>'
);
}
return str + s;
}, '');
}
},
title: {
text: 'Gantt Project Management'
},
xAxis: {
currentDateIndicator: true,
min: today - 3 * day,
max: today + 18 * day
}
});
#container {
max-width: 800px;
margin: 1em auto;
}
<script src="https://code.highcharts.com/gantt/highcharts-gantt.js"></script>
<script src="https://code.highcharts.com/gantt/modules/exporting.js"></script>
<div id="container"></div>

x-axis displaying incorrectly in Highcharts php

I have the following code:
<script>
$.getJSON('https://www.quandl.com/api/v3/datasets/ECB/RTD_M_S0_N_C_EUR1Y_E.json?start_date=2003-01-01', function(json) {
var hiJson = json.dataset.data.map(function(d) {
return [new Date(d[0]), d[1]]
});
// var hiJson = json.dataset.data.map(function(d) {
// return { x: new Date(d[0]), y: d[1] };
// });
// Create the chart
$('#Euribor').highcharts('chart', {
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
day: '%Y'
}
},
rangeSelector: {
selected: 1
},
title: {
text: 'Euribor Interest Rates',
},
series: [{
type: 'line',
name: 'Interest Rate',
data: hiJson,
}]
});
});
</script>
This prints out a Highcharts chart, but the x-axis is incorrect. It should be in Years, but it looks more like it's a time format.
Your help is much appreciated!
R

Categories