Amcharts Map, how to make default zoom to Asia continent - amcharts

How to make default zoom to Asia continent when page loads. in Amcharts map

You can set the zoomLatitude, zoomLongitude and zoomLevel in your map dataProvider to the default position and zoom level you want the map to be on load.
Example below:
var map = AmCharts.makeChart("chartdiv", {
"type": "map",
"theme": "light",
"dataProvider": {
"map": "continentsLow",
"zoomLatitude": 47.8936,
"zoomLongitude": 115.6176,
"zoomLevel": 2,
"getAreasFromMap": true,
"areas": [{
"id": "asia",
"showAsSelected": true
}]
},
"areasSettings": {
"autoZoom": false,
"selectedColor": "#CC0000"
}
});
<script src="https://www.amcharts.com/lib/3/ammap.js"></script>
<script src="https://www.amcharts.com/lib/3/maps/js/continentsLow.js"></script>
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv" style="width:100%; height: 250px"></div>

Related

How to display plotBands by date on a Kendo chart?

I have been trying to add plotBands by date on a kendo chart as in the snippet. plotBands doesn't seems to be at the correct position.
Note the TimeWindows object at the snippet. It should start after the first point.
tideSet is the object with Tides and TideWindows collections
How can I configure plotBands in the correct positions?
var tideSet={
"Tides":[
{
"timeStamp":"2018-07-24T00:33:00",
"pred":0.660
},
{
"timeStamp":"2018-07-24T06:09:00",
"pred":6.350
},
{
"timeStamp":"2018-07-24T12:32:00",
"pred":0.400
},
{
"timeStamp":"2018-07-24T18:51:00",
"pred":7.410
},
{
"timeStamp":"2018-07-25T01:19:00",
"pred":0.570
},
{
"timeStamp":"2018-07-25T06:58:00",
"pred":6.380
}
],
"TideWindows":[
{
"WindowsStart":"2018-07-24T02:03:00",
"WindowEnd":"2018-07-24T08:39:00"
}
]
};
var plots = new Array();
for (var i = 0; i < tideSet.TideWindows.length; i++) {
plots.push(
{
from: new Date(tideSet.TideWindows[i].WindowsStart),
to: new Date(tideSet.TideWindows[i].WindowEnd),
color: "#007eff"
});
}
$("#kendoChartTides").kendoChart({
dataSource: {
data: tideSet.Tides,
schema: {
model: {
fields: {
pred: { type: "string" },
timeStamp: { type: "date" }
}
}
}
},
series: [{
type: "line",
style: "smooth",
field: "pred",
categoryField: "timeStamp"
}],
title: {
text: "Tides"
},
valueAxis: {
title: {
text: "Predictions"
}
},
categoryAxis: {
field: "timeStamp",
type: "date",
labels: {
rotation: 40,
template: "#= kendo.format('{0:dd/HH:mm}', new Date(value)) #"
},
baseUnit:"minutes",
baseUnitStep: "auto",
plotBands: plots
},
tooltip:
{
visible: true,
template: "#= kendo.format('{0:dd/HH:mm}', new Date(category)) # <br /> Value: #= value # "
}
});
<link href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script></head>
<div id="kendoChartTides"> </div>
This happens because the plot bands are aligned to the category axis' steps. You currently have your chart's baseUnitStep to "auto". This causes the steps to be too far apart and your plot bands get "rounded" to the nearest steps, so to speak. Here's what you can do to work around this problem:
Change the baseUnitStep to 1. This will give you a precision of 1
minute for your plot bands. However this will also result in grid
lines and axis labels at an interval of 1 minute, which will be slow
and look horrible. We'll fix that in the following steps.
Add a step value of 180 (or similar) to your labels' config. This will make the
category labels appear every 3 hours.
Add a majorGridLines configuration section and set the step of the grid lines to 180, so that they appear as frequently as the labels.
Add a majorTicks config section and set the step interval to 60 or something.
Your categoryAxis config section should look similar to this:
categoryAxis: {
field: "timeStamp",
type: "date",
labels: {
rotation: 40,
template: "#= kendo.format('{0:dd/HH:mm}', new Date(value)) #",
step: 180
},
baseUnit:"minutes",
baseUnitStep: 1,
plotBands: plots,
majorTicks: {
step: 60
},
majorGridLines: {
visible: true,
step: 180
}
}
You can see your code snippet with these changes on this dojo: https://dojo.telerik.com/EFEjezoR

Amchart doesn't show up when listed with html <select> tag

