Chart.js: Sort the stacked bars by value - javascript

I have the following stacked bar chart with the sample data. I want that per year (label) the individual stacked bars are sorted by the value. E.g. for 2019 the bar should be (form top to bottom) red (50), blue (20) and black (10).
https://jsfiddle.net/7rna08dm/2/
How can I achieve this? Is there the possibility to do this with the datasets property? Or is there any bar sorting property?
Currenctly I'm using the following data structure and didn't find a solution to achieve the expected behaviour with sorting the data:
data: {
labels: ['2017', '2018', '2019', '2020', '2021', '2022'],
datasets: [
{
label: 'Max',
data: [0, 0, 50, 10, 0, 70],
backgroundColor: 'red',
},
{
label: 'Peter',
data: [10, 0, 20, 30, 0, 0],
backgroundColor: 'blue',
},
{
label: 'Dave',
data: [0, 0, 10, 20, 0, 30],
backgroundColor: 'black',
},
],
},

Related

Remove space on bar ZingChart

I'm making a chart here and I have a little problem with removing the distance between the boxes
var myConfig = {
type: 'bar',
legend: {
layout: "x4",
overflow : "page",
shadow : false,
align : "left",
alpha :0.05,
"adjust-layout": true,
marker : {
type : "circle",
size : "7px",
"border-color" :"none"
}
},
scaleX: {
// convert text on scale indices
labels: ['Automotive', 'Retail', 'Wholesale']
},
plot: {
barWidth:"50%",
animation: {
effect: 'ANIMATION_EXPAND_BOTTOM',
method: 'ANIMATION_STRONG_EASE_OUT',
sequence: 'ANIMATION_BY_NODE',
speed: 275,
}
},
series: [
{
// plot 1 values, linear data
values: [23, 20, 27],
text: 'Sum of target Premi',
backgroundColor: '#fa6383',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [35, 42, 33],
text: 'Sum of premi Leads',
backgroundColor: '#fb9f40',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Activity',
backgroundColor: '#fdcd55',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Booking',
backgroundColor: '#4bc0c1',
borderRadius: 5,
}
]
};
for my settings like this. there are suggestions so there can be no space ?
i have try documentation but does not work.
https://www.zingchart.com/docs/chart-types/bar
I'm not sure that I correctly understood your problem but probably you can try to use "barsOverlap" in "plot" configuration to achieve the desired result.
var myConfig = {
type: 'bar',
legend: {
layout: "x4",
overflow : "page",
shadow : false,
align : "left",
alpha :0.05,
"adjust-layout": true,
marker : {
type : "circle",
size : "7px",
"border-color" :"none"
}
},
scaleX: {
// convert text on scale indices
labels: ['Automotive', 'Retail', 'Wholesale']
},
plot: {
barWidth:"50%",
barsOverlap: '50%',
animation: {
effect: 'ANIMATION_EXPAND_BOTTOM',
method: 'ANIMATION_STRONG_EASE_OUT',
sequence: 'ANIMATION_BY_NODE',
speed: 275,
}
},
series: [
{
// plot 1 values, linear data
values: [23, 20, 27],
text: 'Sum of target Premi',
backgroundColor: '#fa6383',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [35, 42, 33],
text: 'Sum of premi Leads',
backgroundColor: '#fb9f40',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Activity',
backgroundColor: '#fdcd55',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Booking',
backgroundColor: '#4bc0c1',
borderRadius: 5,
}
]
};

How to make Chart.js with dynamic months on x-axis

