I am new to javascript and am working on an application which would allow someone to view a plot for data using amCharts. I had tried Dash by Plotly but unfortunately on a shared platform I couldnt run it as it consumed more resources than expected. The challenge I have been having is linking the dropdown menu to the amCharts. I tried linking them up using the code below but returned errors saying value is not known. I have the following blocks of code can someone assist in linking them up.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
#dropdown {
width : 100%;
height : auto;
}
#chartdiv {
width : 100%;
height : 500px;
}
</style>
<meta charset="utf-8"/>
<script src="amcharts.js" type="text/javascript"></script>
<script src="serial.js" type="text/javascript"></script>
<script src="amstock.js" type="text/javascript"></script>
<script src="plugins/dataloader/dataloader.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="plugins/export/export.css" type="text/css" media="all" />
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
</head>
<body>
<script>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
d3.csv("data.csv", function(error, data) {
var select = d3.select("body")
.append("div")
.append("select")
select
.on("change", function(d) {
var value = d3.select(this).property("value");
});
select.selectAll("option")
.data(data)
.enter()
.append("option")
.attr("value", function (d) { return d.value; })
.text(function (d) { return d.label; });
});
var chart = AmCharts.makeChart( "chartdiv", {
"path": "/amcharts/",
"type": "stock",
"theme": "light",
"dataSets": [ {
"title": value,
"fieldMappings": [ {
"fromField": "Open",
"toField": "open"
}, {
"fromField": "High",
"toField": "high"
}, {
"fromField": "Low",
"toField": "low"
}, {
"fromField": "Close",
"toField": "close"
}, {
"fromField": "Volume",
"toField": "volume"
} ],
"compared": false,
"categoryField": "Date",
/**
* data loader for data set data
*/
"dataLoader": {
"url": "http://www.google.com/finance/historical?q="+value+":ADBE&startdate=Jan+01%2C+2009&enddate=Aug+2%2C+2012&output=csv",
"format": "csv",
"showCurtain": true,
"showErrors": true,
"async": true,
"reverse": false,
"delimiter": ",",
"useColumnNames": true
},
}],
"panels": [ {
"showCategoryAxis": false,
"title": "Value",
"percentHeight": 70,
"stockGraphs": [ {
"type": "line",
"id": "g1",
/*"openField": "open",
"closeField": "close",
"highField": "high",
"lowField": "low",*/
"valueField": "close",
"lineColor": "#db4c3c",
"fillColors": "#fff",
"negativeLineColor": "#db4c3c",
"negativeFillColors": "#db4c3c",
"fillAlphas": 0,
"comparedGraphLineThickness": 2,
"columnWidth": 0.7,
"useDataSetColors": false,
"comparable": true,
"compareField": "close",
"showBalloon": false,
"proCandlesticks": true
} ],
"stockLegend": {
"periodValueTextComparing": "[[percents.value.close]]%",
"periodValueTextRegular": "[[value.close]]"
}
}, {
"title": "Volume",
"percentHeight": 30,
"stockGraphs": [ {
"valueField": "volume",
"type": "column",
"showBalloon": false,
"fillAlphas": 1,
"lineColor": "#db4c3c",
"fillColors": "#db4c3c",
"negativeLineColor": "#db4c3c",
"negativeFillColors": "#db4c3c"
} ],
"stockLegend": {
"periodValueTextRegular": "[[value.close]]"
}
} ],
"chartScrollbarSettings": {
"graph": "g1"
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"fullWidth": true,
"cursorAlpha": 0.1,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true,
"valueLineAlpha": 0.5
},
"periodSelector": {
"position": "left",
"periods": [ {
"period": "MM",
"selected": true,
"count": 1,
"label": "1 month"
}, {
"period": "YYYY",
"count": 1,
"label": "1 year"
},{
"period": "YYYY",
"count": 2,
"label": "2 year"
},{
"period": "YTD",
"label": "YTD"
}, {
"period": "MAX",
"label": "MAX"
} ]
},
"dataSetSelector": {
"position": "left"
},
"export": {
"enabled": true
}
} );
</script>
<div id="chartdiv"></div>
</body>
</html>
The trick is retaining the value of the dropdown and appending it to the url. The other thing is it possible to create a call back function to update the plot whenever the dropdown is changed. The contents of the dropdown are
name,ticker
apple, AAPL
google,googl
microsoft,msft
The first row being the header row with column names. The intention is not to hard code the dataset and the dropdown to allow someone without any knowledge to change add a dataset to the list. Its not necessarily financial data but also healthcare and other forms. chose this as a working example coz it was nearest.
value isn't defined by the time AmCharts.makeChart is called due to the fact that the csv method is asynchronous. You'll want to adjust your setup so that your csv callback creates the initial chart with a default value, e.g.
var chart;
d3.csv("data.csv", function(error, data) {
// ... other code ...
var value = data[0].ticker; //for this particular use case - update to the appropriate csv column name as needed
chart = AmCharts.makeChart("...", {
// ... rest of your config as usual, including the now defined value variable
});
});
To make the dropdown update the chart, you need to modify the chart instance's dataLoader url then call the loadData method during the change callback:
select
.on("change", function(d) {
var value = d3.select(this).property("value");
chart.dataSets[0].dataLoader.url = /* modify the url string here */
chart.dataSets[0].dataLoader.loadData(); //reload the data with new URL value
});
Related
Im working in a graph where data comes from server like Object's Array.
I dont need some data to show in my graph, data where number=0, and i want to know if amchart have some function to dont show this.
Here is an example of the code:
var data =[
{'number':1, 'date':'11:00-11:59', 'duration': 3},
{'number':2, 'date':'12:00-12:59', 'duration':6},
{'number':4, 'date':'13:00-13:59', 'duration':12},
{'number':8, 'date':'14:00-14:59', 'duration':8},
{'number':0, 'date':'14:00-14:59', 'duration':0}
];
var chart = AmCharts.makeChart("chartdiv", {
"theme": "light",
"type": "serial",
"startDuration": 2,
"dataProvider": data,
"valueAxes": [{
"id": "number",
"position": "left",
"title": "N Llamadas"
},{
"id": "durationAxis",
"position": "right",
"title": "duration"
}],
"graphs": [{
"balloonText": "[[category]]: <b>[[value]]</b>",
"fillColorsField": "color",
"fillAlphas": 1,
"lineAlpha": 0.1,
"type": "column",
"valueField": "number"
},{
"bullet": "square",
"bulletBorderAlpha": 1,
"bulletBorderThickness": 1,
"dashLengthField": "dashLength",
"legendValueText": "[[value]]",
"title": "duration",
"fillAlphas": 0,
"valueField": "duration",
"valueAxis": "durationAxis"
}],
"depth3D": 20,
"angle": 30,
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryField": "date",
"categoryAxis": {
"gridPosition": "start",
"labelRotation": 0
},
"export": {
"enabled": true
}
});
In this case i dont want to show the last item of the array because number is 0, i shouldnt create a new array for reasons project.
Thanks in advance
Not showing a graph object when a value is 0 is pretty much impossible without modifying the array due to the bullets of the line chart (you can hide a column using alphaField, but you can't remove the bullet). You can write an init handler that nulls out zero values so that the chart doesn't show the point or column at all upon chart initialization:
//Nulls out any field that contains a zero, effectively hiding the point/column from the chart.
//Note that the category will still be visible if both points are null unless you null out that category as well.
AmCharts.addInitHandler(function(chart) {
var valueFields = chart.graphs.map(function(graph) {
return graph.valueField;
});
chart.dataProvider.forEach(function(dataItem) {
valueFields.forEach(function(valueField) {
if (dataItem[valueField] === 0) {
dataItem[valueField] = null;
}
})
})
}, ["serial"]);
Note that this will effect the data export (csv, xlsx, json) as well. If you want to re-add those zero values to the data export, you can use the processData callback in the export plugin to modify your data to re-add the zeroes:
"export": {
"enabled": true,
//re-add nulled out values as zeroes for data export:
"processData": function(data, cfg) {
var valueFields = this.setup.chart.graphs.map(function(graph) {
return graph.valueField;
});
data.forEach(function(dataItem) {
valueFields.forEach(function(valueField) {
if (dataItem[valueField] == null) {
dataItem[valueField] = 0;
}
});
});
return data;
}
}
Demo
The following is the function used to generate a pie chart. Everything is working fine, except for the addLabel parameter.
graphSentiChart:function(graphData) {
if(graphData.length < 1){
$('.dataContentStatsPie').html('No data available')
}
// $(".dataContentAllPie").empty();
var piechart = AmCharts.makeChart("chartPie", {
"type": "pie",
"theme": "light",
"autoMargins": true,
"marginTop": 0,
"marginBottom": 10,
"marginLeft": 0,
"marginRight": 0,
"dataProvider": graphData,
"titleField":"key",
"valueField": "value",
"addLabel": (0, 25, 'Total Tweets= 360'),
"startDuration":0,
"responsive": {
"enabled":true
},
"legend":{
"autoMargins":false,
"marginLeft":20,
"enabled": true,
"spacing":20,
"markerType":"circle",
"horizontalGap" :20,
},
"labelsEnabled":false,
//"balloonText": "[[title]]<br><span style='font-size:14px'><b>[[value]]</b> ([[percents]]%)</span>",
"colorField": "color",
"innerRadius": "60%",
"export": {
"enabled": true,
"libs": {
"path": "http://amcharts.com/lib/3/plugins/export/libs/"
}
}
});
What I have given in the addLabel parameter is not being taken and the label is also not getting shown. Can anybody help me on this?
There is no such property in amCharts addLabel. There is a method, which can be used to add labels to an already existing chart object.
To specify labels in the JSON config of the chart, use allLabels:
"allLabels": [{
"x": 0,
"y": 25,
"text": "Total Tweets= 360"
}]
I'm trying to load data using dataLoader to build the chart (Amcharts)
and for that i'm calling a method from controller(APS.NET MVC web application) that return a JSON data, the data contain a date and i think this is causing the problem
this is the method that return JSON:
[HttpGet]
public JsonResult DataStatSum()
{
string dossier = Session["Dossier"].ToString();
string societe = Session["Societe"].ToString();
int userId = Int32.Parse(Session["USER_ID"].ToString());
List<Report_DrillDownSum_Result> l = db.Report_DrillDownSum(dossier,societe, 62, 353, 354).ToList();
var jsonn = new JavaScriptSerializer().Serialize(l);
var json = Newtonsoft.Json.JsonConvert.SerializeObject(l);
return Json(json, JsonRequestBehavior.AllowGet);
}
and this is javascript code (chart configuration):
<script src="~/js/jquery-1.11.0.min.js"></script>
<script src="~/js/amchratsV3.17.2/amcharts/amcharts.js"></script>
<script src="~/js/amchratsV3.17.2/amcharts/serial.js"></script>
<script src="~/js/amchratsV3.17.2/amcharts/plugins/dataloader/dataloader.js"></script>
<script src="~/js/amchratsV3.17.2/amcharts/themes/light.js"></script>
#*<script src="~/js/date.format.js"></script>*#
<script type="text/javascript">
AmCharts.makeChart("chartdiv",
{
"type": "serial",
"dataLoader":
{
"url": "/ChartStat/DataStatSum",
"format": "json"
},
"categoryField": "JourD",
"dataDateFormat": "YYYY-MM-DD",
"angle": 30,
"depth3D": 30,
"startDuration": 1,
"fontSize": 14,
"handDrawn": true,
"handDrawScatter": 4,
"theme": "light",
"categoryAxis": {
"gridPosition": "start",
"parseDates": true
},
"trendLines": [],
"graphs": [
{
"balloonText": "[[title]] : [[value]] km",
"fillAlphas": 1,
"id": "AmGraph-1",
"title": "Athlete 1",
"type": "column",
"valueField": "ValDim1"
},
{
"balloonText": "[[title]] : [[value]] km",
"fillAlphas": 1,
"id": "AmGraph-2",
"title": "Athlete 2",
"type": "column",
"valueField": "ValDim2"
}
],
"guides": [],
"valueAxes": [
{
"id": "ValueAxis-1",
// "title": "Axis title"
}
],
"allLabels": [],
"balloon": {},
"legend": {
"useGraphSettings": true
},
"titles": [
{
"id": "Title-1",
"size": 15,
"text": "Distance parcourue (km)"
}
],
})
actually i get the error when i put "dataDateFormat": "YYYY-MM-DD" .
JSON data looks like :
"[{\"JourD\":\"2015-09-01\",\"ValDim1\":17126.0,\"ValDim2\":18080.0},{\"JourD\":\"2015-09-08\",\"ValDim1\":16960.0,\"ValDim2\":18000.0},{\"JourD\":\"2015-09-15\",\"ValDim1\":17880.0,\"ValDim2\":18075.0}]"
i get this error in google chrome console when i try to display the chart:
Uncaught TypeError: Cannot read property 'toString' of undefined.
changing my method to this solve the problem, cause i dont need to convert the object to JSON string
[HttpGet]
public JsonResult DataStatSum()
{
string dossier = Session["Dossier"].ToString();
string societe = Session["Societe"].ToString();
int userId = Int32.Parse(Session["USER_ID"].ToString());
List<Report_DrillDownSum_Result> l = db.Report_DrillDownSum(dossier,societe, 62, 353, 354).ToList();
return Json(l, JsonRequestBehavior.AllowGet);
}
I'm trying to build a Gantt chart based on amcharts. I will probably have only one item per line though, so I tried with the sample _JSON_ganttDateBased but when I leave only one item per row (John, Smith and Ben only have one task each), the X axis reverts to time instead of date.
I looked into floating bar as a possible way around but I'm not sure I can put dates on the axis.
Thanks
This happens because the total time span is small and there's plenty of space to put grid lines / labels on X axis. So the chart reverts to lines.
This can be easily resolved by enforcing the granularity for your value axis to daily:
"valueAxis": {
"type": "date",
"minPeriod": "DD"
}
That should revert your axis increments back to days.
Here's a working example:
var chart = AmCharts.makeChart( "chartdiv", {
"type": "gantt",
"period": "DD",
"valueAxis": {
"type": "date",
"minPeriod": "DD"
},
"brightnessStep": 10,
"graph": {
"fillAlphas": 1,
"balloonText": "[[open]] - [[value]]"
},
"rotate": true,
"categoryField": "category",
"segmentsField": "segments",
"dataDateFormat": "YYYY-MM-DD",
"startDateField": "start",
"endDateField": "end",
"dataProvider": [ {
"category": "John",
"segments": [ {
"start": "2015-01-02",
"end": "2015-01-03"
} ]
}, {
"category": "Smith",
"segments": [ {
"start": "2015-01-01",
"end": "2015-01-02"
} ]
}, {
"category": "Ben",
"segments": [ {
"start": "2015-01-06",
"end": "2015-01-09"
} ]
} ],
"chartCursor": {
"valueBalloonsEnabled": false,
"cursorAlpha": 0,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true
},
"chartScrollbar": {
}
} );
<script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="http://www.amcharts.com/lib/3/serial.js"></script>
<script src="http://www.amcharts.com/lib/3/gantt.js"></script>
<div id="chartdiv" style="width: 100%; height: 400px;"></div>
Is it possible to reverse the category axis of a time-based chart in amcharts? I know that the value axis can be easily flipped but I've not seen a solution for the category axis. I need to have the most relevant and therefore recent data on the left.
I'm using a time-based area chart. Here's a demo: http://jsfiddle.net/N5rpu/1/
In the example I've reversed the value axis and done the same to the category axis just to show that nothing happens.
var chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "none",
"pathToImages": "http://www.amcharts.com/lib/3/images/",
"dataProvider": chartData,
"valueAxes": [{
"position": "left",
"title": "Unique visitors",
"reversed": true
}],
"graphs": [{
"fillAlphas": 0.4,
"valueField": "visits"
}],
"chartScrollbar": {},
"chartCursor": {
"categoryBalloonDateFormat": "JJ:NN, DD MMMM",
"cursorPosition": "mouse"
},
"categoryField": "date",
"categoryAxis": {
"minPeriod": "mm",
"parseDates": true,
"reversed": true
}
});
In fact I had the opposite problem - dates in the AmCharts categoryAxis where being displayed in reverse from chronological order!
This was achieved by ordering the dates from most recent to less recent in the dataProvider array, i.e.
"dataProvider": [{
"value": 74,
"date": "2014-11-16"
},
{
"value": 73,
"date": "2014-11-15"
},
{
"value": 70,
"date": "2014-11-14"
}];