My previous issue was to get json data attached to amcharts, after struggling for a while, I got it running the way I want. But when I move it from test page to page where it would be listed with other charts it doesn't seem to work. When I click on blank chart this error appears in the console
Uncaught TypeError: Cannot read property 'length' of undefined
at Object.xToIndex (serial.js:14)
at b.handleCursorMove (serial.js:8)
at Object.a.inherits.b.fire (amcharts.js:1)
at Object.dispatchMovedEvent (amcharts.js:27)
at Object.handleMouseDown (amcharts.js:26)
at b.handleMouseDown (serial.js:1)
at HTMLDivElement.<anonymous> (amcharts.js:18)
Below is the code which is working when I have it on separate page
var chart = AmCharts.makeChart("chart1", {
"type": "serial",
"dataLoader": {
"url": "#myURL"
},
"valueAxes": [{
"title": "Load Average",
"gridColor": "#FFFFFF",
"gridAlpha": 0.2,
"dashLength": 0
}],
"gridAboveGraphs": true,
"startDuration": 1,
"graphs": [{
"balloonText": "[[title]] of [[category]]:[[value]]",
"id": "AmGraph-1",
"lineThickness": 3,
"valueField": "LoadAverage"
}],
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryField": "EndTimeLoop",
"categoryAxis": {
"title": "End Time Loop",
"gridPosition": "start",
"gridAlpha": 0,
"tickPosition": "start",
"tickLength": 20,
"labelRotation": 90
}
});
function setDataSet(dataset_url) {
AmCharts.loadFile(dataset_url, {}, function(data) {
chart.dataProvider = AmCharts.parseJSON(data);
chart.validateData();
});
};
this is the part where select happens in html side
<div class="chartWrapper" id="chartSingleTest1">
<select onchange="showChart(this.options[this.selectedIndex].value);">
<option value="chart1">Chart #1</option>
<option value="chart2">Chart #2</option>
<option value="chart3">Chart #3</option>
</select>
<div id="chart1" class="chartBoxSingle" style="display: none;"></div>
<div id="chart2" class="chartBoxSingle" style="display: none;"></div>
<div id="chart3" class="chartBoxSingle" style="display: none;"></div>
</div>
and here is js part where selects the first option on page load
var currentChart;
function showChart( divid ) {
if (currentChart !== undefined)
currentChart.style.display = "none";
if ( divid ) {
currentChart = document.getElementById(divid);
currentChart.style.display = "block";
}
else {
currentChart = undefined;
}
}
$(document).ready(function() { showChart('chart1'); });
You have to call the chart object's validateSize method when toggling the display of a chart from none to block as shown in this example that uses tabs. Here's another example using your structure:
var charts = {};
charts["chart1"] = AmCharts.makeChart("chart1", {
type: "serial",
dataProvider: [{
"value": 1,
"category": "Category 1"
}, {
"value": 2,
"category": "Category 2"
}, {
"value": 3,
"category": "Category 3"
}],
categoryField: "category",
graphs: [{
valueField: "value",
type: "column",
fillAlphas: .8
}]
});
charts["chart2"] = AmCharts.makeChart("chart2", {
type: "pie",
dataProvider: [{
"value": 2,
"title": "Slice 1"
}, {
"value": 2,
"title": "Slice 2"
}, {
"value": 2,
"category": "Slice 3"
}],
titleField: "title",
valueField: "value"
});
var currentChart;
function showChart(divid) {
if (currentChart !== undefined)
currentChart.style.display = "none";
if (divid) {
currentChart = document.getElementById(divid);
currentChart.style.display = "block";
charts[divid].validateSize();
} else {
currentChart = undefined;
}
}
$(document).ready(function() {
showChart('chart1');
});
.chartBoxSingle {
width: 100%;
height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/serial.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/pie.js"></script>
<div class="chartWrapper" id="chartSingleTest1">
<select onchange="showChart(this.options[this.selectedIndex].value);">
<option value="chart1">Chart #1</option>
<option value="chart2">Chart #2</option>
</select>
<div id="chart1" class="chartBoxSingle" style="display: none;"></div>
<div id="chart2" class="chartBoxSingle" style="display: none;"></div>
</div>

how can i set custom color of data in amCharts

I have a stanadart data form form my graphics.
var data = [
{"product": "Laptop", "sellOfMonth": 250},
{"product": "Phone", "sellOfMonth": 1250},
{"product": "Comupter", "sellOfMonth": 20}
];
Fro thi data my data values are sellOfMonth property. And I have a new array for style of this data like this:
var styles = [{"name":"sellOfMonth", "color": "#123"}];
This style will be color of column chart.
If my data is stacked:
var data = [
{"product": "Laptop", "sellOfMonth": 250, "sellOfYear": 2500},
{"product": "Phone", "sellOfMonth": 1250, "sellOfYear": 1500},
{"product": "Comupter", "sellOfMonth": 20,, "sellOfYear": 200}
];
and style array is:
var styles = [
{"name":"sellOfMonth", "color": "#123"},
{"name":"sellOfYear", "color": "#dfc"}
];
So I can create an amchart and set dataProvider as my data array.
But I could not set the colors.
Looking at how your styles are set up, you can easily use that to create your graphs array and set each graph's fillColors property to the desired color.
var graphs = styles.map(function(style) {
return {
"type": "column",
"valueField": style.name,
"fillColors": style.color,
"lineColor": style.color,
"fillAlphas": .8
};
});
From there you can assign your graphs array to makeChart or the object's graphs array if you're using the library's class-based methods.
Demo below:
var styles = [
{"name":"sellOfMonth", "color": "#123"},
{"name":"sellOfYear", "color": "#dfc"}
];
var graphs = styles.map(function(style) {
return {
"type": "column",
"valueField": style.name,
"fillColors": style.color,
"lineColor": style.color,
"fillAlphas": .8
};
});
var data = [
{"product": "Laptop", "sellOfMonth": 250, "sellOfYear": 2500},
{"product": "Phone", "sellOfMonth": 1250, "sellOfYear": 1500},
{"product": "Comupter", "sellOfMonth": 20, "sellOfYear": 200}
];
var chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "light",
"valueAxes": [{
"stackType": "regular"
}],
"dataProvider": data,
"graphs": graphs,
"categoryField": "product"
});
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/serial.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>

