making large csv chartable by querying iso code in highcharts - javascript

I'm trying to load a csv and format it so it will display as a chart in highcharts, this is proving difficult because of the structure of the csv data.
Here is the csv: https://pastebin.com/Ynz7GJJh
Sample:
iso,type,year,affected
JAM,Earthquake,1907,90000
JAM,Storm,1912,94820
TON,Volcano,1946,2500
DZA,Earthquake,1954,129250
HTI,Storm,1954,250000
Here is my highcharts.ajax so far
var hsOptions = {
chart: {
type: 'column'
},
title: {
text: 'KEY NATURAL HAZARD STATISTICS'
},
subtitle: {
text: 'Number of People Affected'
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Units'
}
},
series: []
};
Highcharts.ajax({
url: '/pathto.csv',
dataType: 'text',
success: function(csv) {
var rows = csv.split(/\r\n|\n/);
var cell;
var series = [];
var seriesBuilder = {name: countryValue, data: []};
for (var i = 0; i < rows.length; i++) {
cell = rows[i].split(',');
if (cell[0] === countryValue){
seriesBuilder.data.push(cell);
}
}
console.log(seriesBuilder);
series.push(seriesBuilder);
hsOptions.series.push(series);
Highcharts.chart('hazard-stats', hsOptions);
},
error: function (e, t) {
console.error(e, t);
}
});
which does make this
But I need this to build a series per disaster type, then the years have to combine on their own axis... it should be able to render just like this:

Related

highcharts doesn't read data, works with fake data

