I'm trying to make a chart to display the revenues of a company, and I would like to display the predictions for this year but with a borderDash segment option. How could I do that? I tried this and I have no clue how to do it.
const lineCanvas = document.getElementById("lineCanvas");
const prediction = (ctx, value) => ctx.dataIndex = 4 ? value : undefined;
const lineChart = new Chart(lineCanvas, {
type: "line",
data: {
labels: ["2019", "2020", "2021", "2022"],
datasets: [{
label: "Revenues",
data: [2195, 2225, 2166, 2250],
backgroundColor: "orange",
borderColor: "orange",
segment: {
borderDash: ctx => prediction(ctx, [6, 6])
}
}]
},
options: {
scales: {
y: {
ticks: {
font: {
size: 18
},
stepSize: 10
},
title: {
display: true,
text: "Total",
font: {
size: 14
}
},
},
x: {
ticks: {
font: {
size: 18
}
},
title: {
display: true,
text: "Year",
font: {
size: 14
}
}
}
},
plugins: {
title: {
display: true,
text: "Company's Revenues",
font: {
size: 22
},
padding: 0
},
subtitle: {
display: true,
text: "(in millions of €)",
font: {
size: 18
},
padding: 0
}
}
}
});
Here's the expected result:
Image of the expected result
I hope somebody can help me with that.
Thanks in advance.
What about adding an extra dataset for your forecast data. Style this second set with a dashed line? Yes, that results in 2 datasets. One for the data and one for the prediction. Hope that helps.
As example (not tested, just as example):
const lineChart = new Chart(lineCanvas, {
type: "line",
data: {
labels: ["2019", "2020", "2021", "2022"],
datasets: [{
label: "Revenues",
data: [2195, 2225, 2166, 2250],
backgroundColor: "orange",
borderColor: "orange",
}, {
label: "Revenues",
data: [2195, 2225, 2166, 2250, 6000, 9000], /* Add the extra data points */
borderColor: "red" /* Whatever style you like */
}]
}, options:[] });
Related
I currently display my data like this:
Click here
but I would like to display the data like this:
Click here
The idea is that at the bottom it would show the summary of all three colors numbers combined, but once you hover it would show how much each color has.
If all is one bar, if red is 7, blue is 3, the red but be a lot more in the bar.
This is the code for version 1, done with chart js
var ctx = document.getElementById("myChart").getContext("2d");
var data = {
labels: ["Chocolate", "Vanilla", "Strawberry"],
datasets: [
{
label: "Blue",
backgroundColor: "blue",
data: [3, 7, 4]
},
{
label: "Red",
backgroundColor: "red",
data: [4, 3, 5]
},
{
label: "Green",
backgroundColor: "green",
data: [7, 2, 6]
}
]
};
var myBarChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
barValueSpacing: 20,
scales: {
yAxes: [{
ticks: {
min: 0,
}
}]
}
}
});
const myChart = new Chart(
document.getElementById('myChart'),
config
);
your problem is the next, you are using a wrong config you must something like this:
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.6.0/dist/chart.min.js"></script>
<canvas id="MyChart" width="400" height="200"></canvas>
<script>
new Chart(document.getElementById("MyChart"), {
type: 'bar',
data: {
labels: [2017],
datasets: [{
label: "Chocolate",
type: "bar",
stack: "Base",
backgroundColor: "#eece01",
data: [30],
}, {
label: "Vanilla",
type: "bar",
stack: "Base",
backgroundColor: "#87d84d",
data: [-15],
}, {
label: "Strawberry",
type: "bar",
stack: "Base",
backgroundColor: "#f8981f",
data: [20],
}, {
label: "candy",
type: "bar",
stack: "Base",
backgroundColor: "#00b300",
backgroundColorHover: "#3e95cd",
data: [-10]
}]
},
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
interaction: {
intersect: false,
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
});
</script>
Now you just need to fix the styles and sizes of the graphic
If someone finds this, the solution is this:
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
};
I have a horizontal stacked bars with 3 labels with the same order for the colors. I would like to know how can I reverse the color order for the first label only so that it goes from dark blue to dark red and keep the same color flow for label 2 and 3.
https://jsfiddle.net/samwhite/s9yzuqd5/
var colors = ['#93003a', '#f4777f', '#ffb040', '#a5d5d8', '#00429d'];
var def_color = '#d3d3d3';
let labels = [
"In my organization, more emphasis is placed on quantity of work than on the quality of work",
"My Division/Office/Region is making real, meaningful progress on diversity, inclusion, and opportunity in our workplace",
"In my Division/Office/Region, I am given a fair opportunity to work on visible, career-enhancing assignments"
];
// Construct the chart
let chart = Highcharts.chart('container1_1', {
...
yAxis: {
title: { text: 'Response Rate' },
max: 100,
maxPadding: 0,
labels: {
format: '{value}%'
},
gridLineWidth: 0,
minorGridLineWidth: 0
},
...
xAxis: {
categories: labels,
labels: {
style: {
fontSize: '1em',
color: '#000',
width: 370,
float: 'left'
}
}
},
series: [{
name: 'Strongly Agree',
color: colors[4],
data: []
}, {
name: 'Agree',
color: colors[3],
data: []
}, {
name: 'Neither Agree nor Disagree',
color: colors[2],
data: []
}, {
name: 'Disagree',
color: colors[1],
data: []
}, {
name: 'Strongly Disagree',
color: colors[0],
data: []
}]
});
Added Color on each data set to work in the color scheme needed based on the index
you can see the reference here: https://api.highcharts.com/highcharts/series.bar.data
{
name: tooltip_titles[s],
color: colors[Math.abs(s - 4)],
y: dept_data["102"][4-s]
},
Old - https://jsfiddle.net/jouwsLn0/
New - https://jsfiddle.net/js1bfxe5/1/
series: [{
name: 'Strongly Agree',
color: colors[4],
data: []
}, {
name: 'Agree',
color: colors[3],
data: []
}, {
name: 'Neither Agree nor Disagree',
color: colors[2],
data: []
}, {
name: 'Disagree',
color: colors[1],
data: []
}, {
name: 'Strongly Disagree',
color: colors[0],
data: []
}]
});
$("#filterOrganization").change(function () {
$(this).find("option:selected")
.each(function () {
var optionValue = $(this).text();
let dept_data = data[optionValue];
chart.series.forEach((series, s) => {
console.log(s);
console.log(dept_data["102"][4-s]);
series.setData([
{
name: tooltip_titles[s],
color: colors[Math.abs(s - 4)],
y: dept_data["102"][4-s]
},
{
name: tooltip_titles[s],
color: colors[s],
y: dept_data["104"][4-s]
},
{
name: tooltip_titles[s],
color: colors[s],
y: dept_data["105"][4-s]
}]);
});
});
}).change();
I am using mixed chart (bar and two lines). Everything is working fine until I added time unit on the x-axis. The first bar in the chart moves to left.
var data = [
{
date: "2014-01-04 22:23:00",
pop: 20,
rh: 67,
temp: 38,
wspd: 7
},
{
date: "2014-02-04 22:23:00",
pop: 15,
rh: 69,
temp: 39,
wspd: 8
},
];
new Chart(document.getElementById("canvas"), {
type: 'bar',
data: {
labels: data.map(d => new Date(d.date)),
datasets: [{
label: "RH",
type: "line",
borderColor: "#8e5ea2",
data: data.map(d => d.rh),
fill: false
}, {
label: "Temp",
type: "bar",
backgroundColor: "rgba(0,0,0,0.2)",
data: data.map(d => d.temp),
}
]
},
options: {
title: {
display: true,
text: 'Daily Forecast'
},
legend: { display: true },
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'month'
}
}],
},
}
});
I'm using chart.js API to render a several stacked vertical bars chart, but the performance is slow. I even made some changes such that all the content object was already processed by the server, and not the browser, but I realised the big majority of time comes from the final function new Chart(overallStatsChart, content);.
I also tried switching off animation, which slightly improved performance, but not that much.
Any ideas on how to improve performance, that is, initial loading?
var countryList = {"AR":"Argentina","AU":"Australia","BO":"Bolivia","BR":"Brasil","CA":"Canada","CL":"Chile","CN":"中国","CO":"Colombia","CR":"Costa Rica","CU":"Cuba","CZ":"Česká","DE":"Deutschland","DK":"Danmark","DO":"Rep. Dominicana","EC":"Ecuador","ES":"España","FI":"Suomessa","FR":"France","GR":"Ελλάδα","GT":"Guatemala","HU":"Magyarország","IE":"Ireland","IN":"India","IT":"Italia","JP":"日本","MX":"México","NI":"Nicaragua","NL":"Nederland","NO":"Norge","PA":"Panamá","PE":"Perú","PL":"Polska","PR":"Puerto Rico","PT":"Portugal","PY":"Paraguay","RO":"România","RU":"Россия","SE":"Sverige","SV":"El Salvador","TR":"Türkiye","UA":"Україна","UK":"United Kingdom","US":"USA","UY":"Uruguay","VE":"Venezuela"};
//populates country labels
var labels = [], size = 0;
for (var key in countryList){
labels.push(key);
size++;
}
var _data = function(i){
var arr = [];
for (var n=0; n<size; n++){
arr.push(n==i ? 1 : 0);
}
return arr;
};
var dataset = [], i=0;
for (var key in countryList){
dataset.push(
{
label: "depreciation",
data: _data(i),
backgroundColor: 'navy'
}, {
label: "insurance",
data: _data(i),
backgroundColor: 'blue'
}, {
label: "credit",
data: _data(i),
backgroundColor: 'aqua'
}, {
label: "inspection",
data: _data(i),
backgroundColor: 'teal'
}, {
label: "road taxes",
data: _data(i),
backgroundColor: 'olive'
}, {
label: "maintenance",
data: _data(i),
backgroundColor: 'green'
}, {
label: "repairs",
data: _data(i),
backgroundColor: 'lime'
}, {
label: "fuel",
data: _data(i),
backgroundColor: 'maroon'
}, {
label: "parking",
data: _data(i),
backgroundColor: 'yellow'
}, {
label: "tolls",
data: _data(i),
backgroundColor: 'orange'
}, {
label: "fines",
data: _data(i),
backgroundColor: 'red'
}, {
label: "washing",
data: _data(i),
backgroundColor: 'purple'
}, {
label: "maintenance",
data: _data(i),
backgroundColor: 'green'
}
);
i++;
}
var options = {
maintainAspectRatio: false,
legend: {
position: 'bottom', // place legend on the right side of chart
display: false, //do not display
labels : {
fontSize: 9,
fontColor: 'black'
}
},
scales: {
xAxes: [{
stacked: true, // this should be set to make the bars stacked
beginAtZero: true
}],
yAxes: [{
stacked: true, // this also..
beginAtZero: true
}]
},
animation: {
duration : 1000,
easing : 'linear'
}
};
var content = {
type: 'bar',
data: {
labels: labels,
datasets: dataset
},
options: options
};
//I made tests with timestamps and here it takes the biggest part of the time
new Chart(overallStatsChart, content);
.chart {
position: relative;
margin: auto;
}
#overallStatsChartDiv{
min-height: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<div class="chart" id="overallStatsChartDiv">
<canvas id="overallStatsChart"></canvas>
</div>
Now I get it :)
I was wrongly duplicating the data attributes, based on this answer.
Solution is quite simple, every data attribute can have directly all the values, without the need of introduction of zeros.
var countryList = {"AR":"Argentina","AU":"Australia","BO":"Bolivia","BR":"Brasil","CA":"Canada","CL":"Chile","CN":"中国","CO":"Colombia","CR":"Costa Rica","CU":"Cuba","CZ":"Česká","DE":"Deutschland","DK":"Danmark","DO":"Rep. Dominicana","EC":"Ecuador","ES":"España","FI":"Suomessa","FR":"France","GR":"Ελλάδα","GT":"Guatemala","HU":"Magyarország","IE":"Ireland","IN":"India","IT":"Italia","JP":"日本","MX":"México","NI":"Nicaragua","NL":"Nederland","NO":"Norge","PA":"Panamá","PE":"Perú","PL":"Polska","PR":"Puerto Rico","PT":"Portugal","PY":"Paraguay","RO":"România","RU":"Россия","SE":"Sverige","SV":"El Salvador","TR":"Türkiye","UA":"Україна","UK":"United Kingdom","US":"USA","UY":"Uruguay","VE":"Venezuela"};
//populates country labels
var labels = [], size = 0;
for (var key in countryList){
labels.push(key);
size++;
}
var _data = function(){
var arr = [];
for (var n=0; n<size; n++){
arr.push(1);
}
return arr;
};
var dataset = [
{
label: "depreciation",
data: _data(),
backgroundColor: 'navy'
}, {
label: "insurance",
data: _data(),
backgroundColor: 'blue'
}, {
label: "credit",
data: _data(),
backgroundColor: 'aqua'
}, {
label: "inspection",
data: _data(),
backgroundColor: 'teal'
}, {
label: "road taxes",
data: _data(),
backgroundColor: 'olive'
}, {
label: "maintenance",
data: _data(),
backgroundColor: 'green'
}, {
label: "repairs",
data: _data(),
backgroundColor: 'lime'
}, {
label: "fuel",
data: _data(),
backgroundColor: 'maroon'
}, {
label: "parking",
data: _data(),
backgroundColor: 'yellow'
}, {
label: "tolls",
data: _data(),
backgroundColor: 'orange'
}, {
label: "fines",
data: _data(),
backgroundColor: 'red'
}, {
label: "washing",
data: _data(),
backgroundColor: 'purple'
}, {
label: "maintenance",
data: _data(),
backgroundColor: 'green'
}
];
var options = {
maintainAspectRatio: false,
legend: {
position: 'bottom', // place legend on the right side of chart
display: false, //do not display
labels : {
fontSize: 9,
fontColor: 'black'
}
},
scales: {
xAxes: [{
stacked: true, // this should be set to make the bars stacked
beginAtZero: true
}],
yAxes: [{
stacked: true, // this also..
beginAtZero: true
}]
},
animation: {
duration : 1000,
easing : 'linear'
}
};
var content = {
type: 'bar',
data: {
labels: labels,
datasets: dataset
},
options: options
};
//I made tests with timestamps and here it takes the biggest part of the time
new Chart(overallStatsChart, content);
.chart {
position: relative;
margin: auto;
}
#overallStatsChartDiv{
min-height: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<div class="chart" id="overallStatsChartDiv">
<canvas id="overallStatsChart"></canvas>
</div>
We made some section in Flot Pie Chart but we can't get data for jquery data setting which is coming in left side area in default plugin show two field but we want to show three data. We are using flot pie chart jquery plugin :-
please see the image:-
jquery setting :-
// Flot Pie Chart - Traffic Sources bar
$(function() {
var data = [{
label: "Direct",
data: 15,
color: "#d3d3d3",
}, {
label: "Display",
data: 5,
color: "#bababa",
}, {
label: "Organic",
data: 30,
color: "#79d2c0",
}, {
label: "Paid",
data: 15,
color: "#1ab394",
}, {
label: "Referral",
data: 20,
color: "#049e7f",
}, {
label: "Social",
data: 15,
color: "#00775f",
}];
var plotObj = $.plot($("#traffic-sources"), data, {
series: {
pie: {
show: true
}
},
grid: {
hoverable: true
},
tooltip: true,
tooltipOpts: {
content: "%p.0%, %s", // show percentages, rounding to 2 decimal places
shifts: {
x: 20,
y: 0
},
defaultTheme: false
}
});
var addTd = '<td class="legendData"> hello </td>';
$('#traffic-sources').find('.legendColorBox').next().before(addTd);
});
$(function() {
var data = [{
label: "Direct",
data: 15,
color: "#d3d3d3",
}, {
label: "Display",
data: 5,
color: "#bababa",
}, {
label: "Organic",
data: 30,
color: "#79d2c0",
}, {
label: "Paid",
data: 15,
color: "#1ab394",
}, {
label: "Referral",
data: 20,
color: "#049e7f",
}, {
label: "Social",
data: 15,
color: "#00775f",
}];
for (var i = 0; i < data.length; i++) {
//put the data value into the label
data[i].label = ' ' + data[i].data + '% ' + data[i].label;
}
var plotObj = $.plot($('#traffic-sources'), data, {
series: {
pie: {
show: true,
}
},
grid: {
hoverable: true
},
tooltip: true,
legend: {
show: true
},
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/flot/flot/958e5fd4/jquery.flot.js"></script>
<script src="https://cdn.rawgit.com/flot/flot/master/jquery.flot.pie.js"></script>
<div id="traffic-sources" style="width:500px;height:400px;"></div>
loop through all your data object and concatenate your label with data data[i].label = ' '+data[i].data+'% '+data[i].label; and then show it.