Loading nested JSON data into Gantt Chart - javascript

I am currently in the process of upgrading migrating my amCharts from V3 to V4 (I wish I hadn't started!) - One of the many issues I'm facing is trying to create a Gantt chart with JSON data.
I had no issue doing this using V3 library, but for the life of me I can't wrap my head around version 4 configuration.
This is how I loaded data using V3 (without any issues):
var chart_today = new Date();
var chart_month = chart_today.getMonth() + 1;
var chart_day = chart_today.getDate();
if (chart_month < 10) chart_month = '0' + chart_month;
if (chart_day < 10) chart_day = '0' + chart_day;
$('.ganttdiv').each(function(obj) {
var chart = AmCharts.makeChart(obj, {
"type": "gantt",
"theme": "light",
"responsive": {
"enabled": true
},
"marginRight": 70,
"period": "mm",
"precision": -1,
"dataDateFormat": "YYYY-MM-DD",
"columnWidth": 0.5,
"valueAxis": {
"type": "date"
},
"graph": {
"fillAlphas": 1
},
"rotate": true,
"categoryField": "category",
"segmentsField": "segments",
"colorField": "color",
"startDate": chart_today.getFullYear() + "-" + chart_month + "-" + chart_day,
"startField": "start",
"endField": "end",
"durationField": "duration",
"dataLoader": {
"url": "https://api.myjson.com/bins/zkhs3",
"async": true,
"reload": 300
},
"valueScrollbar": {
"autoGridCount": true
},
"chartCursor": {
"cursorColor": "#55bb76",
"valueBalloonsEnabled": false,
"cursorAlpha": 0,
"valueLineAlpha": 0.5,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true,
"zoomable": false,
"valueZoomable": true
},
});
});
I am attempting to recreate the same gantt chart - I have stripped back the bells and whistles in an effort to just display data but I'm having no joy.
Link to CodePen with latest attempt
Any suggestions would be greatly appreciated!
--also any suggestions for renaming the question would be a bonus :P

Related

AMcharts stockchart 2 timeseries on y axis

I am making an AMcharts stockchart with markers on it. The way I have done the markers is by taking the value of the price series only if a condition is met. Therefore the data has 4 columns:
Date
SPY price (SP500 etf)
Daily RSI Stance 1 (1,0 boolean value)
Signal (If Daily RSI Stance 1 = 1, SPY price, else blank)
CSV with data found here:
http://quantresearch.club/wp-content/themes/oceanwp/testing/RSI1dip.csv
The problem is that even though the data is perfectly aligned it does not show that way on the amcharts chart, which has me completely stumped. The markers ie. "4. Signal" show up under the "2. SPY price" timeseries. As shown here:
and finally for the code:
This first part is contained in the larger code below and it is what makes both timeseries appear.
"panels": [ {
"stockGraphs": [ {
"id": "g1",
"title": "SPY Price",
"valueField": "spy",
//"type": "line",
"lineColor": "#39fe90",
"useDataSetColors": false
},{
"id": "g2",
"title": "Signal",
"valueField": "Signal",
"bulletSize": 10,
"bullet": "round",
//"bulletBorderAlpha": 1,
"lineColor": "#551A8B",
"useDataSetColors": false
AmCharts.loadFile( "http://quantresearch.club/wp-content/themes/oceanwp/testing/RSI1dip.csv", {}, function( response ) {
var csvData = AmCharts.parseCSV( response, {
"useColumnNames": true
});
//var csvDataLength = csvData.length;
chartData = [];
guideData = [];
//var a = 0;
//var b = 0;
//var c;
var lastdate;
var firstdate;
$.each(csvData, function(i,k){
if(k.Date != undefined) {
chartData.push( {
"Date": k.Date,
"SPY": k.SPY,
"Signal": k.Signal
})
}
});
//console.log(guideData);
chart = AmCharts.makeChart( "chartdiv", {
"type": "stock",
"theme": "light",
"categoryAxesSettings": {
"labelRotation" : 30,
"minPeriod": "DD",
"axisAlpha" : 1,
"gridAlpha": 0,
//"dateFormats" : "MMM-YYYY",
},
"legend": {
"useGraphSettings": true
},
"dataSets": [ {
"fieldMappings": [{
"fromField": "SPY",
"toField": "spy"
},
{
"fromField": "Signal",
"toField": "Signal"
}],
"dataProvider": chartData,
"categoryField": "Date",}],
//Where the chart gets populated
"panels": [ {
"stockGraphs": [ {
"id": "g1",
"title": "SPY Price",
"valueField": "spy",
//"type": "line",
"lineColor": "#39fe90",
"useDataSetColors": false
},{
"id": "g2",
"title": "Signal",
"valueField": "Signal",
"bulletSize": 10,
"bullet": "round",
//"bulletBorderAlpha": 1,
"lineColor": "#551A8B",
"useDataSetColors": false
}],
"stockLegend": {
//"periodValueTextComparing": "[[percents.value.close]]%",
"periodValueTextRegular": "[[value.close]]",
//"labelText" : "SPY",
"combineLegend": true,
"markerType" : "line"
}
}, ],
"chartScrollbarSettings": {
"graph": "g1",
"usePeriod": "DD",
"position": "bottom",
"gridAlpha": 0
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"fullWidth": true,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true,
"valueLineAlpha": 0.5
},
"periodSelector": {
"inputFieldsEnabled" : true,
"position": "top",
"periods": [ {
"period": "YYYY",
"count": 2,
"label": "2Y"
}, {
"period": "YYYY",
"count": 5,
"label": "5Y"
},
{
"period": "YYYY",
"count": 10,
"label": "10Y"
},
{
"period": "MAX",
"label": "MAX",
"selected": true,
}
]
},
"valueAxesSettings": {
"gridColor": "#555",
"gridAlpha": 0,
//"axisAlpha" : 1,
"inside": false,
"position": "right",
"showLastLabel": true
},
"panelsSettings": {
"usePrefixes": false,
"marginRight" : 20,
"marginBottom" : 10,
"marginLeft" : 20,
"marginTop" : 10
},
"export": {
"enabled": true,
"position": "top-left"
}
} );
/*chart.addListener("init", function(event) {
console.log(event);
});*/
});
If anyone has any ideas about this it would be greatly appreciated.
Thank you very much.
The issue is due to the stock chart's data grouping functionality. The chart groups data to improve performance when there a lot of points visible, which impacts how the line is drawn as it is using points derived from its data grouping algorithm. By default it's using the "Close" value in the grouping to plot your points and changing the periodValue in your SPY graph will change the appearance. Since your Signal data set has much fewer points in comparison, the chart simply plots out the raw values for that graph, which do not match up to your grouped SPY graph's values, regardless of which periodValue you use.
Your only option to make the values from both graphs line up correctly is to disable data grouping by setting maxSeries to 0 in your categoryAxesSettings. This will impact performance if you have a lot of points.
Here's a codepen of your chart with maxSeries set to 0.

How to show stacked and unstacked bar graphs together in Chart.js

We are trying to display three sets of data, two stacked, one unstacked using chart.js. We defined two sets of axis where only the stacked data shows and the unstacked data does not. We can only get the axis to display or not display, but we cannot get the data to appear at all.
We know the data is valid because we can get all of the data to stack together, but not separately.
recycleChartData = {
"type":"bar",
"data":{
"labels":["Mar-2016"],
"datasets":[
{
"label":"benchmark",
"backgroundColor":"#ff3300",
"yAxisID":"stacked_testY2",
"xAxisID":"stacked_testX2",
"data":["2632.29"]
},
{
"label":"Crossville",
"backgroundColor":"#009900",
"yAxisID":"stacked_testY",
"xAxisID":"stacked_testX",
"data":["2268.44"]
},
{
"label":"test",
"backgroundColor":"#ffff00",
"yAxisID":"stacked_testY",
"xAxisID":"stacked_testX",
"data":["181.92"]
}
]
},
"options":{
"scales":{
"yAxes":[
{
"id":"stacked_testY",
"position":"left",
"stacked":true,
"display":true
},
{
"id":"stacked_testY2",
"position":"left",
"stacked":false,
"display":false
}
],
"xAxes":[
{
"id":"stacked_testX",
"position":"bottom",
"stacked":true,
"display":true
},
{
"id":"stacked_testX2",
"position":"bottom",
"stacked":false,
"display":false
}
]
}
}
};
It's odd that your code doesn't work, if you change the non-stacked dataSet to a line graph you see the data! Maybe worth posting an issue on the chartjs github.
But...
There was a feature released in 2.5.0 which will allow for this sort of scenario. More on what it is can be read here, https://github.com/chartjs/Chart.js/issues/2643.
Basically, you can add a new property stack on each of your dataSets to denote which stack you would like it to go on to, so for example with your data you could remove the extra scales and have 2 stacks
var config = {
"type": "bar",
"data": {
"labels": ["Mar-2016","Apr-2016"],
"datasets": [ {
"label": "Crossville",
"backgroundColor": "#009900",
"data": ["2268.44","2268"],
stack: 2,
}, {
"label": "test",
"backgroundColor": "#ffff00",
"data": ["181.92","181.92"],
stack: 2
},{
"label": "benchmark",
"type": "bar",
"backgroundColor": "#ff3300",
"data": ["2632.29","2632.29"],
stack: 1
}]
},
"options": {
"scales": {
"yAxes": [{
"id": "stacked_testY",
"type": 'linear',
"position": "left",
"stacked": true,
"display": true
}],
"xAxes": [{
"position": "bottom",
"stacked": true,
"display": true
}]
}
}
};
var chartElement = document.getElementById('chart');
var chart = new Chart(chartElement, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div style="width:75%;">
<canvas id="chart"></canvas>
</div>
I came across this issue when trying to find out how to stack specific datasets of a line diagram in Chart.js v2.x.
Chart.js v3.x supports the stack attribute for line diagrams but in Chart.js v2.x:
you have to use multiple y-axis
to align the values you need to calculate the maximal value yourself and set ticks.max or ticks.suggestedMax in the axis configuration.
false console:
let yMax = 3000; // Calculate value beforehand.
var config = {
"type": "line",
"data": {
"labels": ["Mar-2016","Apr-2016","May-2016"],
"datasets": [ {
"label": "Crossville",
"backgroundColor": "#009900",
"data": ["2268.44","2268","31"]
}, {
"label": "test",
"borderColor": "#ffff00",
"data": ["181.92","181.92", "1000"],
"yAxis": 'A'
},{
"label": "benchmark",
"backgroundColor": "#ff3300",
"data": ["2632.29","2632.29","500"]
}]
},
"options": {
"scales": {
"yAxes": [
{
"id": "A",
ticks: {
beginAtZero: true,
display: true,
suggestedMax: yMax
},
},
{
"stacked": true,
"ticks": {
beginAtZero: true,
display: true, // Set this to false so that only one axis is shown!!!
suggestedMax: yMax
},
},
],
"xAxes": [{
"position": "bottom",
"stacked": true,
"display": true
}]
}
}
};
var chartElement = document.getElementById('chart');
var chart = new Chart(chartElement, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<div style="width:75%;">
<canvas id="chart"></canvas>
</div>

Bar Chart slow zoom In/out - AmCharts

While zooming my Bar amchart is rendering very slow when data is large, that is, 2975 points. Although, rendering is fine but it is lagging while zooming in/out using drag icon. The code is as below:
for(var i=0; i<title.length; i++) {
var graphElem = {
"title":title[i],
"valueField":valueFields[i],
"valueAxis":"v1",
"type": "column",
"fillAlphas": 0.8,
"lineAlpha": 0.2
};
graph.push(graphElem);
}
var chart = AmCharts.makeChart(graphType, {
"type": "serial",
"theme": "light",
"pathToImages": "/grm/images/",
"legend": {
"equalWidths": false,
"position": "bottom",
"spacing": 3,
"markerSize":8,
},
"dataProvider": dataProvider,
"valueAxes": [ {
"id":"v1",
"axisThickness": 1,
"gridAlpha": 0,
"axisAlpha": 1,
"position": "left",
"integersOnly" : true
} ],
"columnSpacing" : 0,
"graphs": graph,
"chartScrollbar": {
"dragIconHeight" : 25,
"dragIconWidth" : 25
},
"chartCursor": {
"cursorAlpha": 0,
"cursorPosition": "mouse",
"categoryBalloonDateFormat": "MMM DD, YYYY JJ:NN"
},
"categoryField": "linkTimestamp",
"categoryAxis": {
"parseDates": true,
"axisColor": "#000000",
"minPeriod": "mm"
},
"dataDateFormat": "YYYY-MM-DD HH:NN:SS"
} );
chart.addListener("dataUpdated", zoomChart);
zoomChart();
function zoomChart(){
chart.zoomToIndexes(chart.dataProvider.length - 20, chart.dataProvider.length - 1);
}
if i use graph other than the bar(column) chart, zoom in/out is fast but it is lagging only in case of "type": "column". Please help where am i making mistake. Thanks
Try to only allow the re-rendering to happen after the zoom by setting updateOnReleaseOnly to true.
Try to remove animations, it worked for me.

Showing percentage on bar graph in amcharts

I am newbie in Amcharts and I am trying to show the percentage of the data in the column graph.
var amc=AmCharts.makeChart("pickup_bar",
{
"type": "serial",
"dataLoader": {
"url": "the data url"
},
"categoryField": "distance",
"startDuration": 1,
"categoryAxis": {
"gridPosition": "start"
},
"trendLines": [],
"graphs": [
{
"valueField": "taxi",
"fillColors":"#1E90FF",
"type": "column",
"balloonText": "[[title]] of [[category]]:[[value]]",
"fillAlphas": 0.8,
"lineAlpha": 0.2,
"id": "AmGraph-1",
"title": "Distance Traveled",
"labelText": " ",
"labelPosition": "inside",
"labelFunction": function( item ) {
var total = 0;
for ( var i = 0; i < chart.dataLoader.length; i++ ) {
total += chart.dataLoader[ i ][ item.graph.valueField ];
}
var percent = Math.round( ( item.values.value / total ) * 1000 ) / 10;
return percent + "%";
}
}],
"guides": [],
"valueAxes": [
{
"id": "ValueAxis-1",
"title": "Milage",
"gridColor": "#FFFFFF",
"gridAlpha": 0.2
}
],
"categoryAxis": {
"title": "(in Kilometers)"
},
"gridAboveGraphs": true,
"allLabels": [],
"balloon": {},
"legend": {
"enabled": true,
"useGraphSettings": true
},
"titles": [
{
"id": "Title-1",
"size": 15,
"text": "Taxis Driving Distance "
}
]
});
The data format is json and will be as
> [{"distance":"<50","taxi":309,"day":1},{"distance":"50-100","taxi":100,"day":1},{"distance":"100-200","taxi":300,"day":1},...]
The chart is load even loading but when I remove the line
"labelPosition": "inside",
The graph appears but not the percentage.
Can Anyone help in this?
There are a couple of issues in your code.
Firstly, you're accessing an undefined chart variable. Your code is assigning the chart object to amc. You'll want to change your code to match, or access the chart instance through item.graph.chart.
Secondly, you're looping through the dataLoader in your labelFunction instead of the dataProvider. The dataLoader object doesn't store your chart data, it just loads data into your chart's dataLoader after it retrieves it from the specified URL. Here's your fixed labelFunction:
"labelFunction": function(item) {
var total = 0;
var chart = item.graph.chart;
for (var i = 0; i < chart.dataProvider.length; i++) {
total += chart.dataProvider[i][item.graph.valueField];
}
var percent = Math.round((item.values.value / total) * 1000) / 10;
return percent + "%";
}
The labels display for me with your data after I made these changes. If you're still not seeing the labels, perhaps you have a lot of data in a limited space. By default, the chart won't render graph value labels if it can't fit them. If you want to override this behavior, set the graph's showAllValueLabels property to true.
Demo

Change function to use as onchange event

I have the following javascript function for listbox organization:
$("#organization").change(function(e) {
//function updateOrganization() {
organization = $("#organization").val();
indicator = $("#indicators").val();
funcid = "fill_chart_average_score";
//console.log('changed');
$.getJSON('functions/getfunctions.php', {
"organization":organization,
"indicator":indicator,
"funcid":funcid},
function(dataChart) {
var chart = AmCharts.makeChart("chartaveragescore", {
"theme": "light",
"type": "serial",
"startDuration": 1,
"dataProvider": dataChart,
"rotate": false,
"categoryField": "organisatie",
"valueAxes": [ {
"gridColor": "#FFFFF",
"gridAlpha": 0.2,
"dashLength": 0
} ],
"gridAboveGraphs": true,
"startDuration": 1,
"graphs": [ {
"balloonText": "[[category]]: <b>[[value]]</b>",
"fillColorsField": "fillcolor", //Dit veld heb ik meegegeven vanuit SQL functie en bevat de HEX kleurcodes BD
"fillAlphas": 0.8,
"lineAlpha": 0.2,
"type": "column",
"valueField": "score"
} ],
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryAxis": {
"gridPosition": "start",
"gridAlpha": 0,
"tickPosition": "start",
"tickLength": 20
},
"export": {
"enabled": true
}
},0);
$('.chart-input').off().on('input change',function() {
var property = jQuery(this).data('property');
var target = chart;
chart.startDuration = 0;
});
});
});
This works great, but what i want now is to make a function not based on $("#organization").change(function(e) but just make a function like function updateOrganization() and call this function in an onchange within the html element. When i change the $("#organization").change(function(e) with function updateOrganization() the function doesn't work anymore.
I'm a starting javascript learner :).
I think you want to call function on change of dropdown and you want to do it with onchange event of select tag. This might help you.
You should declare your function outside the block. Something like:
function updateOrganization() {
organization = $("#organization").val();
indicator = $("#indicators").val();
funcid = "fill_chart_average_score";
// ...
}
and then use it as:
$("#organization").change(updateOrganization);

Categories

Resources