I'm trying to make visualization of the voltage, Array has 1k elements but I'm testing it on first 10 for now, the thing is that It doesn't display anything, what's more interesting when I use fake date which is commented out now, It shows chart properly. I thought that perhaps there is some problem with array so tried to use Array.from but it also brought no effect, here is my code:
.then(function(res) {
var averageVoltage = []
var inputVoltage = []
var date = []
for (var i = 0; i < 10; i++) {
if (res[i].average_volatage !== undefined) {
averageVoltage.push(res[i].average_volatage)
date.push(res[i].timestamp)
}
}
console.log(averageVoltage)
console.log(date)
Highcharts.chart('battery_chart', {
chart: {
type: 'line'
},
title: {
text: id
},
yAxis: {
title: {
text: 'Measurement'
},
},
xAxis: {
categories: date
},
series: [{
name: 'Average Voltage',
data: averageVoltage
// data: [12283, 12283, 12281, 12280, 12282, 12283, 12281, 12282, 12281, 12280]
},
]
});
and that's how array is shown in console.log:
Your array should show up as [12283, 12281, 12280, etc.] in console as well, instead it shows up as [Number, Number, ...]. Try changing this line:
averageVoltage.push(res[i].average_volatage)
to:
averageVoltage.push(parseInt(res[i].average_volatage))
Additionally, instead of using dates as categories, it could be easier to use the highchart datetime axis. This would let you manipulate how you want the date displayed, have several series with different timestamps in one graph, and many other things. To get this to work, you could do this:
.then(function(res) {
var averageVoltage = []
var inputVoltage = []
for (var i = 0; i < 10; i++) {
if (res[i].average_volatage !== undefined) {
averageVoltage.push({x: new Date(res[i].timestamp).getTime(), y: parseInt(res[i].average_volatage)})
}
}
console.log(averageVoltage)
Highcharts.chart('battery_chart', {
chart: {
type: 'line'
},
title: {
text: id
},
yAxis: {
title: {
text: 'Measurement'
},
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'Average Voltage',
data: averageVoltage
},
]
});

database to Highchart ASP.NET MVC

I want to input JSON data that I have from Database to highchart. but the chart didn't show up but JSON data does.
In ajax I already separate the category and data, but it's not working. especially because i don't know how to debug this javascript code. when I open inspect the sources in browser but it show nothing. I hope someone can help me
my ViewModel
public class DataByYear
{
public int Total { get; set; }
public string year { get; set; }
}
this is my Provider
public List<DataByYear> GetDataByYear()
{
tesdbEntities entities = new tesdbEntities();
var data = entities.Database.SqlQuery<DataByYear>("exec DataByYear");
return data.ToList();
}
I use SP to get the data from database
My Controller
public ActionResult Index()
{
return View();
var penjualan = new PenjualanProvider();
var index = new List<DataByYear>();
index = penjualan.GetDataByYear();
return this.Json(index, JsonRequestBehavior.AllowGet);
}
and this is my JS
$(document).ready(function () {
$.ajax({
url: '#Url.Action("Index")',
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: 'json',
async: true,
success: function (dataChart) {
var Xaxis = [];
var dataseries = [];
for (i = 0; i < DataByYear.length; i++) {
var items = DataByYear[i];
var XcategoreisItem = items.year;
var seriesData = items.Total;
Xaxis.push(XcategoreisItem);
dataseries.push(seriesData);
getchart(Xaxis, dataseries);
}
}
})
});
function getchart(Xaxis, dataseries) {
$('#data').highcharts({
chart: {
type: 'line',
zoomType: 'xy',
panning: true,
panKey: 'shift'
},
title: {
text: 'Profit From 2018'
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
format: '{y}%',
}
}
},
xAxis: {
categories: Xaxis
},
yAxis: {
title: {
text: 'Y axis text'
},
series: dataseries
}
});
};

Highcharts sort stacked bar

I didn't see any solutions matching the exact scenario I was hitting in Highcharts so I'm posting my find here.
I have a stacked bar chart in Highcharts and needed the bars to be sorted by value greatest to smallest and maintain their category relationship. Normally the preferred solution would be to sort the data before sending it in to Highcharts but that wasn't an option in my scenario.
Credit to the original poster where I found the solution here
You should perform the Chart.redraw() only once after all setData operations are finished: http://jsfiddle.net/BlackLabel/2mLg7235/
$.each(series, function(seriesIndex, ser) {
(...)
ser.setData(data, false);
});
chartSource.redraw();
In your code the redraw happens after every setData operation.
In my example the sorting function executes two times faster or so (thanks to this modification).
This solution is slow to execute as it post-processes the chart data. If I find a way to speed it up, I will update the code posted here.
http://jsfiddle.net/eecvsj7s/
$(function () {
var chart;
var sortData = function(chartSource) {
var series = chartSource.series;
var axis = chartSource.xAxis[0];
var categories = [];
if($.isArray(series)) {
var ser = $.grep(series, function(ser, seriesIndex) {
return ser.visible;
})[0];
$.each(ser.data, function(dataIndex, datum) {
console.log(datum.category + ": " + datum.stackTotal);
var obj = {
name: datum.category,
index: dataIndex,
stackTotal: datum.stackTotal
}
categories.push(obj);
});
}
categories.sort(function(a, b) {
var aName = a.name.toLowerCase();
var bName = b.name.toLowerCase();
var aTotal = a.stackTotal;
var bTotal = b.stackTotal;
if(aTotal === bTotal) {
return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
} else {
return ((aTotal > bTotal) ? -1 : ((aTotal < bTotal) ? 1 : 0));
}
});
var mappedIndex = $.map(categories, function(category, index) {
return category.index;
});
categories = $.map(categories, function(category, index) {
return category.name;
});
console.log(categories);
console.log(mappedIndex);
axis.setCategories(categories);
$.each(series, function(seriesIndex, ser) {
var data = $.map(mappedIndex, function(mappedIndex, origIndex) {
return ser.data[mappedIndex].y;
});
ser.setData(data,false);
});
chartSource.redraw();
};
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
plotOptions: {
series: {
stacking: 'normal',
events: {
hide: function() { sortData(chart); },
show: function() { sortData(chart); }
}
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5]
}]
}, function(chart) { sortData(chart); });
});
});

Javascript HighCharts reading from a different format