I'm trying to make a Chart.js with a dynamic x-axis that will always use the next 7 months as the ticks for the x-axis.
But I'm having two problems:
The lines are not showing on my graph
The x-axis is only showing the first and last month, none of the months in-between.
Here is an example I made in paint to show what I'm trying to achieve:
And here is the code I have so far:
/* Build the charts */
var ctx = document.getElementById('ROIchart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
datasets: [{
label: 'Paid Search and Leads',
backgroundColor: 'red',
borderColor: 'red',
data: [10, 10, 10, 10, 10, 10, 10],
}, {
label: 'SEO and Content',
backgroundColor: 'green',
borderColor: 'green',
data: [0, 2, 8, 21, 57, 77, 100],
fill: true,
}]
},
// Configuration options go here
options: {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'month'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="ROIchart"></canvas>
With the moment.js library, you can look at the length of your array, and from a starting month generate the months, and then put them as labels
/* Build the charts */
var ctx = document.getElementById('ROIchart').getContext('2d');
var array1 = [10, 10, 10, 10, 10, 10, 10];
var months = []
for (let i = 0; i < array1.length; i++) {
months.push(moment().year(2020).month(i+1).date(0).startOf('month'))
}
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: months,
datasets: [{
label: 'Paid Search and Leads',
backgroundColor: 'red',
borderColor: 'red',
data: array1,
}, {
label: 'SEO and Content',
backgroundColor: 'green',
borderColor: 'green',
data: [0, 2, 8, 21, 57, 77, 100],
fill: true,
}]
},
options: {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'month'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
<canvas id="ROIchart"></canvas>

Refreshing the image of a chart using chart.js

I'm doing an app that displays daily personal work data.
I store the data in an array called "dailyTimePerProjectPerWeek", for now I define the data for 3 weeks.
I have placed two buttons in the html, "Previous Week" and "Next Week", to navigate between the weeks.
When the page is loaded for the first time it shows the most recent week corresponding to the highest index of the array mentioned above.
The problem is that it does something strange to me to visualize the data, it's like that I created several charts.
How can I refresh the image of the chart properly?
There goes my html code:
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Charts4DailyProgress</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<body>
<h1>Weekly Time per Project</h1>
<div id="canvas-container">
<canvas id="ctx" width="1000"></canvas>
<button type="button" onclick="decrementWeek()">Previous Week</button>
<button type="button" onclick="incrementWeek()">Next Week</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>
There goes my javascript code:
var dailyTimePerProjectPerWeek =[];
dailyTimePerProjectPerWeek[0] = {
labels: ['M', 'TU','W','TH','F','SA','SU'], // responsible for how many bars are gonna show on the chart
// create 12 datasets, since we have 12 items
// data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')
// put 0, if there is no data for the particular bar
datasets: [{
label: 'Master Project. Second Part',
data: [300, 480, 360,180, 240, 300,480],
backgroundColor: '#D4AF37'
}, {
label: 'Guild Ideas - Learning Angular',
data: [60, 0, 240, 180, 120, 0, 60],
backgroundColor: '#C0C0C0'
}, {
label: 'Charts For Daily Progress',
data: [60, 180, 120, 180, 120, 120, 0],
backgroundColor: '#133a7c'
}, {
label: 'Project Manager',
data: [120, 180, 120, 120, 0],
backgroundColor: '#109618'
}, {
label: 'TOOYS',
data: [0, 180, 120, 0, 120, 0,0],
backgroundColor: '#990099'
}, {
label: 'Web Pc Explorer',
data: [0, 0, 120, 180, 0, 120, 0],
backgroundColor: '#54161F'
}, {
label: 'Mind Maps Program',
data: [0, 0, 180, 180, 0, 0, 0],
backgroundColor: '#708238'
}, {
label: 'Chain System',
data: [0, 0, 180, 0, 0, 0],
backgroundColor: '#E86100'
}, {
label: 'Code Generator',
data: [60, 0, 0, 0, 0, 0],
backgroundColor: '#F81894'
}, {
label: 'Electronic Brain',
data: [0, 0, 0, 0, 0, 0,240],
backgroundColor: '#6cc4ee'
}]
}
dailyTimePerProjectPerWeek[1] = {
labels: ['M', 'TU','W','TH','F','SA','SU'], // responsible for how many bars are gonna show on the chart
// create 12 datasets, since we have 12 items
// data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')
// put 0, if there is no data for the particular bar
datasets: [{
label: 'Master Project. Second Part',
data: [0, 480, 360,180, 240, 300,480],
backgroundColor: '#D4AF37'
}, {
label: 'Guild Ideas - Learning Angular',
data: [0, 0, 240, 180, 120, 0, 60],
backgroundColor: '#C0C0C0'
}, {
label: 'Charts For Daily Progress',
data: [0, 180, 120, 180, 120, 120, 0],
backgroundColor: '#133a7c'
}, {
label: 'Project Manager',
data: [0, 180, 120, 120, 0],
backgroundColor: '#109618'
}, {
label: 'TOOYS',
data: [0, 180, 120, 0, 120, 0,0],
backgroundColor: '#990099'
}, {
label: 'Web Pc Explorer',
data: [0, 0, 120, 180, 0, 120, 0],
backgroundColor: '#54161F'
}, {
label: 'Mind Maps Program',
data: [0, 0, 180, 180, 0, 0, 0],
backgroundColor: '#708238'
}, {
label: 'Chain System',
data: [0, 0, 180, 0, 0, 0],
backgroundColor: '#E86100'
}, {
label: 'Code Generator',
data: [0, 0, 0, 0, 0, 0],
backgroundColor: '#F81894'
}, {
label: 'Electronic Brain',
data: [0, 0, 0, 0, 0, 0,240],
backgroundColor: '#6cc4ee'
}]
}
dailyTimePerProjectPerWeek[2] = {
labels: ['M', 'TU','W','TH','F','SA','SU'], // responsible for how many bars are gonna show on the chart
// create 12 datasets, since we have 12 items
// data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')
// put 0, if there is no data for the particular bar
datasets: [{
label: 'Master Project. Second Part',
data: [300, 480, 360,180, 240, 300,0],
backgroundColor: '#D4AF37'
}, {
label: 'Guild Ideas - Learning Angular',
data: [60, 0, 240, 180, 120, 0, 0],
backgroundColor: '#C0C0C0'
}, {
label: 'Charts For Daily Progress',
data: [60, 180, 120, 180, 120, 120, 0],
backgroundColor: '#133a7c'
}, {
label: 'Project Manager',
data: [120, 180, 120, 120, 0],
backgroundColor: '#109618'
}, {
label: 'TOOYS',
data: [0, 180, 120, 0, 120, 0,0],
backgroundColor: '#990099'
}, {
label: 'Web Pc Explorer',
data: [0, 0, 120, 180, 0, 120, 0],
backgroundColor: '#54161F'
}, {
label: 'Mind Maps Program',
data: [0, 0, 180, 180, 0, 0, 0],
backgroundColor: '#708238'
}, {
label: 'Chain System',
data: [0, 0, 180, 0, 0, 0],
backgroundColor: '#E86100'
}, {
label: 'Code Generator',
data: [60, 0, 0, 0, 0, 0],
backgroundColor: '#F81894'
}, {
label: 'Electronic Brain',
data: [0, 0, 0, 0, 0, 0,0],
backgroundColor: '#6cc4ee'
}]
}
var currentWeek = dailyTimePerProjectPerWeek.length - 1;
var weekValue = currentWeek; //At first time weekValue points to the current week
function drawData(){
var chart = new Chart(ctx, {
type: 'bar',
data: dailyTimePerProjectPerWeek[weekValue],
options: {
responsive: false,
legend: {
position: 'right' // place legend on the right side of chart
},
scales: {
xAxes: [{
stacked: true // this should be set to make the bars stacked
}],
yAxes: [{
stacked: true // this also..
}]
}
}
});
}
function incrementWeek(){
if(weekValue === dailyTimePerProjectPerWeek.length - 1){
console.log("This is the current week");
} else {
weekValue += 1;
drawData();
}
}
function decrementWeek(){
if(weekValue === 0){
console.log("This is the oldest week of the time series");
} else {
weekValue -= 1;
drawData();
}
}
/*
function selectWeek(){
}
*/
/*
function fixWeek(){
}*/
//Main Program
var chart = new Chart(ctx, {
type: 'bar',
data: dailyTimePerProjectPerWeek[weekValue],
options: {
responsive: false,
legend: {
position: 'right' // place legend on the right side of chart
},
scales: {
xAxes: [{
stacked: true // this should be set to make the bars stacked
}],
yAxes: [{
stacked: true // this also..
}]
}
}
});
The truth is that I use the following code to try to refresh the image:
function drawData(){
var chart = new Chart(ctx, {
type: 'bar',
data: dailyTimePerProjectPerWeek[weekValue],
options: {
responsive: false,
legend: {
position: 'right' // place legend on the right side of chart
},
scales: {
xAxes: [{
stacked: true // this should be set to make the bars stacked
}],
yAxes: [{
stacked: true // this also..
}]
}
}
});
}
Change your drawData() function to:
function drawData() {
chart.data = dailyTimePerProjectPerWeek[weekValue];
chart.update();
}

Charts JS: Doughnut chart and hiding tooltip for specific data index within each dataset

I am trying to take a chartJS doughnut chart and instead of it displaying each piece of data on a single dataset I want each unique piece of data (with its own unique label) to display on its own dataset. This means to represent that data on each dataset it still needs two pieces of data:
- the desired value (ie. 80%)
- the difference value (ie. 20%)
After some research I figured out how to use callback function to display the dataset label to each of its data values and add a percentage character after its number value. Now I am trying to hide the tooltip for the second data value within each dataset. I am new to javascript so a little help would be appreciated! Cheers.
Chart.defaults.global.defaultFontSize = 16;
Chart.defaults.global.defaultFontColor = '#000';
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [
/* Outer doughnut data starts*/
{
data: [90, 10],
backgroundColor: [
'rgba(210, 35, 42, 1)',
'rgba(0, 0, 0, 0.05)'
],
label: 'Skill #1'
},
/* Outer doughnut data ends*/
/* Inner doughnut data starts*/
{
data: [50, 50],
backgroundColor: [
'rgba(210, 35, 42, 0.75)',
'rgba(0, 0, 0, 0.05)'
],
label: 'Skill #2'
},
/* Inner doughnut data ends*/
{
data: [15, 85],
backgroundColor: [
'rgba(210, 35, 42, 0.5)',
'rgba(0, 0, 0, 0.05)'
],
label: 'Skill #3'
},
{
data: [5, 95],
backgroundColor: [
'rgba(210, 35, 42, 0.25)',
'rgba(0, 0, 0, 0.05)'
],
label: 'Skill #4'
}
],
},
options: {
title: {
display: true,
text: 'My Skills',
fontSize: 24,
},
scales: {
xAxes: [{
gridLines: {
display: false,
drawBorder: false,
},
ticks: {
display: false,
}
}],
yAxes: [{
gridLines: {
display: false,
drawBorder: false,
},
ticks: {
display: false,
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var dslabelamt = dataset.data[tooltipItem.index];
return data.datasets[tooltipItem.datasetIndex].label + ': ' + dslabelamt + '%';
}
}
}
}
});
https://codepen.io/manudan711/pen/aadYRj
those data-sets in chart.js don't work alike series in other charts do, but are index-based. therefore you'd require only two datasets and then you'd have to map those values accordingly; so that index position 0, 1, 2, 3, ... on both of the data arrays, would sum up to 100.

How to limit the data points to get display in highchart

I have a requirement to limit the data points in highchart when it displayed due to space issue. Let's say if I have 100 data points in one series. I just want to display first 5 and when clicking on the expand button(I need to add a expand button in the chart) the highchart will display with all 100 points. (The expanded view will be in a modal window and the modal window will have the full hight).
I know the series are complex like, I can have multiple series in the to chart like this
series: [{
name: 'Year 1800',
data: [107, 31, 635, 203, 2]
}, {
name: 'Year 1900',
data: [133, 156, 947, 408, 6]
}, {
name: 'Year 2012',
data: [1052, 954, 4250, 740, 38]
}]
and I can have complex data model like this
1.data: [1052, 954, 4250, 740, 38]
2.data: [[5, 2], [6, 3], [8, 2]]
3.
data: [{
name: 'Point 1',
color: '#00FF00',
y: 0
}, {
name: 'Point 2',
color: '#FF00FF',
y: 5
}]
Note: Am not setting the series, am creating a widget in JavaScript which includes Highchart inside it. I can override the Highchart code for this.

Categories