Why won't my amChart serial chart render if the config includes the categoryAxis property?

I have a chart that refuses to render properly if I include the categoryAxis property in the chart options. By "render properly", I mean that the plot area shows up, the title is displayed, but none of the columns are rendered.
I am using an AmCharts serial chart with GrantMStevens amChartsDirective because my project is built in Angularjs.
Here is a plunk with the categoryAxis commented out. If you enable that line of code, the chart will immediately exhibit this behavior.
This chart uses text values for the categoryField and numeric vlaues for the valueField. I have another chart that uses date values for the categoryField and numeric values for the valueField and it works just fine.
I am assuming that there some interaction between the fact that this a not a categoryField is not a date value that causes this but I cannot find any combination of properties that lets me set properties on the categoryField.
This is what I WANT to do:
categoryAxis: {
gridAlpha: 0.3,
gridColor: "GRAY"
},
Does anyone know why this doesn't work?
Here is the HTML:
<html ng-app="amChartsDirectiveExample">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<div ng-controller="amChartsController2" style="height: 400px; width: 600px;">
<am-chart id="mySecondChart" options="amChartOptions2"></am-chart>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.0/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/amcharts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/serial.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/themes/light.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/themes/chalk.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/themes/black.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/themes/dark.js"></script>
<script src="https://rawgit.com/ThumbsAlmighty/amCharts-Angular/master/dist/amChartsDirective.js"></script>
<script src="script.js"></script>
<script src="theme.js"></script>
</body>
And here is the JavaScript:
angular.module('amChartsDirectiveExample', ['amChartsDirective'])
.controller('amChartsController2', function($scope) {
$scope.chartData = [
{
"EscalationCount": "2",
"Area": "One"
},
{
"EscalationCount": "9",
"Area": "Two"
},
{
"EscalationCount": "5",
"Area": "Three"
},
{
"EscalationCount": "4",
"Area": "Four"
},
{
"EscalationCount": "3",
"Area": "Five"
}];
$scope.amChartOptions2 = {
type: "serial",
categoryField: "Area",
startDuration: 1,
rotate: true,
theme: "light",
trendLines: [],
//categoryAxis: {}, // Uncomment this line to break the chart.
graphs: [{
balloonText: "[[title]] for [[category]]: [[value]]",
fillAlphas: 1,
id: "AmGraph-1",
title: "Escalation Volume",
type: "column",
valueField: "EscalationCount"
}],
guides: [],
valueAxes: [{
id: "ValueAxis-1",
title: "EscalationCount",
}],
allLabels: [],
balloon: [],
legend: {
enabled: false
},
titles: [{
id: "Title-1",
size: 15,
text: "Lookit me! I rendered the Chart title!"
}],
data: $scope.chartData
};
});
For some reason the angular directive sets parseDates to true by default if you have a categoryAxis defined, which breaks if your chart isn't date-based. If you set parseDates: false in your categoryAxis, it will work.
categoryAxis: {
parseDates: false,
gridAlpha: 0.3,
gridColor: "#d3d3d3"
},
Here's your updated plunk: http://plnkr.co/edit/TYZdR0KEOAKcbHnGdTfP?p=preview
Note, I changed your gridColor to the hex equivalent. While named colors will work, if you plan on using the export plugin, you'll need to set your colors as a hex string.

