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.
Related
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
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.
I'm building a pie graph using amcharts.
The pie is displayed normally in Firfox, meanwhile in Chrome it isn't:
html:
<div id="performancePieChartDiv" style="width: 295px; height: 83px"></div>
js:
var performancePieConfig = {
"type": "pie",
"angle": 50,
"depth3D": 15,
"valueField": "value",
"titleField": "label",
"labelsEnabled": false,
"balloonText" : "[[percents]]%",
"colors": [
"#00CC00",
"#FFAB02",
"#FF0000"
],
"gradientType": "linear",
"gradientRatio": [-.4, 0],
"legend": {
"position": "right",
"markerBorderColor": "#000000",
"markerSize": 8,
"marginRight" : 0,
"marginLeft" : 0,
"verticalGap": 0,
"valueWidth" : 0,
"switchable": false
},
"outlineAlpha": 1,
"outlineColor": "#cdcdcd"
};
createChart("performancePieChartDiv", performancePieConfig, true, performancePieData, function(retValue) {
performancePieChart = retValue;
});
In the Chrome Console I'm having the error:
https://localhost/report/amcharts/images/dragIconRoundBigH.svg 404 (Not Found)
https://localhost/report/amcharts/images/dragIconRoundBig.svg 404 (Not Found)
although this files are located at the needed folder in my local repository.
Any idea why this is happening?
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);
I have written some code in amcharts.js to create stacked bar charts (with data as a parameter) and a pie chart.
The code can be found here:
http://jsfiddle.net/akashdmukherjee/myd363tw/30/
HTML:
<script type="text/javascript" src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="http://www.amcharts.com/lib/3/serial.js"></script>
<script type="text/javascript" src="http://www.amcharts.com/lib/3/pie.js"></script>
<script type="text/javascript" src="http://www.amcharts.com/lib/3/themes/none.js"></script>
<div id="chartdiv"></div>
CSS:
#chartdiv {
width : 100%;
height : 500px;
font-size : 11px;
}
JS:
var year_wise_continent_breakdown_data =
[
{"year": 2003,"europe": 2.5,"namerica": 2.5,"asia": 2.1,"lamerica": 0.3,"meast":0.2,"africa": 0.1},
{"year": 2004,"europe": 2.6,"namerica": 2.7,"asia": 2.2,"lamerica": 0.3,"meast": 0.3,"africa": 0.1}
, {"year": 2005,"europe": 2.8,"namerica": 2.9,"asia": 2.4,"lamerica": 0.3,"meast": 0.3,"africa": 0.1}
];
var quarter_wise_continent_breakdown_data_for_2003 =
[
{"year": "Q1","europe": 0.5,"namerica": 2.1,"asia": 1.1,"lamerica": 0.3,"meast":0.2,"africa": 0.1},
{"year": "Q2","europe": 2.6,"namerica": 2.7,"asia": 3.2,"lamerica": 0.3,"meast": 0.3,"africa": 0.1}
, {"year": "Q3","europe": 2.8,"namerica": 1.7,"asia": 1.4,"lamerica": 1.3,"meast": 1.3,"africa": 2.1}
];
var quarter_wise_continent_breakdown_data_for_2004 =
[
{"year": "Q1","europe": 1.5,"namerica": 2.1,"asia": 1.1,"lamerica": 0.3,"meast":0.2,"africa": 0.1},
{"year": "Q2","europe": 4.6,"namerica": 2.7,"asia": 3.2,"lamerica": 0.3,"meast": 0.3,"africa": 0.1}
, {"year": "Q3","europe": 5.8,"namerica": 1.7,"asia": 1.4,"lamerica": 1.3,"meast": 1.3,"africa": 2.1}
];
var quarter_wise_continent_breakdown_data_for_2005 =
[
{"year": "Q1","europe": 3.9,"namerica": 2.1,"asia": 1.1,"lamerica": 0.3,"meast":0.2,"africa": 0.1},
{"year": "Q2","europe": 2.1,"namerica": 2.7,"asia": 3.2,"lamerica": 0.3,"meast": 0.3,"africa": 0.1}
, {"year": "Q3","europe": 0.8,"namerica": 1.7,"asia": 1.4,"lamerica": 1.3,"meast": 1.3,"africa": 2.1}
];
var continent_breakdown_data = [
{"country": "UK", "litres": 99},
{"country": "Belgium","litres": 60},
{ "country": "The Netherlands","litres": 50}
];
var make_pieChart_from_continent_breakdown_data = function(selected_year, selected_region){
AmCharts.makeChart("chartdiv", {
"type": "pie",
"theme": "none",
"dataProvider": continent_breakdown_data,
"valueField": "litres",
"titleField": "country",
"exportConfig":{
menuItems: [{
icon: '/lib/3/images/export.png',
format: 'png'
}]
}
});
};
var make_stackedBars_chart = function(data_for_stackedBars_chart){
AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "none",
"legend": {
"horizontalGap": 10,
"maxColumns": 1,
"position": "right",
"useGraphSettings": true,
"markerSize": 10
},
"dataProvider": data_for_stackedBars_chart,
"valueAxes": [{
"stackType": "regular",
"axisAlpha": 0.3,
"gridAlpha": 0
}],
"graphs": [{
"balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
"fillAlphas": 0.8,
"labelText": "[[value]]",
"lineAlpha": 0.3,
"title": "Europe",
"type": "column",
"fillColors": "#3C3C3C",
"valueField": "europe"
}, {
"balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
"fillAlphas": 0.8,
"labelText": "[[value]]",
"lineAlpha": 0.3,
"title": "North America",
"type": "column",
"color": "#000000",
"valueField": "namerica"
}, {
"balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
"fillAlphas": 0.8,
"labelText": "[[value]]",
"lineAlpha": 0.3,
"title": "Asia-Pacific",
"type": "column",
"color": "#000000",
"valueField": "asia"
}, {
"balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
"fillAlphas": 0.8,
"labelText": "[[value]]",
"lineAlpha": 0.3,
"title": "Latin America",
"type": "column",
"color": "#000000",
"valueField": "lamerica"
}, {
"balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
"fillAlphas": 0.8,
"labelText": "[[value]]",
"lineAlpha": 0.3,
"title": "Middle-East",
"type": "column",
"color": "#000000",
"valueField": "meast"
}, {
"balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
"fillAlphas": 0.8,
"labelText": "[[value]]",
"lineAlpha": 0.3,
"title": "Africa",
"type": "column",
"color": "#000000",
"valueField": "africa"
}],
"categoryField": "year",
"categoryAxis": {
"gridPosition": "start",
"axisAlpha": 0,
"gridAlpha": 0,
"position": "left"
},
"exportConfig":{
"menuTop":"20px",
"menuRight":"20px",
"menuItems": [{
"icon": '/lib/3/images/export.png',
"format": 'png'
}]
}
})
};
//****************************************************************************
// RENDER CHARTS
//****************************************************************************
make_stackedBars_chart(year_wise_continent_breakdown_data);
////make_pieChart_from_continent_breakdown_data(2005, "Asia-Pacific");
If you notice, I create stacked bar charts using make_stackedBars_chart() function by passing in data. From my code, there are four options I can pass as data for the stacked bar chart:
1. year_wise_continent_breakdown_data
2. quarter_wise_continent_breakdown_data_for_2003
3. quarter_wise_continent_breakdown_data_for_2004
4. quarter_wise_continent_breakdown_data_for_2003
I could also create a pie chart instead using the function make_pieChart_from_continent_breakdown_data(selected_year, selected_region). The pie chart, for simplicity here, uses only one piece of data that's defined as the continent_breakdown_data variable.
The first view that an user of this 'dashboard' would see is the year-wise trends broken down by continents. This is the page that's renders when you open the jsfiddle link. This is made possible by a function call make_stackedBars_chart(year_wise_continent_breakdown_data);
But now is the fun part.
How do I make this interactive?
Let's start with the first view.
When the user single-clicks on the first column (data for year 2003), or second column (data for year 2004), or third column (data for year 2005), I want the selected column to be highlighted in Grey. Something like this.
My hope is that this can be set by setting the fillColors attribute of the graph object in the function. But how?
Next, when the user double-clicks on the selected column, the user should be able to drill-down to a new stacked bar chart which shows category breakdown but trending over Quarters of the selected year. So, let's say the user selected year 2005. When they single-clicked, it turned grey. After single-clicking or before single-clicking, if they double-click the year 2005 column, a new stacked bar chart is loaded with an additional button on top to go back to the previous chart. My understanding is that this needs to be done using a function call of make_stackedBars_chart(quarter_wise_continent_breakdown_data_for_2005);
This should look something like this:
Once this, is done user should be able to click on the top button to go back from there to the old chart into this view.
Fine. So the user saw year-wise view and quarter-wise view. But, now they want to select only one category (Asia-Pacific region) of year 2005 and see some other data specific to that. Selecting any portion on the chart should first collect the category (region/continent in this case) they have selected and the year they have selected. The selected region should be colored grey on a single click.
On a double click before/after the single-click on this portion of Asia-Pacific in 2005, this information should be passed onto a function that creates a pie chart accordingly. For this, a function call of this could be made
make_pieChart_from_continent_breakdown_data(2005, "Asia-Pacific"); The resultant graph should also have a button on top to go back to the original view. It should look something like this.
Clicking on 'Go Back', they should be redirected to the original year-wise stacked bar chart.
You should follow this example on drill down data: http://www.amcharts.com/tutorials/drill-down-column-chart/
Key points: generate data of quarter data as subdata for the yeardata and attach a click event to the chart to catch clicks on the bar to open next level.
Structure is like this:
data = [{country : "Country1", data1 : "value1", data2 : "value2",
subdata [{ country : "Country1", data1.1 : "value1.1", data2.1 : "data2.1"},
{country : "Country1", data1.2 : "value1.2", data2.2 : "data2.2"}]}]
and click event:
chart.addListener("clickGraphItem", function (event) {
if (event.item.dataContext.subdata != undefined) {
event.chart.dataProvider = event.item.dataContext.subdata;
event.chart.validateData();
}
});
This example shows how to change chart types onclick: http://www.amcharts.com/tips/switching-chart-type-fly-serial-pie/
Relevant points: You can have other type of chart on screen hidden, and onclick makes you change between charts:
document.getElementById('chartdiv').style.display = 'none';
document.getElementById('chartdiv2').style.display = 'block';
For double click, catch the following event: http://www.amcharts.com/tips/simulate-doubleclick-map-object/
Pointers:
map.addListener("clickMapObject", function (event) {
if ( false !== map.clickedObject && map.clickedObject === event.mapObject ) {
// doubleckick
map.clickedObject = false;
alert('doubleclick');
} else {
clearTimeout( map.clickedObjectTimeout );
map.clickedObject = event.mapObject;
map.clickedObjectTimeout = setTimeout( function () {
map.clickedObject = false;
}, 500 );
}
});
Final notes: These are some pointers where you have to make the solution by your own. Markups are taken (almost) directly from the linked examples, so event/element names will vary on your need. Maybe you at least get started with these.