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.
Related
Im dealing with this problem.
I have smoothed line chart from amcharts v5.
And everything is working properly until i want to add second line to the chart. It only displays one line chart. And i need to add second line to the same chart.
If I change data values to another chart. It is working fine but same problem, only one line.
So my question is, how to add second line into same chart.
am5.ready(function() {
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root)
]);
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: true,
panY: true,
wheelX: "panX",
wheelY: "zoomX",
pinchZoomX:true
}));
// Add cursor
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
behavior: "none"
}));
cursor.lineY.set("visible", false);
function generateDataInvestice(roky,investice) {
value = investice;
return {
date: roky,
value: value
};
}
function generateDatasInvestice(count,i) {
var data = [];
var investice = 5;
for (var i = 1; i < count; ++i) {
data.push(generateDataInvestice(i,investice));
}
return data;
}
//generate uver
function generateDataUver(roky,uver) {
value = uver;
return {
date: roky,
value: value
};
}
function generateDatasUver(count,i) {
var data = [];
var uver = 1;
for (var i = 1; i < count; ++i) {
data.push(generateDataUver(i,uver));
}
return data;
}
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
maxDeviation: 1,
baseInterval: {
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {
pan:"zoom"
}),
tooltip: am5.Tooltip.new(root, {})
}));
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
maxDeviation:1,
renderer: am5xy.AxisRendererY.new(root, {
pan:"zoom"
})
}));
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(am5xy.SmoothedXLineSeries.new(root, {
name: "Series",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "value",
valueXField: "date",
tooltip: am5.Tooltip.new(root, {
labelText: "{valueY}"
})
}));
series.fills.template.setAll({
visible: true,
fillOpacity: 0.2
});
series.bullets.push(function() {
return am5.Bullet.new(root, {
locationY: 0,
sprite: am5.Circle.new(root, {
radius: 4,
stroke: root.interfaceColors.get("background"),
strokeWidth: 2,
fill: series.get("fill")
})
});
});
var data = generateDatasInvestice(30,0);
var data_uver = generateDatasUver(30,0);
series.data.setAll(data,data_uver);
series.appear(30);
chart.appear(1000, 100);
}); // end am5.ready()
Here is working soluiton on codepen: https://codepen.io/tom-august/pen/KKQLgbm
Thanks a lot.
In your data, you should have several value fields like so:
var data = [
{
date: new Date("2022-12-27").getTime(),
value1: 10,
value2: 20
},
{
date: new Date("2022-12-28").getTime(),
value1: 20,
value2: 30
},
{
date: new Date("2022-12-29").getTime(),
value1: 10,
value2: 20
}
];
Then you need to create a series for each line that you want to display, associating each series with the corresponding value field. This can be done using a function:
function createSeries(name, field) {
var series = chart.series.push(am5xy.SmoothedXLineSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueXField: "date",
valueYField: field
}));
series.data.setAll(data);
}
createSeries("Series 1", "value1");
createSeries("Series 2", "value2");
am5.ready(function() {
var root = am5.Root.new("chartdiv");
var chart = root.container.children.push(am5xy.XYChart.new(root, {}));
var data = [
{
date: new Date("2022-12-27").getTime(),
value1: 10,
value2: 20
},
{
date: new Date("2022-12-28").getTime(),
value1: 20,
value2: 30
},
{
date: new Date("2022-12-29").getTime(),
value1: 10,
value2: 20
}
];
var xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
baseInterval: { timeUnit: "day", count: 1 },
renderer: am5xy.AxisRendererX.new(root, {}),
}));
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {})
}));
function createSeries(name, field) {
var series = chart.series.push(am5xy.SmoothedXLineSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueXField: "date",
valueYField: field
}));
series.data.setAll(data);
}
createSeries("Series 1", "value1");
createSeries("Series 2", "value2");
});
#chartdiv {
width: 100%;
height: 350px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<div id="chartdiv"></div>
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);
I have a Pie Chart that gets its data from the file. In raw form, this is the data:
[{"name":"Dual","load":"20"},{"name":"Gas","load":"35"},{"name":"Other_Fossil_Fuels","load":"15"},{"name":"Nuclear","load":"12"},{"name":"Hydro","load":"8"},{"name":"Wind","load":"10"},{"name":"Other_Renwables","load":"10"}]
I am trying to make a method that formats this data correctly so that it can be used in the pie chart. However only the Names come through correctly, with all of the percentages set to 0. I have a feeling that it is because the raw data is saved as a String. But using parseInt() on the data before pushing doesn't help and the === check returns num. Here is the code i am trying to implement.
function setPieData(data){
var json = JSON.parse(data);
var fuelTypes = [{name: 'Dual',load:[]},
{name: 'Gas', load:[]},
{name: 'Other_Fossil_Fuels', load:[]},
{name: 'Nuclear', load: []},
{name: 'Hydro', load: []},
{name: 'Wind', load: []},
{name: 'Other_Renwables', load:[]}];
for(i=0; i < json.length; i++){
if(json[i].name == fuelTypes[i].name){
fuelTypes[i].load.push(parseInt(json[i].load));
}
if(fuelTypes[i].load === parseInt(fuelTypes[i].load, 10)){
alert("not num");
}else{
alert("num");
}
}
drawChart(fuelTypes);
}
function drawChart(stuff){
var globalDate = new Date();
var dMth = globalDate.getMonth() + 1;
var dDay = globalDate.getDate();
var dYr = globalDate.getFullYear();
var dStr = dMth + '/' + dDay + '/' + dYr;
title = "Real-time Fuel Mix " + dStr;
var seriesData= stuff;
Highcharts.setOptions({
colors: ['#C00000', '#FF0000', '#7F7F7F', '#FFC000', '#4F81BD', '#00B050', '#92D050']
});
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: title
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
},
showInLegend: true
}
},
series: [{
name: "MI Power",
colorByPoint: true,
data: stuff
}]
create an Array and push your data like following
var dataPie =[];
var abc =your data //your json
$.each(abc,function(i,el)
{
dataPie.push({name :el.name,y: parseInt(el.load)});
});
use dataPie in your drawChart function.
see working fiddle here
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.
Here is a jsFiddle for an issue i have been trying to solve:
http://jsfiddle.net/kSSYg/
When the donut chart loads, the slices are not visible, but the legends are. When you hover over, they appear.
Has anyone else encountered this?
code
$(function () {
var chart;
$(document).ready(function() {
var colors = Highcharts.getOptions().colors,
categories = ['Security', 'Interfaces', 'SNMP', 'Management', 'General'],
name = 'Rule Categories',
data = [{"y":23.53,"drilldown":{"name":"Security","categories":["Pass","Fail"],"data":[11.77,11.77]}},{"y":23.53,"drilldown":{"name":"Interfaces","categories":["Pass","Fail"],"data":[23.53,0]}},{"y":23.53,"drilldown":{"name":"SNMP","categories":["Pass","Fail"],"data":[11.77,11.77]}},{"y":5.88,"drilldown":{"name":"Management","categories":["Pass","Fail"],"data":[5.88,0]}},{"y":23.53,"drilldown":{"name":"General","categories":["Pass","Fail"],"data":[23.53,0]}}];
// Build the data arrays
var browserData = [];
var versionsData = [];
for (var i = 0; i < data.length; i++) {
// add browser data
browserData.push({
name: categories[i],
y: data[i].y,
color: data[i].color
});
// add version data
for (var j = 0; j < data[i].drilldown.data.length; j++) {
var brightness = 0.2 - (j / data[i].drilldown.data.length) / 5 ;
versionsData.push({
name: data[i].drilldown.categories[j],
y: data[i].drilldown.data[j],
color: Highcharts.Color(data[i].color).brighten(brightness).get()
});
}
}
// Create the chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie'
},
title: {
text: 'Browser market share, April, 2011'
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
shadow: false
}
},
tooltip: {
valueSuffix: '%'
},
series: [{
name: 'Browsers',
data: browserData,
size: '60%',
dataLabels: {
formatter: function() {
return this.y > 5 ? this.point.name : null;
},
color: 'white',
distance: -30
}
}, {
name: 'Versions',
data: versionsData,
innerSize: '60%',
dataLabels: {
formatter: function() {
// display only if larger than 1
return this.y > 1 ? '<b>'+ this.point.name +':</b> '+ this.y +'%' : null;
}
}
}]
});
});
});
Do you have to define your own colors? If you remove the two lines which are setting the colors, it works. See http://jsfiddle.net/kSSYg/2/
remove:
color: data[i].color
and
color: Highcharts.Color(data[i].color).brighten(brightness).get()
The reason these lines are not working is because your data array objects do not define the attribute "color"