Kendo chart performance issue

I am working on kendo chart. I am loading 30k data on the chart.
You can see in the code I have attached that, when I zoom in and out with mouse scroll, the process becomes very slow. Is it possible to reduce time of execution for each processes? And also first time loading of the chart is also very slow.
I want to know that is 30k data on Kendo chart should be loaded? Is there any limit that Kendo has set for data loading on the chart?
var Chartdata = [];
function createChart() {
$("#chart").kendoChart({
dataSource: {
data: Chartdata
},
series: [{
type: "scatterLine",
xField: "date",
yField: "close"
}, {
type: "scatterLine",
xField: "date",
yField: "volume"
}, {
type: "scatterLine",
xField: "date",
yField: "high"
}, {
type: "scatterLine",
xField: "date",
yField: "low"
}, {
type: "scatterLine",
xField: "date",
yField: "open"
}, {
type: "scatterLine",
xField: "date",
yField: "symbol"
}],
xAxis: {
name: "Date",
baseUnit: "minutes",
BaseUnitSteps: {
second: [1]
},
labels: {
visible: true,
step: 50,
font: "8px Arial,Helvetica,sans-serif",
template: "#= kendo.toString(new Date(value), 'MM/dd/yyyy HH:mm:ss') #"
},
majorUnit: 1,
majorTickType: "none",
majorGridLines: {
step: 5,
},
minorGridLines: {
visible: true,
step: 1,
},
minorTickType: "none",
majorTickType: "none",
},
yAxis: {
majorUnit: 25,
majorTickType: "none",
majorGridLines: {
step: 1,
},
minorGridLines: {
visible: true,
step: 1,
},
minorTickType: "none",
majorTickType: "none",
},
transitions: false,
zoomable: {
mousewheel: {
lock: "y"
},
selection: {
lock: "y"
}
},
zoom: setRange,
}).data("kendoChart");
}
function setRange(e) {
var chart = e.sender;
var options = chart.options;
e.originalEvent.preventDefault();
var xRange = e.axisRanges.Date;
if (xRange) {
var xMinonzoom = xRange.min;
var xMaxonzoom = xRange.max;
var dMaxonzoom = new Date(xMaxonzoom.getYear(), xMaxonzoom.getMonth(), xMaxonzoom.getDay(), xMaxonzoom.getHours(), xMaxonzoom.getMinutes(), xMaxonzoom.getSeconds());
var dMinonzoom = new Date(xMinonzoom.getYear(), xMinonzoom.getMonth(), xMinonzoom.getDay(), xMinonzoom.getHours(), xMinonzoom.getMinutes(), xMinonzoom.getSeconds());
var diff = dMaxonzoom - dMinonzoom;
if (xMaxonzoom - xMinonzoom < 10) {
return;
}
options.xAxis.min = xMinonzoom;
options.xAxis.max = xMaxonzoom;
chart.refresh();
}
}
$(document).ready(function() {
$.ajax({
type: "GET",
cache: true,
url: "https://api.myjson.com/bins/1uan0",
async: false
}).success(function(result) {
var dataresult = result;
$(dataresult).each(function(e, data) {
Chartdata.push({
"date": new Date(Date.parse(data.date)),
"close": data.close,
"volume": data.volume,
"high": data.high,
"low": data.low,
"open": data.open,
"symbol": data.symbol
});
});
createChart();
});
});
#chart circle {
display: none;
}
<link href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.mobile.all.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://kendochart.webashlar.com/kendochart/Javascripts/kendo.all.min.js"></script>
<div id="chart"></div>
Thank you
I have created a dojo for you so hopefully this points you to the right direction.
Chart Dojo
All I have done is added in some simple filtering so that based on the min and max zoom you have selected for the grid it will only call those items into the datasource for you rather than the entire dataset.
This is achieved via this bit of code:
var datasource = chart.dataSource;
console.log("DataSource Total before Filtering is:: " + datasource.total());
datasource.filter();
datasource.filter([{field:"date", operator:"gte",value : xMinonzoom }, {field:"date", operator: "lte", value:xMaxonzoom}]);
console.log("DataSource Total after Filtering is:: " + datasource.total());
So this shows you the effect the filtering is having on the data source you are returning back.
If you wanted to speed things up further you could potentially look at grouping for larger data sets i.e. when you first load the grid up as the data to me at that point is just noise (in my opinion) and is not really meaningful to me (but it maybe in your use case).
Think how mapping works with instances zoomed out summarized as a number rather than trying to show all the individual data points until you start zooming in and seeing the data individually.
If you need more info then let me know and I will expand the answer/ provide more info if I can.

Resources