Basically, am working with json objects however my skills are not that much because I am still a newbie in javascript and json or object literals. Am trying to achieve where I would like to push or insert a custom json object at the last element of the other xml/json file. Is there any on way how to do this? I've been trying to do it for quite some time now but could not make it work. Any idea how to make it work? because honestly, I don't have any left :-)
I use getJSON to request a JSON from my website. It works great, but I need to somehow insert another custom object literals at the end of the json is it possible?
By the way here is my code.
$(function() {
$.getJSON('https://some_link_from_a_server_that_produces_xml_file_or_json',
function(data) {
//var dataLength = data.length;
fillData();
function fillData() {
var jsonData = [{
"LastModification": "04:27:48",
"Symbol": "EURUSD",
"Bid": '1.20568',
"Ask": "1.21238",
"High": '1.21789',
"Low": '1.19253',
"Direction": "-1",
"InserTime": "\/Date(1358760600163)\/",
"volume": "0"
}];
for (var i = 0; i < jsonData.length; i++) {
data.push([
parseFloat(jsonData[i].Bid),
parseFloat(jsonData[i].High),
parseFloat(jsonData[i].Low),
parseFloat(jsonData[i].Ask),
parseInt(jsonData[i].InserTime.substr(6)),
parseInt(jsonData[i].volume)
]);
}
CreateChart();
} // end of function fillData()
function CreateChart() {
var chart = new Highcharts.stockChart('container2',
{
title: {
text: 'EUR/USD',
floating: true,
align: 'left',
x: 0,
y: 55
},
subtitle: {
text: 'highest: 1.23223 / lowest: 1.21774',
floating: true,
align: 'left',
x: 0,
y: 70
},
xAxis: {
gridLineWidth: 1
},
yAxis: {
gridLineWidth: 1
},
rangeSelector: {
buttons: [
{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1D'
}, {
type: 'all',
count: 1,
text: 'All'
}
],
selected: 1,
inputEnabled: true
},
series: [
{
name: 'EURUSD',
type: 'candlestick',
data: data,
tooltip: {
valueDecimals: 5
}
}
]
}); // end of highcharts.stockchart
}
});
});
I think you are making a array of JSON which looks like [{...}, {...}]
However, in your code you are making an array of array which looks like [[...], [...]].
Try :
let data = [];
const func = function(data) {
fillData();
function fillData() {
var jsonData = [{
"LastModification": "04:27:48",
"Symbol": "EURUSD",
"Bid": '1.20568',
"Ask": "1.21238",
"High": '1.21789',
"Low": '1.19253',
"Direction": "-1",
"InserTime": "\/Date(1358760600163)\/",
"volume": "0"
}];
for (var i = 0; i < jsonData.length; i++) {
data.push({
Bid :parseFloat(jsonData[i].Bid),
High : parseFloat(jsonData[i].High),
Low : parseFloat(jsonData[i].Low),
Ask : parseFloat(jsonData[i].Ask),
InserTime : parseInt(jsonData[i].InserTime.substr(6)),
Volume :parseInt(jsonData[i].volume)
});
}
console.log(data);
} // end of function fillData()
}
func(data);
Related
I want to show the x values of a array as time stamp. The x value was generated by x = Date.now()
var test = {
"datasets": [{
"data": [{
"x": 1609753734252,
"y": 44.82420388241937
}, {
"x": 1609753735263,
"y": 46.02068615892796
}, {
"x": 1609753741254,
"y": 53.21622091958411
}]
}, {
"data": [{
"x": 1609753734252,
"y": 129.77634259930292
}, {
"x": 1609753735263,
"y": 129.86789675071483
}, {
"x": 1609753741254,
"y": 129.9137373479274
}]
},
"labels": [1609753734252, 1609753735263, 1609753741254]
}
The options
var config = {
type: 'line',
options: {
responsive: true,
responsiveAnimatinDuration: 500,
animation: {
duration: 0
},
elements: {
point: {
radius: 0
},
line: {
borderWidth: 2,
fill : false
}
},
legend : {
display : false
},
scales: {
xAxes: [{
type : 'time',
time : {
format : "HH:MM",
unit : "hour"
}
}]
}
}
};
The javascript code:
config.data = test;
window.myLine = new Chart(ctx.getContext('2d'), config);
I want to show the time in format hh:mm? What is wrong?
The data will be updated all 500 ms. Can I hide the transitions?
You don't have that option format as you're using it
You can use the unit and the parser, this last one accepts the same format options as moment accepts.
You can try using as a string like the following:
MM-DD-YYYY
Or sending a function, like this
parser: (tickValue) => {
// just as an example
if (tickValue > 0)
return moment(tickValue).format('MM-DD-YYYY');
}
Can you please try the following way mentioned here in the documentation to formate date
https://www.chartjs.org/docs/latest/axes/cartesian/time.html#display-formats.
I tried it with the following:
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
second: 'hh:mm:ss'
}
// unit : 'minute'
}
}]
Now I get all the years from 1971 to today. But I want to have the x-scaling set auto. Without displayFormat all times are displayed. But unfortunately as long int.
I also tried it with "unit". After that I get an exception: isAMomemtObject
I use vue.js for my project. Also I use websocket for my datas. Every one second come datas. I need to use realtime chart on my project. But I dont find any chart to solve my problem. For example I use apexchart but it have not refresh datas in my chart when new datas come.
my websocket data like:
{
"topic": "2",
"message": "data"
}
my database data like this:
{
"id": "1",
"deviceName": "refrigerator",
"deviceType": "lineChart",
"topic": "1",
"message": "",
},
{
"id": "8",
"deviceName": "refrigerator",
"deviceType": "lineChart",
"topic": "1",
"message": "",
},
I get my datas from database in this code. And I check my topic, is it same or not. if it is same, I put websocket message to json data to see at screen:
let bufferMessage = [];
bufferMessage = jsonFromDatabase;
socket.on("message", (topic, message) => {
bufferMessage.forEach(element => {
if (element.topic == topic) {
element.message = message.toString();
}
});
});
My code is :
<div id="chart">
<apexchart type="line" height="350" :options="chartOptions" :series="$store.state.bufferMessage[index].message"></apexchart>
</div>
<script>
import Vue from "vue";
import ApexCharts from "apexcharts";
import VueApexCharts from "vue-apexcharts";
Vue.component("apexchart", VueApexCharts);
export default {
components: {
apexchart: VueApexCharts,
},
data() {
return {
series: [
{
name: "Desktops",
data: [],
},
],
chartOptions: {
chart: {
height: 350,
type: "line",
zoom: {
enabled: false,
},
},
dataLabels: {
enabled: false,
},
stroke: {
curve: "straight",
},
title: {
text: "Product Trends by Month",
align: "left",
},
grid: {
row: {
colors: ["#f3f3f3", "transparent"],
opacity: 0.5,
},
},
xaxis: {
categories: [],
},
},
}
</script>
but the way there is no any error in this code. I just want to convert this chart to realtime chart for my websocket datas.
Unless OP shows the part in the code of updating the data, I only can offer a reference of the official apexcharts documentation, about updating the data :
import VueApexCharts from 'vue-apexcharts'
export default {
name: 'Vue Chart',
data: function () {
return {
chartOptions: {
chart: {
id: 'vuechart-example',
},
xaxis: {
categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998],
},
},
series: [{
name: 'Vue Chart',
data: [30, 40, 45, 50, 49, 60, 70, 81]
}]
}
},
methods: {
updateChart() {
const max = 90;
const min = 20;
const newData = this.series[0].data.map(() => {
return Math.floor(Math.random() * (max - min + 1)) + min
})
// In the same way, update the series option
this.series = [{
data: newData
}]
}
}
}
As you can see in the example above, by just changing the props, we trigger the update event of ApexCharts. (from the docs)
Sandbox Example https://codesandbox.io/s/50z5wrmp6k
Here's what I'm trying to do:
Use papa parse to parse a CSV file.
Create two JS Objects(ohlc and volume) with that parsed data.
Then that data is used to create a highstocks chart.
Parsing with papa parse example:
function doStuff(data) {
//do stuff here
console.log(data);
}
function parseData(url, callBack) {
Papa.parse(url, {
download: true,
dynamicTyping: true,
complete: function(results) {
callBack(results.data);
}
});
}
parseData("https://www.quandl.com/api/v3/datasets/WIKI/AAPL.csv", doStuff);
A working Highchart example: jsfiddle
Me trying to combine the top two examples: jsfiddle
$(function () {
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 = 1;
function parseData(url, callBack) {
Papa.parse(url, {
download: true,
dynamicTyping: true,
complete: function(results) {
callBack(results.data);
}
});
}
function setObjects(data) {
console.log(data[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
]);
}
}
parseData("https://www.quandl.com/api/v3/datasets/WIKI/AAPL.csv", setObjects);
// create the chart
$('#container').highcharts('StockChart', {
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
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
Can anyone help me out with what I am doing wrong? I know two things that haven't been done. The data needs to be reverse so that it is in ascending order by date. And the date needs to be converted to milliseconds. However it would help me to get the current data at least inserting to the objects first and then go from there.
This bit
var i = 1;
dataLength = data.length;
Should be in the first lines of the setObjects function, where data is present and the value dataLength is actually used.
I try to use dynamically the HighCharts plugin : grouped_categories
The good Json format for this plugin is :
xAxis: {
categories: [{
name: "Fruit",
categories: ["Apple", "Banana", "Orange"]
}, {
name: "Vegetable",
categories: ["Carrot", "Potato", "Tomato"]
}, {
name: "Fish",
categories: ["Cod", "Salmon", "Tuna"]
}]
}
I use this technic for make my xAxis dynamically :
In my chart I write : xAxis: {categories: []} and after I call the
part of the Json options.xAxis.categories = json[0]['data'];
So I tried many technics, but never the good ...
Have you got an idea for resolve this problem ?
Thank you very much.
Geo-x
EDIT 1
This is my code after the generation of my JSON with AJAX
// -- Graphical options --
var options = {
chart: {
renderTo: 'graphique',
type : type_graph},
xAxis: {categories: []},
title: {text: ''},
tooltip: {
animation : true,
borderRadius : 15
},
plotOptions: {
line: {
allowPointSelect: true,
cursor: 'pointer',
groupPadding: 0.1,
states: {
hover: {
brightness: -0.3}}
},
column: {
allowPointSelect: true,
cursor: 'pointer'
}
}
,series: []
}
$.post(
"statistiques_data.php",
parametres_connexion,
function(json) {
// X AXIS --------------------------------------
options.xAxis.categories = json[0]['data'];
// DATA --------------------------------------
options.series[0] = json[1];
// LEGEND --------------------------------------
options.legend = {enabled : false,backgroundColor : '#FCFFC5'};
// LABELS --------------------------------------
switch (type_graph) {
///////////////////////////////
case 'line' :
///////////////////////////////
var dataSum = 0;
for (var i=0;i < json[1]['data'].length;i++) {
dataSum += json[1]['data'][i]
};
options.plotOptions.bar.dataLabels = {enabled:true,formatter:function() {var pcnt = (this.y / dataSum) * 100; return Highcharts.numberFormat(pcnt,2) + ' %';}};
options.xAxis.labels = {step: 1,style: {fontSize: '9px',fontFamily: 'Arial Bold, Arial, Verdana'}};
break;
///////////////////////////////
case 'column' :
///////////////////////////////
var dataSum = 0;
for (var i=0;i < json[1]['data'].length;i++) {
dataSum += json[1]['data'][i]
};
options.plotOptions.column.dataLabels = {enabled:true,formatter:function() {var pcnt = (this.y / dataSum) * 100; return Highcharts.numberFormat(pcnt,2) + ' %';}};
options.xAxis.labels = {
autoRotation: [-10,-20,-30,-40,-50,-60,-70,-80,-90],
step: 1,
style: {fontSize: '80%',fontFamily: 'Arial Bold, Arial, Verdana'}};
break;
}
// GRAPHIC
chart = new Highcharts.Chart(options);},
"json");
EDIT 2
I generate my JSON with a PHP code :
[{name: "col1", categories: [{ name: "CITY1", categories: ["Not information", "Multiple", "type1"] }, { name: "CITY2", categories: ["Not information", "Type2"] }, { name: "CITY3", categories: ["Not information", "Type1","Type2"] }]} { name: "col2", categories: [1,6,1,3,1,2,1,9]}
But now if I try this for generate my graphic I don't have results :
For my name col1
options.xAxis.categories = json[0];
And for my name col2
options.series[0] = json[1];
It's an error with the navigation of my json but I don't see where is the error
after looking at your question for a very long time. believe me I am looking at the question for about half an hour, the json that you are providing has name and categories both as string. but Highcharts work with a string and number format. change your json categories to number and it will work.
I'm trying to use yahoo finance data to generate a Highcharts candlestick chart like this http://www.highcharts.com/stock/demo/candlestick-and-volume. But I keep getting this error: http://www.highcharts.com/errors/15
Highcharts Error #15
Highcharts expects data to be sorted
This happens when you are trying to create a line series or a stock chart where the data is not sorted in ascending X order. For performance reasons, Highcharts does not sort the data, instead it is required that the implementer pre-sorts the data.
My code is as follows.
$(function () {
$.getJSON('http://websitescraper.heroku.com/?url=http://ichart.finance.yahoo.com/table.csv?s=000338.sz&callback=?', function (csvdata) {
//console.log(csvdata);
var arr = csvdata.split('\n').slice(1);
var data = [];
for (var i = arr.length-1; i >= 0; --i) {
//console.log(arr[i]);
var line = arr[i].split(',');
line[0] = Date.parse(line[0]);
line = $.map(line, function(v) {
return parseFloat(v);
});
line = line.slice(0,6);
//var j = JSON.stringify(line.slice(0,0+6));
console.log(line);
data.push(line);
}
data = JSON.stringify(data.slice(1));
console.log(data);
run(data);
});
});
function run(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
]);
}
// create the chart
$('#container2').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'Shanghai Composite Index 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
}],
series: [{
type: 'candlestick',
upLineColor: 'red',
downLineColor: 'green',
name: 'SSE',
data: ohlc,
/*dataGrouping: {
units: groupingUnits
}*/
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1
/*dataGrouping: {
units: groupingUnits
}*/
}]
});
}
Can somebody help? Thanks a lot!
The problem is the data = JSON.stringify(data.slice(1));. It turns the array to a string, therefore Highstock doesn't recognize it. Remove JSON.stringify and it will work fine:
data = data.slice(1);
Here's the DEMO.