I am trying to create a donut chart with chart.js using data from csv file. Following is my script so far, but it is not working. Any guidance is appreciated on the same.
<script>
var file='donut.csv';
d3.csv(file).then(makeChart); //use d3.csv to read file
function makeChart(types){
var can=types.map(function(d){return d.cancelled});
var suc=types.map(function(d){return d.success});
var fa=types.map(function(d){return d.failed});
{
var chart=new Chart(document.getElementById("doughnut-chart"), {
type: 'doughnut',
data: {
labels: ["Cancelled","Success", "Failed"],
datasets: [
{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#3cba9f","#8e5ea2"],
data: [can,suc,fa]
}
]
},
options: {
title: {
display: true,
text: 'Weekly Status'
}
}
}
}
);
</script>
and my donut.csv looks like as below:
cancelled,300,
success,1000,
failed,20,
Since your CSV data has no header, you should use d3.text to load the data, followed by d3.csvParseRows to parse it to a JSON array (see https://stackoverflow.com/a/13870360/2358409). To extract the data values from the JSON array, you can use Array.map.
data: d3.csvParseRows(types).map(v => v[1])
Please take a look at your amended code and see how it works.
d3.text("https://raw.githubusercontent.com/uminder/testdata/main/so/csv/donut.csv").then(makeChart);
function makeChart(types) {
new Chart('doughnut-chart', {
type: 'doughnut',
data: {
labels: ['Cancelled', 'Success', 'Failed'],
datasets: [{
label: 'Population (millions)',
backgroundColor: ['#3e95cd', '#3cba9f', '#8e5ea2'],
data: d3.csvParseRows(types).map(v => v[1])
}]
},
options: {
title: {
display: true,
text: 'Weekly Status'
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="doughnut-chart" height="90"></canvas>
Related
I want to display values with predefined units. e.g.: 22.00B/s
The data structure looks like this:
['6.84KB/s', '4.49KB/s', '3.42KB/s']
But only such data are displayed:
['7.5', '4.3', '10.3']
How can I display such values?
3.42KB/s
(Without removing letters or special characters)
You will need to use a category scale for this:
const options = {
type: 'bar',
data: {
labels: ["val1", "val2", "val3"],
datasets: [{
label: '# of Votes',
data: ['6.84KB/s', '4.49KB/s', '3.42KB/s'],
backgroundColor: 'pink'
}]
},
options: {
scales: {
y: {
type: 'category',
labels: ['6.84KB/s', '4.49KB/s', '3.42KB/s'],
reverse: true
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.2/chart.js"></script>
</body>
I am currently trying to create a doughnut chart that represents a projects completion with 2 mains sections; complete and incomplete. is there any way that I can make it so that the complete sections is split into multiple subsections which display peoples usernames when hovered without cluttering the legend?
Beneath is an artistic rendition because I feel like I haven't given enough information.
You can use the generateLabels function as described here.
Please take a look at below runnable sample code and see how it works.
var labels = ['Incomplete', 'Sam', 'Claudia', 'Kevin', 'Sonia', 'Kate'];
var data = [14, 5, 4, 3, 7, 5];
new Chart('myChart', {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: labels.map((l, i) => i ? 'yellow' : 'lightblue'),
weight: 0.6
}]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: () => [{
text: 'Incomplete',
fillStyle: 'lightblue',
strokeStyle: 'lightblue',
},
{
text: 'Complete',
fillStyle: 'yellow',
strokeStyle: 'yellow',
}]
}
}
}
}
});
canvas {
max-height: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart"></canvas>
I'm trying to use chart.js to create a bar chart that shows the number of ad impressions in an ad buy by publication. The desired chart would show a bar for each publication representing the number of impressions for the ad on that website.
I thought that this needs to happen as multiple datasets, one for each publication, where each dataset contains one data point. Here's the code I'm using for this approach:
var chartData_webbanner_300x600 = {
labels: ["Publication 1", "Publication 2"],
datasets: [
{
label: "Publication 1",
backgroundColor: "#971317",
data: [30000]
},
{
label: "Publication 2",
backgroundColor: "#0b72ba",
data: [40000]
},
]
};
window.onload = function() {
var ctx_webbanner_300x600 = document.getElementById('chart_webbanner_300x600').getContext('2d');
window.myBar = new Chart(ctx_webbanner_300x600, {
type: 'bar',
data: chartData_webbanner_300x600,
options: {
title: {
display: true,
text: 'Web Banner Impressions'
},
responsive: true,
}
});
}; //window.onload = function()
The resulting chart only shows one bar. Here's a screenshot:
I also tried this as a single dataset, but had no luck there. This is the approach I tried with that:
var chartData_webbanner_300x600 = {
labels: ["Total Impressions"],
datasets: [
{
label: ["Publication 1", "Publication 2"],
backgroundColor: ["#971317","#0b72ba"],
data: [30000,40000]
}
]
};
window.onload = function() {
var ctx_webbanner_300x600 = document.getElementById('chart_webbanner_300x600').getContext('2d');
window.myBar = new Chart(ctx_webbanner_300x600, {
type: 'bar',
data: chartData_webbanner_300x600,
options: {
title: {
display: true,
text: 'Web Banner Impressions'
},
responsive: true,
}
});
}; //window.onload = function()
Here's how that is displaying (with no bars):
Please let me know if you have any ideas on what I'm doing wrong. Thank you for taking the time to help!
I was able to get it working with this code:
var graphData = {
labels: ['Publication 1', 'Publication 2'],
datasets: [{
label: 'Impressions',
data: [30000, 40000],
backgroundColor: [
"#971317",
"#0b72ba"
],
}, ]
};
var ctx_webbanner_300x600 = document.getElementById('chart_webbanner_300x600').getContext('2d');
var chr = new Chart(ctx_webbanner_300x600, {
data: graphData,
type: 'bar',
options: {
scales: {
yAxes: [{
display: true,
ticks: {
beginAtZero: true // minimum value will be 0.
}
}]
}
}
});
This is based on what I found here Setting specific color per label in chart.js and here How to set max and min value for Y axis - which overcame a problem where the scale was starting at the lowest value in my data set.
I have a doughnut graph created using Chart.js with two datasets. The graph displays the number of employees in offices around the world, with the second dataset breaking this down into permanent and contract employees.
There's a jsfiddle of this running here: https://jsfiddle.net/tetsujin1979/tt3ch8z7/
The "labels" attribute of the options for the graph contains the names of the offices, but since there is only one array of labels, they are repeated for the second dataset, and appear on the mouseover text for it.
var config = {
type: 'doughnut',
data: {
datasets: [
{
data: [124,231,152,613,523],
backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue],
label: 'Offices'
},
{
data: [60,64,100,131,71,81,337,276,405,118],
backgroundColor: [chartColors.purple, chartColors.grey],
label: 'Permanent/Contract'
}
],
labels: ['London', 'New York', 'Paris', 'Moscow', 'Mumbai']
}
};
var ctx = document.getElementById('employees-graph').getContext('2d');
var employeesGraph = new Chart(ctx, config);
Is it possible to specify a second array of labels for the permanent/contract dataset so the hover text displays the values from this second
Add a labels array to both of the datasets
var config = {
type: 'doughnut',
data: {
datasets: [
{
data: [124,231,152,613,523],
backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue],
label: 'Offices',
labels: ['London', 'New York', 'Paris', 'Moscow', 'Mumbai']
},
{
data: [60,64,100,131,71,81,337,276,405,118],
backgroundColor: [chartColors.purple, chartColors.grey],
label: 'Permanent/Contract',
labels: ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
}
]
}
};
And add the following to the options:
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ": " + dataset.data[index];
}
}
}
}
I am using the canvasjs for plotting the column chart. I am using the code from this link https://canvasjs.com/editor/?id=https://canvasjs.com/example/gallery/column/oil_reserves/, the code is below:
<!DOCTYPE HTML>
<html>
<head>
<title>Basic HTML5 Column Chart </title>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Top Oil Reserves"
},
animationEnabled: true,
axisY: {
title: "Reserves(MMbbl)"
},
legend: {
verticalAlign: "bottom",
horizontalAlign: "center"
},
theme: "theme2",
data: [
{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: [
{y: 297571, label: "Venezuela"},
{y: 267017, label: "Saudi" },
{y: 175200, label: "Canada"},
{y: 154580, label: "Iran"},
{y: 116000, label: "Russia"},
{y: 97800, label: "UAE"},
{y: 20682, label: "US"},
{y: 20350, label: "China"}
]
}
]
});
chart.render();
}
</script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;">
</div>
</body>
</html>
Now I want to use a text file generated from python instead of the default values in the dataPoints. The test file data looks like a dictionary data separated by comma. Here is a sample of the text file data:
{'DNS_SERVER1': 2.768651, 'FTP_SERVER1': 2.488129, 'AUTHENTICATION_SERVER1': 2.768651, 'WAP_SERVER1': 2.768651, 'WEB_SERVER1': 2.768651, 'EMAIL_SERVER1': 2.768651}
I want the labels to be first part before semicolon like 'DNS_SERVER1' and the value y to be equal to 2nd part of the semicolon like 2.768651. How Can I do this using the canvasjs script? Any help is appreciated.
Thanks.
You must have to read the file to two separate datasets (LABELS and DATA) and insert them like this:
data = {
labels: ["DNS_SERVER", "FTP_SERVER", "AUTH_SERVER"],
datasets: [{
label: 'Performance',
data: [2.768651, 2.488129, 2.768651]
}]
};
Above is a nominal way.
You can change "labels:" dataset and "data:" dataset for your loaded data.