I am using Highcharts and i currently have 2 arrays which I would like to stop reading from and start reading the data from my object.
Here is the code i currently have:
items = ['Item 1', 'Item 2'];
Quantity = [10 , 5];
jQuery('#container').highcharts({
chart: {
type: 'column'
},
xAxis: {
categories: mydata
},
title: {
text: 'Items Title'
},
series: [{
name: 'Items',
data: Quantity
}],
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}<br/>',
shared: true
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
console.log('Clicked');
},
},
},
},
},
});
The above displays 2 items of height 10 and 5.
Now what I need to do is to be able to read this data instead:
var mydata = {
"items":[{
"id":"123",
"name":"item name here",
"subitems":[{
"id":"567",
"name":"subitem 1"
},
{
"id":"657",
"name":"subitem 2"
}],
"somthing here":null,
},
{
"id":"456",
"name":"item name here too",
"subitems":[{
"id":"567",
"name":"subitem here"
},
{
"id":"657",
"name":"subitem here roo"
}],
"somthing here":null,
}]
};
The quantity values need to be the subitems count so in the case of the data above it would be 2,2
How can I do this?
This should get you started:
https://jsfiddle.net/b3wii/0Lx77f1a
If you click on a column it reads the mydata and displays the subitems. To get the subItem count just use mydata.items[i]['subitems'].length. To update the existing Item values change currentItemY or currentItemX.
click: function (e) {
if(this.series.name != 'SubItems'){
let currentItemName = items[this.index];
let currentItemY = this.y;
let currentItemX = this.x;
let newCategories = [];
let newSeries = [];
for(let i in mydata.items){
if(mydata.items[i]['name'] == currentItemName){
for(let j in mydata.items[i]['subitems']){
newCategories.push(mydata.items[i]['subitems'][j]['name']);
newSeries.push(mydata.items[i]['subitems'][j]['quantity']);
}
}
}
chart.update({
xAxis: {
categories: newCategories
},
series: [{
name: 'SubItems',
data: newSeries
}]
});
}
},

Highcharts error "cannot read property of undefined"

I'm creating a chart using Highcharts (and getting the data from a JSON file). However, I'm getting TypeError: Cannot read property 'map' of undefined.
I have the following code:
myData.get(function (data) {
$scope.loadData = data;
});
$('#container').highcharts({
xAxis: {
type: 'datetime'
},
series: [{
name: 'Temperature',
data: $scope.loadData.map(function(d) {
return [d.timestamp, d.actual];
})
}, {
name: 'Range',
data: $scope.loadData.map(function(d) {
return [d.timestamp, d.min, d.max];
}),
type: 'arearange'
}]
});
I've also created a Plunker.
Any tips on what I'm doing wrong here?
So I changed your Plunkr to a working example: http://plnkr.co/edit/Q4z6NdVtp3TRMKgmH5tc?p=preview
First of all, in your data.json you have timestamps added as strings. Highchart does not accept that.
I changed the factory to get JSON data via $http
.factory('myData', function($http) {
return {
getData : function () {
var data = [];
data = $http.get('data.json');
return data;
}
}
})
In the callback of getData I build the chart:
myData.getData().then(function(response) {
$scope.loadData = response.data;
$('#container').highcharts({
xAxis: {
type: 'datetime'
},
series: [{
name: 'Temperature',
data: [$scope.loadData.timestamp, $scope.loadData.actual]
},
{
name: 'Range',
data: [$scope.loadData.timestamp, $scope.loadData.min, $scope.loadData.max],
type: 'arearange'
}]
});
});
this is asynchronous call :
myData.get(function (data) {
console.log("myData.Get");
$scope.loadData = data;
});
So $('#container').highcharts({... will run before the data is set $scope.loadData = data;
you have to move the code inside the callback of myData
myData.get(function (data) {
$scope.loadData = data;
$('#container').highcharts({
xAxis: {
type: 'datetime'
},
series: [{
name: 'Temperature',
data: $scope.loadData.map(function(d) {
return [d.timestamp, d.actual];
})
}, {
name: 'Range',
data: $scope.loadData.map(function(d) {
return [d.timestamp, d.min, d.max];
}),
type: 'arearange'
}]
});
});

Categories