I have been looking for this solution but can't seem to find it . Does chart.js support this ?
I have attempted to parse in the data with papaparse, but due to my limited knowledge I can't find a solution.
There is a Chart.js plugin chartjs-plugin-datasource that makes it easy to load data from CSV files.
Let's suppose you have a CSV file as shown below, and it is saved as sample-dataset.csv in the same directory as your HTML file:
,January,February,March,April,May,June,July
Temperature,7,7,10,15,20,23,26
Precipitation,8.1,14.9,41.0,31.4,42.6,57.5,36.0
Include Chart.js and chartjs-plugin-datasource in your page:
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datasource#0.1.0"></script>
<canvas id="myChart"></canvas>
Then, specify sample-dataset.csv in your script. By default, each row in a CSV file will be mapped to one dataset, and the first column and the first row will be treated as dataset labels and index labels respectively. You can also customize how to parse CSV data using options.
var ctx = document.getElementsById("myChart");
var chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
type: 'line',
yAxisID: 'temperature',
backgroundColor: 'transparent',
borderColor: 'rgb(255, 99, 132)',
pointBackgroundColor: 'rgb(255, 99, 132)',
tension: 0,
fill: false
}, {
yAxisID: 'precipitation',
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'transparent'
}]
},
plugins: [ChartDataSource],
options: {
scales: {
yAxes: [{
id: 'temperature',
gridLines: {
drawOnChartArea: false
}
}, {
id: 'precipitation',
position: 'right',
gridLines: {
drawOnChartArea: false
}
}]
},
plugins: {
datasource: {
url: 'sample-dataset.csv'
}
}
}
});
Here is my solution that works fine for me. I have a CSV file like this:
country,population
China,1415046
India,1354052
United States,326767
Indonesia,266795
Brazil,210868
...
I want to plot a bar chart with my dataset, the y-axis is population and the x-axis is country.
This is the body of my HTML file.
<body>
<canvas id="myChart" width="100" height="100"></canvas>
<script>
// Load the dataset
d3.csv("data.csv").then(makeChart);
// Plot the data with Chart.js
function makeChart(countries) {
var countryLabels = countries.map(function (d) {
return d.country;
});
var populationData = countries.map(function (d) {
return d.population;
});
var chart = new Chart("myChart", {
type: "bar",
data: {
labels: countryLabels,
datasets: [
{
data: populationData
}
]
}
});
}
</script>
</body>
Result:
You can try it with Codesandbox.
I've had need to do something like this from time to time as well. Here's a link on how to create a chart with Chart.js from a CSV file that explains exactly how to create a chart with Chart.js directly from a CSV file.
The use case explains how to convert a CSV file to JSON using the Flex.io web service (Full disclosure: I'm the senior front end developer at Flex.io).
Here's a JsFiddle if you'd like to see the use case in action:
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
$.ajax({
type: 'post',
url: 'https://www.flex.io/api/v1/pipes/flexio-chart-js-csv-to-json/run?stream=0',
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer nmgzsqppgwqbvkfhjdjd');
},
data: $('form').serialize(),
dataType: "json",
success: function(content) {
// render the JSON result from from the Flex.io pipe
$("#flexio-result-data").text(JSON.stringify(content, null, 2))
var first_item = _.get(content, '[0]', {})
var column_labels = _.map(_.omit(first_item, ['os']), function(val, key) {
if (key != 'os')
return key
})
// use Lodash to reformat the JSON for use with Chart.js
var datasets = _.map(content, function(item) {
// use the 'os' column as our label
var item_label = _.get(item, 'os', 'Not Found')
// create an array of number values from each item's JSON object
var item_values = _.map(_.omit(item, ['os']), function(val) {
return parseFloat(val)
})
return {
label: item_label,
data: item_values,
backgroundColor: getRandomColor()
}
})
var chart_data = {
labels: column_labels,
datasets: datasets
}
// render the JSON result after mapping the data with Lodash
$("#chart-data").text(JSON.stringify(chart_data, null, 2))
// render the chart using Chart.js
var ctx = document.getElementById("canvas").getContext("2d");
window.my_chart = new Chart(ctx, {
type: 'bar',
data: chart_data,
options: {
responsive: true,
legend: {
position: 'top'
},
title: {
display: true,
text: 'Use Flex.io to Create a Chart With Chart.js Directly From a CSV File'
}
}
});
}
});
Feel free to step through the use case and let me know if you have any issues.
The simple example of importing CSV data into ChartJS
index.html:
<!-- ChartJS plugin datasrouce example
chartjs-plugin-datasource: https://nagix.github.io/chartjs-plugin-datasource/
Samples: https://nagix.github.io/chartjs-plugin-datasource/samples/
Specific example: https://nagix.github.io/chartjs-plugin-datasource/samples/csv-index.html
Data source: https://gist.githubusercontent.com/mikbuch/32862308f4f5cac8141ad3ae49e0920c/raw/b2b256d69a52dd202668fe0343ded98371a35b15/sample-index.csv -->
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datasource#0.1.0"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
<script src="script.js"></script>
</body>
You can also download this index.html file as a gist.
script.js
// ChartJS plugin datasrouce example
// chartjs-plugin-datasource: https://nagix.github.io/chartjs-plugin-datasource/
// Samples: https://nagix.github.io/chartjs-plugin-datasource/samples/
// Specific example: https://nagix.github.io/chartjs-plugin-datasource/samples/csv-index.html
// Data source: https://gist.githubusercontent.com/mikbuch/32862308f4f5cac8141ad3ae49e0920c/raw/b2b256d69a52dd202668fe0343ded98371a35b15/sample-index.csv
var chartColors = {
red: 'rgb(255, 99, 132)',
blue: 'rgb(54, 162, 235)'
};
var color = Chart.helpers.color;
var config = {
type: 'bar',
data: {
datasets: [{
type: 'line',
yAxisID: 'temperature',
backgroundColor: 'transparent',
borderColor: chartColors.red,
pointBackgroundColor: chartColors.red,
tension: 0,
fill: false
}, {
yAxisID: 'precipitation',
backgroundColor: color(chartColors.blue).alpha(0.5).rgbString(),
borderColor: 'transparent'
}]
},
plugins: [ChartDataSource],
options: {
title: {
display: true,
text: 'CSV data source (index) sample'
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
id: 'temperature',
gridLines: {
drawOnChartArea: false
},
scaleLabel: {
display: true,
labelString: 'Temperature (°C)'
}
}, {
id: 'precipitation',
position: 'right',
gridLines: {
drawOnChartArea: false
},
scaleLabel: {
display: true,
labelString: 'Precipitation (mm)'
}
}]
},
plugins: {
datasource: {
type: 'csv',
url: 'https://gist.githubusercontent.com/mikbuch/32862308f4f5cac8141ad3ae49e0920c/raw/b2b256d69a52dd202668fe0343ded98371a35b15/sample-index.csv',
delimiter: ',',
rowMapping: 'index',
datasetLabels: true,
indexLabels: true
}
}
}
};
window.onload = function() {
var ctx = document.getElementById('myChart').getContext('2d');
window.myChart = new Chart(ctx, config);
};
Here is a a gist with this script.js file.
Make sure that both files are in the same directory.
Open index.html with your browser.
Additional materials
CodeSandbox example to preview the example online.
Reason for posting this answer:
I posted this because people are having problems with reading CSV files from the filesystem (directly from the computer) with JavaScript. The examples in chartjs-plugin-datasource documentation don't explain this, and it is assumed that the user has some basic knowledge on the differences in handling URLs from the web, and files from the file system.
My example just shows the basic functionality of the ChartJS datasource plugin, no third-party modules for reading the CSV file are required.
Edit:
According to ggorlen's suggestion from the comment, I also included the code snippets in the answer itself.
Can't post comments on this elitist site, because four years hasn't gotten me enough "points." ....
#huy - interesting how your Codesandbox has completely different code than what you've posted which I found was directly ripped off from another site... it doesn't even relate to the chart you were talking about building. Within Codesandbox, all I see is an image file of the chart, nothing is actually working (and how could it, when the code isn't even related to your dataset!?).
This is an extract of my plugin (full version):
CKEDITOR.plugins.add('dndck4', {
lang: 'en',
requires: 'widget',
init: function (editor) {
editor.widgets.add('dndck4', {
dialog: 'atomProperties',
pathName: 'atom',
editables: {
caption: {
selector: '.dnd-caption-wrapper',
pathName: 'caption',
allowedContent: 'a[href]; strong; em'
}
},
...
downcast: function(el) {
var caption = '';
if (this.data.usesCaption) {
caption = this.editables.caption.getHtml();
}
var html = Drupal.dndck4.downcastedHtml(this.data, caption);
return CKEDITOR.htmlParser.fragment.fromHtml(html);
},
It worked well, until another JS does something apparently harmless:
editor.on('change', function() {
// Let CKEditor handle updating the linked text element.
editor.updateElement();
});
It breaks my widget based plugin (this.editables is an empty object). Of course I can just check this.editables to avoid error in the next line caption = this.editables.caption.getHtml(); but I'd like to know what happened and why.
I have a few problems with displaying angular material elements and C3.js charts.
With new version of the angular material, in widgets appeared scroll bar.
Does anybody knows how to disable it? I want to show widgets with their fixed size.
Please take a look at the plunker.
The second problem is connected with C3 graphs.
After I open app in browser (at the plunker is also the case) and open the dialog the charts is displaying. Then I close the dialog and open again, the charts are broken.
What could be the cause of this problem? I use a lot of libraries in my project (ngAnimate, ngAria, ngCookies, ngResource, ngTouch, ui.router, ngMaterial,ngMdIcons,ui.grid,ui.grid.selection,ui.grid.cellNav,ui.grid.pagination,ui.grid.resizeColumns, leaflet-directive, bootstrap, jQuery, c3, d3). Do I need to take attention to the order that they are included?
Here is the controller for C3 chart (data come from external source - DB):
angular.module('app')
.controller('ChartCtrl', ['$scope', '$stateParams',
function ($scope, $stateParams) {
$scope.param = $stateParams.param_1;
d3.json('/chart1/'+$stateParams.param_1, function(err, data){
if(err){ throw err; }
$scope.data = data;
//console.log(data);
$scope.$apply();
$scope.chart = c3.generate({
bindto: '#chart1',
/*size: {
height: 350
},*/
data: {
json: $scope.data,
//columns: $scope.data,
keys: {
value: ['data1', 'data2'],
},
type: 'bar'
},
bar: {
width: {
ratio: 0.4 // this makes bar width 50% of length between ticks
}
},
grid: {
x: {
show: true
},
y: {
show: true
}
}
});
});
}]);
And the html template which is included in panel-widget directive:
<div id="chart1" ng-controller="ChartCtrl">
<div id="chart1"></div>
</div>
You can do something like this to fix the size of the graph displayed in tab 1.
In side Tab1, make an SVG with fixed size and height like below:
<div id="tab1" ng-controller="GraphCtrl">
<svg id="chart1" width="100" height="100"></svg>
</div>
Bind the SVG to the graph like this:
$scope.chart_grid_lines = c3.generate({
bindto: d3.select('#chart1'), //binding to svg
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
type: 'spline'
},
legend: {
show: false
}
});
Working code here
Hope this helps!
I am developing a drilled down chart using HichartJS, the chart is getting generated but drill down is not functioning properly.
I need the back button as well so that user can go back to the previous data.
Here is my code,
HTML:
<div ng-controller="myctrl">
<highchart id="chart1" config="highchartsNG"></highchart>
</div>
JS:
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.highchartsNG = {
options: {
chart: {
type: 'column'
}
},
title: {
text: 'Basic drilldown'
},
xAxis: {
type: 'category'
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
}
}
},
series: [{"data":[{"name":"Hiring","y":390309.25,"drilldown":"PRIME MOVER"},{"name":"Private","y":406746.97,"drilldown":"PRIME MOVER"}],"name":"series1","color":"","type":"area"}],
drilldown: {
series: [{"id":"Hiring","data":[["MOTOR CAR",97610],["VAN",129750],["THREE WHEELER",62949.25],["PRIME MOVER",100000]]},{"id":"Private","data":[["MOTOR CAR",488356.97],["VAN",129750],["THREE WHEELER",78949.25],["PRIME MOVER",100000]]}]
}
}
});
Here is the Plunker
Update2 I have made changes for your data , The problem was in formatting of json and the second problem was you were not calling proper id in drillDown. Check the fiddle updated Here with your data
Update1 I have made changes and now its working on fiddle Here . I have added changes to highcharts-ng in script tag in html section of fiddle. Also I changed the data, because your data was not formatted for me.
I just realize that drillDown feature isn't supported by highcharts-ng .see the link Highcharts-ng with drilldown
Following edit was done at source code to make it work.
if(config.drilldown) {
mergedOptions.drilldown = config.drilldown;
};
I am trying to run an ExtJS4 Ext.application inside our existing website template. We have a div #content, into which I want to place the application for development. How do I render the application into this area, rather than replacing the existing html page?
Ext.application({
name: 'HelloExt',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
// renderTo: Ext.Element.get('#content') doesn't work
items: [
{
title: 'Hello Ext',
html : 'Hello! Welcome to Ext JS.'
}
]
});
}
});
You need to use other container than a Ext.container.Viewport. By definfiton Ext.container.Viewport will always take the entire browser window.
From documentation:
The Viewport renders itself to the document body, and automatically sizes itself to the size of the browser viewport and manages window resizing. There may only be one Viewport created in a page.
Just use Ext.panel.Panel instead
Ext.application({
name: 'HelloExt',
launch: function() {
Ext.create('Ext.panel.Panel', {
layout: 'fit',
renderTo: Ext.get('content')
items: [
{
title: 'Hello Ext',
html : 'Hello! Welcome to Ext JS.'
}
]
});
}
});