Related
I am in the situation where people can choose between many different time intervals like
1d (5minute data)
1year (1day data)
If I put this in "groupToPeriods": ["DD"] it will display the days perfectly when it is etc 1-year data.
If I put this in "groupToPeriods": ["NN"] it will display the minutes perfectly when it is etc 1-day data.
Days
Minutes
How do I make it work both with NN and DD at the same time? should I automatically put in either NN or DD depending on which type of data I provide? This is not the case in one of the other sample charts I've tried there it did it automatically, however, that was not one of the stock charts, but normal charts.
I tried this "groupToPeriods": ["DD-NN"] and "groupToPeriods": ["DD", "NN"] without any luck, here and here is some documentation ive read about grouping and date formatting.
var redaw = false;
var logarithmic = false;
var interval = "all";
function createChart1(chartData) {
var chart = AmCharts.makeChart("chartdivs", {
"type": "stock",
"theme": "light",
"recalculateToPercents": "never",
"dataSets": [{
"title": "$",
"fieldMappings": [{
"fromField": "value",
"toField": "value"
}, {
"fromField": "volume",
"toField": "volume"
}],
"dataProvider": chartData,
"categoryField": "date",
"color": "#2e4259",
"fillAlphas": 0.5
}],
"panels": [{
"title": "Fiat",
"showCategoryAxis": false,
"percentHeight": 70,
"color": "#fff",
"recalculateToPercents": "never",
"stockGraphs": [{
"id": "g1",
"valueField": "value",
"comparable": true,
"lineThickness": "3px",
"compareField": "value",
"balloonText": "[[title]]:<b>[[value]]</b>",
"compareGraphBalloonText": "[[title]]:<b>[[value]]</b>",
"color": "#fff"
}]
}, {
"title": "Volume",
"percentHeight": 30,
"color": "#fff",
"stockGraphs": [{
"valueField": "volume",
"type": "line",
"showBalloon": false,
"fillAlphas": 0.5
}],
"stockLegend": {
"periodValueTextRegular": "[[value.close]]",
"marginRight": 10,
"color": "#fff"
}
}],
"panelsSettings": {
// "color": "#fff",
"plotAreaBorderAlpha": 0.5,
"plotAreaBorderColor": "#2e4259",
"marginLeft": 30,
"marginRight": 30,
"marginTop": 5,
"marginBottom": 30
},
"categoryAxesSettings": {
"equalSpacing": true,
"gridColor": "#2e4259",
"gridAlpha": 0.5,
"maxSeries": 1,
//////////////////////////////////// HERE IS THE PROBLEM ////////////////////////////////////
"groupToPeriods": ["DD-NN"]
},
"valueAxesSettings": {
"logarithmic": logarithmic,
"gridColor": "#2e4259",
"gridAlpha": 0.5,
"inside": false,
"showLastLabel": false
},
"chartScrollbarSettings": {
"graph": "g1",
// "graphFillColor": "#000",
"backgroundColor": "transparent",
"gridAlpha": 0,
"graphFillAlpha": 0.8,
"graphLineAlpha": 0,
"graphLineColor": "#fff",
"graphType": "line",
"updateOnReleaseOnly": false,
"graphFillColor": "#2e4259",
"selectedBackgroundColor": "#2e4259",
"selectedGraphFillAlpha": 0,
"selectedGraphFillColor": "#2e4259"
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"fullWidth": false,
"cursorAlpha": 0.5,
"valueLineBalloonEnabled": false,
"valueLineEnabled": false,
"cursorColor": "#000"
}
});
redaw === true ? chart.validateData() : redaw = true;
}
function generateChartData() {
var chartData1 = [];
// current date
var firstDate = new Date();
// now set 500 minutes back
firstDate.setMinutes(firstDate.getDate() - 1000);
var CSRFToken = document.getElementById("CSRFToken").value;
var parameters = "CSRFToken=" + CSRFToken + "&interval=" + interval + "&id=" + 1;
console.log("INTERVAL: " + interval);
ajax("/pages/ajax/request-chart-data.php", parameters, "POST", false, function(results) {
if (results) {
var jsonObj = JSON.parse(results);
console.log("JSON OBJ");
console.log(jsonObj);
for (var i in jsonObj) {
var newDate = new Date(jsonObj[i].date);
chartData1.push({
"date": newDate,
"value": jsonObj[i].price,
"volume": jsonObj[i].volume
});
}
createChart1(chartData1);
} else {
console.log("NO RESULTS");
}
});
}
generateChartData();
No, this isn't possible. groupToPeriods groups data based on whatever your maxSeries is set to in period ascending order; using the default value as an example, - first it starts with seconds (ss), then 10 seconds (10ss), 30 seconds (30ss), then minutes (mm), 10 minutes (10mm), 30 minutes (30mm) then days (DD), weeks (WW), months (MM) then years (YYYY). You can't combine multiple periods in one grouping, so in your case, with your extremely small maxSeries setting, set it to the smallest period you want to group to based on your data. Also note that there is no NN period - it's mm for minutes. You also need to set an appropriate minPeriod as well, which also takes a single period type, to ensure that your data is rendered correctly as well.
Is there a way to add last values in the graph to the legend names when not hover over the AmCharts graph ?
Here is a code pen with a demo chart.
https://codepen.io/anon/pen/LxmLaL
Here is the js code
var chartData = generateChartData();
var chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "light",
"legend": {
"periodValueText":"last"
},
"dataProvider": chartData,
"synchronizeGrid":true,
"valueAxes": [{
"id":"v1",
"axisColor": "#FF6600",
"axisThickness": 2,
"axisAlpha": 1,
"position": "left"
}, {
"id":"v2",
"axisColor": "#FCD202",
"axisThickness": 2,
"axisAlpha": 1,
"position": "right"
}, {
"id":"v3",
"axisColor": "#B0DE09",
"axisThickness": 2,
"gridAlpha": 0,
"offset": 50,
"axisAlpha": 1,
"position": "left"
}],
"graphs": [{
"valueAxis": "v1",
"lineColor": "#FF6600",
"bullet": "round",
"bulletBorderThickness": 1,
"hideBulletsCount": 30,
"title": "red line",
"valueField": "visits",
"fillAlphas": 0
}, {
"valueAxis": "v2",
"lineColor": "#FCD202",
"bullet": "square",
"bulletBorderThickness": 1,
"hideBulletsCount": 30,
"title": "yellow line",
"valueField": "hits",
"fillAlphas": 0
}, {
"valueAxis": "v3",
"lineColor": "#B0DE09",
"bullet": "triangleUp",
"bulletBorderThickness": 1,
"hideBulletsCount": 30,
"title": "green line",
"valueField": "views",
"fillAlphas": 0
}],
"chartScrollbar": {},
"chartCursor": {
"cursorPosition": "mouse"
},
"categoryField": "date",
"categoryAxis": {
"parseDates": true,
"axisColor": "#DADADA",
"minorGridEnabled": true
}
});
chart.addListener("dataUpdated", zoomChart);
zoomChart();
// generate some random data, quite different range
function generateChartData() {
var chartData = [];
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 100);
for (var i = 0; i < 100; i++) {
// we create date objects here. In your data, you can have date strings
// and then set format of your dates using chart.dataDateFormat property,
// however when possible, use date objects, as this will speed up chart rendering.
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var visits = Math.round(Math.sin(i * 5) * i);
var hits = Math.round(Math.random() * 80) + 500 + i * 3;
var views = Math.round(Math.random() * 6000) + i * 4;
chartData.push({
date: newDate,
visits: visits,
hits: hits,
views: views
});
}
return chartData;
}
function zoomChart(){
chart.zoomToIndexes(chart.dataProvider.length - 20, chart.dataProvider.length - 1);
}
I believe it has something to do with periodValueText but I'm unable to figure out how to achieve the same. Any help would be appreciated.
You have correctly pointed out that periodValueText needs to be used. You just need to use double-bracketed meta codes in it. For close value it's [[value.close]]:
"legend": {
"periodValueText":"[[value.close]]"
}
I would like to include guides into my amcharts graphs and I found very descriptive examples. However I'm struggling with positioning of label text, especially in case when guides are so close that labels overlap.
Here is example code https://jsfiddle.net/Tripy/1wwygcy7/2/
HTML:
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/amstock.js"></script>
<div id="chartdiv" style="width: 100%; height: 500px;"></div>
Javascript:
var chartData = weekendGuides = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate( firstDate.getDate() - 200 );
firstDate.setHours( 0, 0, 0, 0 );
for ( var i = 0; i < 200; i++ ) {
var newDate = new Date( firstDate );
newDate.setDate( newDate.getDate() + i );
var a1 = Math.round( Math.random() * ( 40 + i ) ) + 100 + i;
var b1 = Math.round( Math.random() * ( 1000 + i ) ) + 500 + i * 2;
chartData.push( {
"date": newDate,
"value": a1,
"volume": b1
} );
// add weekend guide
if ( 6 == newDate.getDay() ) {
var toDate = new Date( newDate );
toDate.setDate( newDate.getDate() + 2 );
weekendGuides.push( {
"date": newDate,
"toDate": toDate,
"lineAlpha": 0,
"fillAlpha": 0.05,
"fillColor": "#000",
"expand": true
} );
}
}
}
var chart = AmCharts.makeChart( "chartdiv", {
"type": "stock",
"dataSets": [ {
"title": "first data set",
"fieldMappings": [ {
"fromField": "value",
"toField": "value"
}, {
"fromField": "volume",
"toField": "volume"
} ],
"dataProvider": chartData,
"categoryField": "date"
} ],
"panels": [ {
"showCategoryAxis": false,
"title": "Value",
"percentHeight": 70,
"stockGraphs": [ {
"id": "g1",
"valueField": "value",
"comparable": true,
"compareField": "value",
"balloonText": "[[title]]:<b>[[value]]</b>",
"compareGraphBalloonText": "[[title]]:<b>[[value]]</b>"
} ],
"stockLegend": {
"periodValueTextComparing": "[[percents.value.close]]%",
"periodValueTextRegular": "[[value.close]]"
},
"categoryAxis": {
"guides": weekendGuides
},
"valueAxes": [ {
"guides": [ {
"value": 325,
"lineAlpha": 0.8,
"lineColor": "#0c0",
"label": "Guide #1",
"position": "right"
}, {
"value": 322,
"lineAlpha": 0.8,
"lineColor": "#0c0",
"label": "Guide #2",
"position": "right"
}]
} ]
} ],
"chartScrollbarSettings": {
"graph": "g1"
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"fullWidth": true,
"cursorAlpha": 0.1
},
"periodSelector": {
"position": "bottom",
"periods": [ {
"period": "MM",
"selected": true,
"count": 1,
"label": "1 month"
}, {
"period": "YYYY",
"count": 1,
"label": "1 year"
}, {
"period": "YTD",
"label": "YTD"
}, {
"period": "MAX",
"label": "MAX"
} ]
}
} );
Any idea how to push label text below the guide for guides in case that labels are overlapping. Perhaps with CSS code for class name amcharts-guide-[id]?
There isn't a way to do this through the guide properties properties, but you have the right hunch with the css class name. Set addClassNames to true, give your guides IDs and then add a drawn event listener in your stock panel that adjusts the desired guide(s) directly by calling querySelector on the .amcharts-guide-[id] tspan selector and adjusting the y attribute:
AmCharts.makeChart("chartdiv", {
"addClassNames": true,
// ...
"stockPanels": [{
"valueAxes": [{
"guides": [{
"id": "guide-1",
// ..
}, {
"id": "guide-2",
// ..
}]
}],
"listeners": [{
"event": "drawn",
"method": function() {
var guide2Text = document.querySelector('.amcharts-guide-guide-2 tspan');
if (guide2Text) {
guide2Text.setAttribute('y', 20);
}
}
}]
}],
// ..
});
Updated fiddle
I want to show diamond-shaped icon in my chart. I have created this charts using amCharts.
My present amChart:
And I want to put diamond-shaped icon just like in following image:
Here is my JavaScript code:
function getChart(id) {
var allCharts = AmCharts.charts;
for (var i = 0; i < allCharts.length; i++) {
if (id == allCharts[i].div.id) {
return allCharts[i];
}
}
}
function load_holding_graph(graph_type, history, title, aggregate, industry){
var title_1 = industry[0].ticker + '\n';
var title_2 = industry[0].name;
var title_3 = industry[0].industry + ' . ' + industry[0].sector;
// current day exclude weekends
var current_date = new Date();
switch(current_date.getDay()){
case 0:
var s = new Date(current_date.getTime());
var d = s.setDate(current_date.getDate() - 1);
break;
case 6:
var s = new Date(current_date.getTime());
var d = s.setDate(current_date.getDate() - 2);
break;
default:
var d = current_date;
}
var latest_trading_day = $.datepicker.formatDate('dd MM, yy', d);
// CREATE DATA
var chartData = [];
generateChartData(history);
function generateChartData() {
for (var i = 0; i < history.length; i++) {
var date = new Date(history[i].date);
var val = Math.round(Math.random() * (30) + 100);
chartData[i] = ({
date: date,
open: history[i].open,
close: history[i].close,
high: history[i].high,
low: history[i].low,
volume: history[i].volume,
value: val
});
}
}
// CHART CONFIG
var chartConfig = {
type: "stock",
pathToImages : "/static/img/amcharts/",
addClassNames:true,
dataSets: [{
fieldMappings: [{
fromField: "open",
toField: "open"
}, {
fromField: "close",
toField: "close"
}, {
fromField: "high",
toField: "high"
}, {
fromField: "low",
toField: "low"
}, {
fromField: "volume",
toField: "volume"
}, {
fromField: "val",
toField: "val"
}
],
color: "#fff",
dataProvider: chartData,
title: title,
categoryField: "date",
compared: false,
},
{
fieldMappings: [{
fromField: "value",
toField: "value"
}],
color: "#fff",
dataProvider: chartData,
title: title,
categoryField: "date"
},
],
panels: [{
addClassNames:true,
percentHeight: 75,
valueAxes: [{
id:"v1",
//logarithmic:true,
unit : '$',
unitPosition:"left",
position:"left",
},
{
id:"v2",
unit : '$',
unitPosition:"left",
position:"right",
synchronizeWith: "v1",
synchronizationMultiplier: 1,
},
],
marginBottom: 0,
marginTop: 0,
stockGraphs: [{type: graph_type,
id: "g1",
title:title,
openField: "open",
closeField: "close",
highField: "high",
lowField: "low",
valueField: "close",
lineColor: "#11EDF1",
fillColors: "#11EDF1",
negativeLineColor: "#db4c3c",
negativeFillColors: "#db4c3c",
fillAlphas: 1,
// comparedGraphLineThickness: 2,
columnWidth: 0.4,
useDataSetColors: false,
comparable: true,
compareField: "close",
bullet : "round",
bulletAlpha : 0,
showBalloon: true,
showBalloonAt:"top",
"balloonText":"$[[value]]",
} ],
stockLegend: {
enabled:true,
useGraphSettings:true,
data:[{title: ""}],
// valueTextRegular: undefined,
periodValueTextComparing: "[[percents.value.close]]%",
markerType: "diamond",
backgroundColor :"#ffffff",
markerSize : 24,
position:"top",
},
},
],
panelsSettings: {
color: "#fff",
plotAreaFillColors: "#333",
plotAreaFillAlphas: 1,
marginLeft: 60,
marginRight: 60,
marginTop: 20,
marginBottom: 5,
},
categoryAxesSettings: {
equalSpacing: true,
gridColor: "#555",
gridAlpha: 1,
maxSeries:0,
markPeriodChange:false,
autoGridCount:true,
minHorizontalGap:100,
dateFormats: [{period:'fff',format:'JJ:NN:SS'},
{period:'ss',format:'JJ:NN:SS'},
{period:'mm',format:'JJ:NN'},
{period:'hh',format:'JJ:NN'},
{period:'DD',format:'MMM DD, YYYY'},
{period:'WW',format:'MMM DD'},
{period:'MM',format:'MMM YYYY'},
{period:'YYYY',format:'YYYY'}],
},
valueAxesSettings: {
gridColor: "#555",
gridAlpha: 1,
inside: false,
showLastLabel: true,
},
chartCursorSettings: {
pan: true,
valueLineEnabled:true,
valueLineBalloonEnabled:true,
onePanelOnly:true,
},
legendSettings: {
color: "#fff"
},
stockEventsSettings: {
showAt: "high"
},
balloon: {
textAlign: "left",
offsetY: 10,
},
"export": {
"enabled": true,
"backgroundColor": "#fff",
},
}
AmCharts.charts = [];
// CREATE CHART
var chart = AmCharts.makeChart("holding-graph",chartConfig);
console.log(chart)
}
If your chart never uses data point grouping, either by having few data points or having it disabled, you should go with the bulletField solution #gerric proposed.
If the above does not apply, probably the best course of action is to use Trend lines for that.
A trend line is basically a line from one datetime/value pair to another. However, it can also have an icon attached at its either end, which we can exploit to add a diamond image (we're going to use SVG) at any point of the chart.
Here's an example of a ready-made chart:
var icon = "M256,0L96,256l160,256l160-256L256,0z";
var chartData = [];
var iconDate, iconValue;
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 500);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 500; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var val = Math.round(Math.random() * (40 + i)) + 100 + i;
chartData.push({
date: newDate,
value1: val
});
if (i === 480) {
iconDate = new Date(newDate);
iconDate.setHours(12);
iconValue = val;
}
}
}
var chart = AmCharts.makeChart("chartdiv", {
type: "stock",
"theme": "light",
"dataSets": [{
"fieldMappings": [{
"fromField": "value1",
"toField": "value1"
}, {
"fromField": "value2",
"toField": "value2"
}, {
"fromField": "value3",
"toField": "value3"
}, {
"fromField": "value4",
"toField": "value4"
}],
"dataProvider": chartData,
"categoryField": "date"
}],
"panels": [{
"stockGraphs": [{
"id": "g1",
"title": "Graph #1",
"lineThickness": 2,
"valueField": "value1",
"useDataSetColors": false
}],
"trendLines": [{
"initialValue": iconValue,
"initialDate": iconDate,
"lineAlpha": 1,
"lineColor": "#ff0000",
"initialImage": {
"svgPath": icon,
"color": "#cc0000",
"width": 15,
"height": 25,
"offsetX": -7
},
"finalValue": iconValue,
"finalDate": iconDate
}]
}],
"chartScrollbarSettings": {
"graph": "g1"
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"fullWidth": true,
"cursorAlpha": 0.1,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true,
"valueLineAlpha": 0.5
},
"periodSelector": {
"position": "bottom",
"periods": [{
"period": "MM",
"selected": true,
"count": 1,
"label": "1 month"
}, {
"period": "YYYY",
"count": 1,
"label": "1 year"
}, {
"period": "YTD",
"label": "YTD"
}, {
"period": "MAX",
"label": "MAX"
}]
}
});
<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/amstock.js"></script>
<div id="chartdiv" style="width: 100%; height: 300px;"></div>
If you use bulletField, you can set bullets from within your data. The diamond shape is already provided by AmCharts.These two examples could help you out: fiddle & amDemo
I'm using AmChart to make a serial graph and I want to set a different color for the last category label.
Does somebody know how this is possible?
This my code to create the graph and return validateData().
var chart = AmCharts.makeChart("historyContent", {
"type": "serial",
"theme": "light",
"dataProvider": loadDataProvider(tag),
"valueAxes": [{
"gridColor": "#FFFFFF",
"gridAlpha": 0.2,
"dashLength": 0
}],
"gridAboveGraphs": true,
"graphs": [{
"balloonText": "[[p_type]] | [[p_date]]: <b>[[value]]</b>",
"fillAlphas": 0.8,
"lineAlpha": 0.2,
"type": "column",
"valueField": "value"
}],
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryField": "period",
"categoryAxis": {
"gridPosition": "start",
"gridAlpha": 0,
"tickPosition": "start",
"tickLength": 20,
"labelFunction": function(valueText, serialDataItem, categoryAxis) {
var p_type = valueText.substring(valueText.length - 10, 0);
var p_date = valueText.substring(valueText.length - 10);
console.log(valueText);
valueText = p_type + "\n" + p_date;
return valueText;
}
}
});
return chart.validateData();
In amCharts 4:
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.labels.template.fill = am4core.color("#A0CA92");
See the official codepen example
You can use categoryAxis.labelColorField to specify which field in your data holds the color for category axis labels.
var chart = AmCharts.makeChart("historyContent", {
"type": "serial",
"theme": "light",
"dataProvider": loadDataProvider(tag),
"valueAxes": [{
"gridColor": "#FFFFFF",
"gridAlpha": 0.2,
"dashLength": 0
}],
"gridAboveGraphs": true,
"graphs": [{
"balloonText": "[[p_type]] | [[p_date]]: <b>[[value]]</b>",
"fillAlphas": 0.8,
"lineAlpha": 0.2,
"type": "column",
"valueField": "value"
}],
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryField": "period",
"categoryAxis": {
"labelColorField": "color", // specifies which field in data holds color for label
"gridPosition": "start",
"gridAlpha": 0,
"tickPosition": "start",
"tickLength": 20,
"labelFunction": function(valueText, serialDataItem, categoryAxis) {
var p_type = valueText.substring(valueText.length - 10, 0);
var p_date = valueText.substring(valueText.length - 10);
console.log(valueText);
valueText = p_type + "\n" + p_date;
return valueText;
}
}
});
If you you need to color just the last label, you would set that field on your last data point. I.e.:
[{
period: "First",
value: 100
}, {
period: "Second",
value: 200
}, {
period: "Third",
value: 300
}, {
period: "Last",
value: 400,
color: "#cc0000"
}];
Here's a working example:
http://codepen.io/amcharts/pen/02ffa4178c069262b705abbf17bba5dc