I tried the code like this with many small restructuration and modification but without success.
Here is the code:
$(function () {
$.get('data.csv', function(data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
$('#chart').highcharts({
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
data: {
csv: data
},
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
Here is data.csv:
Date,Open,High,Low,Close,Volume
2013-12-20,9371.08,9413.09,9352.98,9400.18,161686900
2013-12-19,9279.68,9351.9,9257.24,9335.74,98276500
2013-12-18,9145.35,9190.73,9122.05,9181.75,82342700
2013-12-17,9142.75,9161.8,9085.12,9085.12,72207500
2013-12-16,9004.62,9187.78,8997.75,9163.56,99105600
2013-12-13,9016.78,9046.63,8990.58,9006.46,67761700
2013-12-12,9032.67,9060.54,8984.28,9017,75120200
2013-12-11,9093.26,9153.14,9065.51,9077.11,64845800
2013-12-10,9180.29,9223.73,9091.97,9114.44,74363400
Can you help me to figure out the problem or purpose new approch please ?
What is my goal ?
Is to be able to load a CSV file inside the chart instead of using JSON file.
Why ?
Because modifing CSV file is more easier for me using PHP than JSON, and it's for performance too.
Thank's
When you do data.length, you are getting length of the csv file string. What you need to do is split the data with the newline delimiter.
// sample from data
var data = `Date,Open,High,Low,Close,Volume
2013-12-20,9371.08,9413.09,9352.98,9400.18,161686900
2013-12-19,9279.68,9351.9,9257.24,9335.74,98276500`;
// split by \n (new line)
data = data.split('\n'); // now data is an array of rows
var finalObj = [];
// iterate over the rows
data.map(function(row){
var obj = {};
// row is a string separated by ','
row = row.split(','); // now row is an array
obj['date'] = row[0];
obj['open'] = row[1];
obj['high'] = row[2];
obj['low'] = row[3];
obj['close'] = row[4];
obj['volume'] = row[5];
finalObj.push(obj);
})
console.log(finalObj);
Output:
[
{
date:'Date',
open:'Open',
high:'High',
low:'Low',
close:'Close',
volume:'Volume'
},
{
date:'2013-12-20',
open:'9371.08',
high:'9413.09',
low:'9352.98',
close:'9400.18',
volume:'161686900'
},
{
date:'2013-12-19',
open:'9279.68',
high:'9351.9',
low:'9257.24',
close:'9335.74',
volume:'98276500'
}
]
Im building a chart system that will show me all data entries. I retrieve my data using ajax and I loop trough the data and group the results by colors (red, blue and yellow) and then divide them by months.
I setup base objects (dateCounts_Red, dateCounts_Blue and dateCounts_Yellow) so that by default it starts all months at 0. A counter would then add when it finds a match tot he apropriate color and month.
When I output my dateCounts I get:
{"2015":{"2015-12":1,"2015-10":null,"2015-08":null,"2015-11":null}}
{"2015":{"2015-12":0,"2015-10":null}}
{"2015":{"2015-12":0,"2015-10":null}}
Here is the code I have so far:
var dateCounts_Red = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
var dateCounts_Blue = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
var dateCounts_Yellow = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
data.d.results.forEach(function(element) {
var date = element.created_date.slice(0, 7);
var yr = date.slice(0, 4);
var Color = element.colorvalue;
if(Color == "red") {
dateCounts_Red[yr][date]++;
}
if(Color == "blue"){
dateCounts_Blue[yr][date]++;
}
if(Color == "yellow"){
dateCounts_Yellow[yr][date]++;
}
});
Red_yr_2015_data = [dateCounts_Red['2015']['2015-01'], dateCounts_Red['2015']['2015-02'], dateCounts_Red['2015']['2015-03'], dateCounts_Red['2015']['2015-04'], dateCounts_Red['2015']['2015-05'], dateCounts_Red['2015']['2015-06'], dateCounts_Red['2015']['2015-07'], dateCounts_Red['2015']['2015-08'], dateCounts_Red['2015']['2015-09'], dateCounts_Red['2015']['2015-10'], dateCounts_Red['2015']['2015-11'], dateCounts_Red['2015']['2015-12']];
Blue_yr_2015_data = [dateCounts_Blue['2015']['2015-01'], dateCounts_Blue['2015']['2015-02'], dateCounts_Blue['2015']['2015-03'], dateCounts_Blue['2015']['2015-04'], dateCounts_Blue['2015']['2015-05'], dateCounts_Blue['2015']['2015-06'], dateCounts_Blue['2015']['2015-07'], dateCounts_Blue['2015']['2015-08'], dateCounts_Blue['2015']['2015-09'], dateCounts_Blue['2015']['2015-10'], dateCounts_Blue['2015']['2015-11'], dateCounts_Blue['2015']['2015-12']];
Yellow_yr_2015_data = [dateCounts_Yellow['2015']['2015-01'], dateCounts_Yellow['2015']['2015-02'], dateCounts_Yellow['2015']['2015-03'], dateCounts_Yellow['2015']['2015-04'], dateCounts_Yellow['2015']['2015-05'], dateCounts_Yellow['2015']['2015-06'], dateCounts_Yellow['2015']['2015-07'], dateCounts_Yellow['2015']['2015-08'], dateCounts_Yellow['2015']['2015-09'], dateCounts_Yellow['2015']['2015-10'], dateCounts_Yellow['2015']['2015-11'], dateCounts_Yellow['2015']['2015-12']];
Im currently getting the following error from my Highcharts js:
Uncaught TypeError: Cannot set property 'index' of undefined
THis is preventing the chart system to work correctly the data returned is not being returned with it's expected data.
Here a full example to the issue https://jsfiddle.net/awo5aaqb/21/
Would anyone know what im missing?
Your date count objects have major structural flaw.
When you prettify them they look like:
var dateCounts_Blue = {
"2015": {
"2015-01": 0,
"2015-02": 0,
"2015-03": 0,
"2015-04": 0
},
"2015": {
"2015-05": 0
},
"2015": {
"2015-06": 0
},
"2015": {
"2015-07": 0
},
......
Object keys must be unique so these are clearly being repeated and the compiler will over write duplicates.
Fix the pattern that breaks away from the intended pattern grouping at the beginning
var dateCounts_Red = {
"2015":
{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0
},
};
var dateCounts_Blue = {
"2015":{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0
}
};
var dateCounts_Yellow = {
"2015":{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0}
};
Your data structure is flawed and such comparing values when doing the foreach loop becomes inconsistent because it compares it to multiple values, the above JSON is the fix for your problem.
Not quite codereview.stackexchange.com, but I heavily modified your javascript to make it work a bit better
$.ajax({
url: basePath,
dataType: 'json',
cache: false,
success: function(data) {
var counts = {};
data.d.results.forEach(function(element) {
// If you know it's all the same year, you could totally ignore this
var yr = element.created_date.slice(0, 4);
var month = parseInt(element.created_date.slice(5,7));
var color = element.colorvalue;
if (counts[color] === undefined) {
counts[color] = {};
}
if (counts[color][yr] === undefined) {
counts[color][yr] = {};
}
current_value = counts[color][yr][month];
if (current_value === undefined) {
// Doesnt exist yet, so add it
counts[color][yr][month] = 1;
} else {
// Exists, so increment by 1
counts[color][yr][month] = current_value + 1;
}
});
console.log(JSON.stringify(counts));
console.log(transform_series(counts['red']['2015']));
console.log(transform_series(counts['blue']['2015']));
console.log(transform_series(counts['yellow']['2015']));
var Options = {
chart: {
renderTo: 'myfirstchart',
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 25,
beta: 0,
depth: 70
}
},
title: {
text: "Test Highcharts"
},
subtitle: {
text: 'Test charts'
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
},
yAxis: {
title: {
text: "Number of entries"
}
},
tooltip: {
headerFormat: '<b>{point.key}</b><br>',
pointFormat: '<span style="color:{series.color}">\u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
depth: 40
}
},
series: [{
name: 'Red',
color: 'red',
data: transform_series(counts['red']['2015']),
stack: '2015'
}, {
name: 'Blue',
color: 'blue',
data: transform_series(counts['blue']['2015']),
stack: '2015'
}, {
name: 'Yellow',
color: 'yellow',
data: transform_series(counts['yellow']['2015']),
stack: '2015'
}]
};
return new Highcharts.Chart(Options);
}
});
// this transforms the hash {10: 5, 11:1, 12:1} to get you all 12 months
// and returns an array of values [ 0, 0, 0, 0, 0 ... 5, 1, 1] that
// can be used in high charts
function transform_series(series) {
return Array.apply(null, Array(13)).map(function (_, i) {return (series[i] === undefined) ? 0 : series[i];}).slice(1,13);
}
I have following generated JavaScript-Code to display a chart with HighCharts:
<script type="text/javascript">
var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
var TaskChart; // Chart-Objekt
var TaskDuration = new Array();
// Save starting points to javascript variables for HighCharts
var startingUTC = 1288102643364;
TaskDuration = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206,216,216,206,206];
for(var i = 0; i < TaskDuration.length; i++) {
if(TaskDuration[i] == 0) {
TaskDuration[i] = null;
}
}
</script>
<script type="text/javascript">
$j(document).ready(function() {
TaskChart = new Highcharts.Chart({
credits: {
enabled: false
},
chart: {
renderTo: "chart01",
defaultSeriesType: 'area',
zoomType: 'x',
spacingBottom: 250
},
title: {
text: "Task Duration"
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
week: '%e. %b %Y'
},
offset: 10,
startOnTick: true,
maxZoom: 7 * 24 * 3600000 // seven days
},
yAxis: {
title: {
text: "Duration"
}
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>';
}
},
plotOptions: {
area: {
stacking: 'normal',
lineColor: '#666666',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#666666'
}
}
},
series: [
{
name: 'Duration',
pointStart: startingUTC,
pointInterval: 24*60*60*1000,
data: TaskDuration
}]
});
});
</script>
The problem is now that I want to remove all the "0" values from the beginning of the TaskDuration series array.
I try to set the values in the array to 'null':
for(var i = 0; i < TaskDuration.length; i++) {
if(TaskDuration[i] == 0) {
TaskDuration[i] = null;
}
}
But Highcharts still display the values in the chart.
How to prevent this behavior?
I also try to remove all values from the array until a value which is not "0". But with this approach the "startingUTC" is wrong. Maybe I have also to recalculate this value...
Regards,
Sandro
You need to remove elements not to set null, use this to remove zero element from array:
var myArray=[];
for(var i = 0; i < TaskDuration.length; i++) {
if(TaskDuration[i] != 0) {
myArray.push(TaskDuration[i]);
}
}
working JSfiddle
The problem is that you're using pointStart and pointInterval.
PointInterval will ignore your null points and will add points to the yAxis.
So, remove it.
series: [{
name: 'Duration',
data: TaskDuration
}]