I have a simple amCharts v4 chart with a function that adds some series and axes.
If I call the function from the script, the chart is displayed correctly, but if it is called externally from a button click or timeout, the legend displays but the series and axes do not. Is there something extra that needs to be done if the series is added later?
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.data = generateChartData();
chart.legend = new am4charts.Legend();
chart.cursor = new am4charts.XYCursor();
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 50;
// Create series
function createAxisAndSeries(field, name, opposite, bullet) {
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = field;
series.dataFields.dateX = "date";
series.strokeWidth = 2;
series.yAxis = valueAxis;
series.name = name;
series.tooltipText = "{name}: [bold]{valueY}[/]";
var interfaceColors = new am4core.InterfaceColorSet();
}
var axisAndSeriesList = [];
function addAxisAndSeries(name) {
if (name==="Visits") {
createAxisAndSeries("visits", "Visits", false, "circle");
} else if (name==="Views") {
createAxisAndSeries("views", "Views", true, "triangle");
} else if (name==="Hits") {
createAxisAndSeries("hits", "Hits", true, "rectangle");
} else {
console.warn('what is ' + name +'?');
}
}
// generate some random data, quite different range
function generateChartData() {
var chartData = [];
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 100);
firstDate.setHours(0, 0, 0, 0);
var visits = 1600;
var hits = 2900;
var views = 8700;
for (var i = 0; i < 15; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
visits += Math.round((Math.random()<0.5?1:-1)*Math.random()*10);
hits += Math.round((Math.random()<0.5?1:-1)*Math.random()*10);
views += Math.round((Math.random()<0.5?1:-1)*Math.random()*10);
chartData.push({date: newDate, visits: visits, hits: hits, views: views });
}
return chartData;
}
function addSeries() {
console.log('Add all 3 in the series');
addAxisAndSeries("Visits");
addAxisAndSeries("Views");
addAxisAndSeries("Hits");
}
// These work
// addAxisAndSeries("Visits");
// addAxisAndSeries("Views");
// addAxisAndSeries("Hits");
// This works
// addSeries();
// This does not work
// setTimeout(function(){
// addSeries();
// }, 3000);
// Clicking on "Add series" button does not work (from HTML)
// <input type="button" onclick="addSeries()" value="Add series" />
See sample pen: https://codepen.io/anon/pen/YdYJKy?editors=0011
You were on the right track in your answer:
The series inherit data from the chart, but apparently that ends with the script.
As you've witnessed, when adding a series dynamically, basically the chart doesn't make presumptions whether the asynchronously-added series will have its own data or will use the chart's. To have the chart continue to provide its data to newly-added series, run chart.invalidateData();.
Here's a fork of your demo that adds that to the addSeries() function:
https://codepen.io/team/amcharts/pen/bb863c597a46895f87d2b67534c353f6
Now the function works whether synchronously or asynchronously, whether via setTimeout or via the button.
The series inherit data from the chart, but apparently that ends with the script.
So chart.data might have {date: '2001-01-01', visits: 100, hits: 200, views: 300} and each series can just specify which data element to use. Once the script ends, this apparently no longer applies and each additional series must have its own data.
To get the example to work as expected, I commented out this line:
// chart.data = generateChartData(); /* works with this line, but not needed */
And added the data with each series like this:
var series = chart.series.push(new am4charts.LineSeries());
series.data = generateChartData(); // <---- new line here
series.dataFields.valueY = field;
Updated pen: https://codepen.io/anon/pen/VqyVjr?editors=0011
I'm still not clear why this data flow does not continue, but have something that works. Anyone who can shed light on why, please do.
Related
Hi all I'm using am4charts.XYChart for showing the prices of two different Vendors
The graph is working fine and tooltip of each point is visible only if we hover the cursor over the points in the graph , but my requirement is the tooltip of all the points in the graph should be displayed while the graph is rendered.
It should be displaying all the time without hovering .
I have used the following code to generate the graph .
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/dark.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
dynamic_data_arr = [{date: "2019-02-25", market1: "21.67", sales1: "Amazon", market2: "25.92", sales2: "La Collette"},
{date: "2019-02-26", market1: "21.67", sales1: "Amazon", market2: "25.92", sales2: "La Collette,Co-op"}]
am4core.useTheme(am4themes_dark);
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
chart = am4core.create("amcharts_chartdiv", am4charts.XYChart);
// Add data
// chart.data = [] ;
chart.data = dynamic_data_arr;
// chart.validateData();
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
//dateAxis.renderer.grid.template.location = 0;
//dateAxis.renderer.minGridDistance = 30;
var valueAxis1 = chart.yAxes.push(new am4charts.ValueAxis());
// valueAxis1.title.text = "Sales";
console.log(valueAxis1);
var valueAxis2 = chart.yAxes.push(new am4charts.ValueAxis());
console.log(valueAxis2);
// valueAxis2.title.text = "Market Days";
valueAxis2.renderer.opposite = true;
valueAxis2.renderer.grid.template.disabled = true;
var series3 = chart.series.push(new am4charts.LineSeries());
series3.dataFields.valueY = "market1";
series3.dataFields.dateX = "date";
series3.dataFields.nameX = "sales1";
series3.name = "Amazon";
series3.strokeWidth = 2;
series3.tensionX = 0.7;
series3.yAxis = valueAxis2;
series3.tooltipText = "{nameX}\n[bold font-size: 20]{valueY}[/]";
series3.showBalloon = true;
var bullet3 = series3.bullets.push(new am4charts.CircleBullet());
bullet3.circle.radius = 3;
bullet3.circle.strokeWidth = 2;
bullet3.circle.fill = am4core.color("#fff");
var series4 = chart.series.push(new am4charts.LineSeries());
series4.dataFields.valueY = "market2";
series4.dataFields.dateX = "date";
series4.dataFields.nameX = "sales2";
series4.name = "Local Vendors";
series4.strokeWidth = 2;
series4.tensionX = 0.7;
series4.yAxis = valueAxis2;
series4.tooltipText = "{nameX}\n[bold font-size: 20]{valueY}[/]";
series4.stroke = chart.colors.getIndex(0).lighten(0.5);
series4.strokeDasharray = "3,3";
series4.showBalloon = true;
var bullet4 = series4.bullets.push(new am4charts.CircleBullet());
bullet4.circle.radius = 3;
bullet4.circle.strokeWidth = 2;
bullet4.circle.fill = am4core.color("#fff");
// Add cursor
chart.cursor = new am4charts.XYCursor();
// Add legend
chart.legend = new am4charts.Legend();
chart.legend.position = "top";
// Add scrollbar
chart.scrollbarX = new am4charts.XYChartScrollbar();
// chart.scrollbarX.series.push(series1);
chart.scrollbarX.series.push(series3);
chart.scrollbarX.parent = chart.bottomAxesContainer; `
Please let me know if there is any option to display all the tooltips at the sametime. TIA .
LabelTooltips seem more along the lines of what you're looking to do.
However, the fact remains they're not tooltips. If you still want actual Tooltips, e.g. because LabelBullets don't have the ... tip that points to its associated bullet, since tooltips are sort of like singletons, i.e. 1 per series and the bullets utilize that, you'll have to roll your own.
If you have the animation theme enabled and have an initial animation, to avoid problems wait til the series' animations are over to do what you need to:
// A series already gets a transitionended event, so we'll wait for chart to be ready to listen to the right one
chart.events.once("ready", function(event) {
chart.series.each(function(series) {
// Wait for the init animation to be over before doing what we need to
series.events.once("transitionended", function(seriesEvent) {
// your code here
});
});
});
At that point we can create tooltips, link their data to the series', and place them according to each bullet. The bullets can be found in the series' bulletsContainer. Be sure to customize the tooltips as needed, e.g.:
series.bulletsContainer.children.each(function(bullet, index) {
var tooltip = new am4core.Tooltip();
tooltip.dataItem = tooltip.tooltipDataItem = series.dataItems.getIndex(index);
// place the tooltip in an appropriate container so the x/y coords are exact
tooltip.parent = chart.plotContainer;
tooltip.x = bullet.x;
tooltip.y = bullet.y;
tooltip.label.text = "{nameX}\n[bold font-size: 20]{valueY}[/]";
tooltip.getFillFromObject = false;
tooltip.background.fill = series.fill;
tooltip.show();
});
Fork:
https://jsfiddle.net/notacouch/9Ljk7t6z/
There's additional code in the demo for compatibility with legend toggling to get you started.
Show all tooltips of a series is not possible, because there is only one per series. I would suggest to use LabelBullets instead (docs) and style them like tooltips.
chart.series.each(series => {
var labelBullet = series.bullets.push(new am4charts.LabelBullet());
labelBullet.setStateOnChildren = true;
labelBullet.label.text = "{nameX}\n[bold font-size: 20]{valueY}[/]";
labelBullet.label.maxWidth = 150;
labelBullet.label.wrap = true;
labelBullet.label.truncate = false;
labelBullet.label.textAlign = "middle";
labelBullet.label.padding(5, 5, 5, 5);
labelBullet.label.fill = am4core.color("#000");
const background = new am4core.RoundedRectangle();
background.cornerRadius(3, 3, 3, 3);
labelBullet.label.background = background;
labelBullet.label.background.fill = series.fill;
labelBullet.label.background.fillOpacity = 0.9;
labelBullet.label.background.stroke = am4core.color("#fff");
labelBullet.label.background.strokeOpacity = 1;
});
I forked your JSFiddle and updated it: JSFiddle
I have a chart containing 3 LineSeries. Sometimes, the lines cross each other. At these points only the single tooltip of the last added series is displayed.
How can I combine those tooltips into one single single tooltip that contains the information on all three series, in case the points are at the same position?
I build the chart using LineSeries and place CircleBullets on them:
/* Create series */
var series1 = chart.series.push(new am4charts.LineSeries());
series1.dataFields.valueY = "cars";
series1.dataFields.categoryX = "year";
series1.name = "Cars";
series1.strokeWidth = 3;
series1.tensionX = 0.7;
bullet1 = series1.bullets.push(new am4charts.CircleBullet());
bullet1.tooltipText = `[bold]YEAR {categoryX}[/]
----
cars: {cars}`;
var series2 = chart.series.push(new am4charts.LineSeries());
series2.dataFields.valueY = "motorcycles";
series2.dataFields.categoryX = "year";
series2.name = "Motorcycles";
series2.strokeWidth = 3;
series2.tensionX = 0.7;
bullet2 = series2.bullets.push(new am4charts.CircleBullet());
bullet2.tooltipText = `[bold]YEAR {categoryX}[/]
----
motorcycles: {motorcycles}`;
var series3 = chart.series.push(new am4charts.LineSeries());
series3.dataFields.valueY = "bicycles";
series3.dataFields.categoryX = "year";
series3.name = "Bicycles";
series3.strokeWidth = 3;
series3.tensionX = 0.7;
bullet3 = series3.bullets.push(new am4charts.CircleBullet());
bullet3.tooltipText = `[bold]YEAR {categoryX}[/]
----
Bicycles: {bicycles}`;
full example: https://codepen.io/anon/pen/ommRPp
So like Albondi was saying, what you can start with is the chart cursor so we can have all the tooltips trigger all the time:
chart.cursor = new am4charts.XYCursor();
From there, if you want to filter which tooltips get shown and what gets shown in the remaining tooltip, I suggest setting an adapter on each bullet's tooltipText. What triggers a tooltip to begin with is if the object has a non-empty tooltipText property. So for the tooltips we want to hide, with an adapter we can just return "" to hide them at will.
To determine if we're hovering over multiple bullets, in this case we can just check if they have the same exact value, we know the value keys are cars, motorcycles, and bicycles, so if they're exactly the same on hover, suppress two of the tooltips, and modify the text of the other to show data for all three. The second parameter of the adapter will be the object we're hovering over, its dataItem.dataContext will have references to the data/values we're looking to compare.
bullet1.adapter.add("tooltipText", blankTooltipTextOnSameValues);
bullet2.adapter.add("tooltipText", blankTooltipTextOnSameValues);
bullet3.adapter.add("tooltipText", function(text, target) {
var data = target.dataItem.dataContext;
if (data.bicycles === data.motorcycles && data.bicycles === data.cars) {
return `[bold]YEAR {categoryX}[/]
----
Cars: {cars}
Motorcycles: {motorcycles}
Bicycles: {bicycles}`;
}
return text;
});
function blankTooltipTextOnSameValues(text, target) {
var data = target.dataItem.dataContext;
if (data.bicycles === data.motorcycles && data.bicycles === data.cars) {
return "";
}
return text;
}
Here's a fork of your code sample with the above changes:
https://codepen.io/team/amcharts/pen/a9c1d3eff9170c04f18e134bd6940daa
You can omit the Chart Cursor if you want, then you'd have to hover over the bullets individually for the tooltip to show. Since series3 is the latest addition to the chart, it will have a higher stacking order and will cover the other bullets at the same point, so the adapter above will achieve the same effect with/without the Chart Cursor.
Combine a cursor with tooltip positioning. You can create a cursor this way:
chart.cursor = new am4charts.XYCursor();
That will show all the labels but with poor positioning.
You should use a tooltip object to position the tooltip of each of the series:
var t = new am4core.Tooltip();
t.dy=-20; // This will move the tooltip 20 pixels up
bullet2.tooltipText = `[bold]YEAR {categoryX}[/]
----
motorcycles: {motorcycles}`
bullet2.tooltip = t;
Have a look of all the different positioning options here.
I used Amcharts to show a chart, and I make a div for it in a Bootstrap component. Followed is my html & js code:
<fieldset>
<legend>Chart</legend>
<div class="row">
<form class="form-horizontal mb-sm line-height-3">
<div class="col-sm-3 col-md-3">
<div class="form-group">
<label for="submitStartTime" class="col-sm-3 control-label">Start Time</label>
<div class="col-sm-6">
<label id="submitStartTime"></label>
</div>
</div>
<div id="latencyChart" class="col-sm-9 col-md-9" style="height: 400px;"></div>
</form>
</div>
</fieldset>
js:
drawChart: function(graphType){
var that = this;
that.generateChartData();
this.chart.dataProvider = this.chartData;
this.chart.categoryField = "date";
this.chart.balloon.bulletSize = 5;
// listen for "dataUpdated" event (fired when chart is rendered) and call zoomChart method when it happens
this.chart.addListener("dataUpdated", that.zoomChart());
// AXES
// category
var categoryAxis = this.chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "DD"; // our data is daily, so we set minPeriod to DD
categoryAxis.dashLength = 1;
categoryAxis.minorGridEnabled = true;
categoryAxis.twoLineMode = true;
categoryAxis.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: 'DD'
}, {
period: 'WW',
format: 'DD'
}, {
period: 'MM',
format: 'MMM'
}, {
period: 'YYYY',
format: 'YYYY'
}];
categoryAxis.axisColor = "#DADADA";
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.axisAlpha = 0;
valueAxis.dashLength = 1;
this.chart.addValueAxis(valueAxis);
// GRAPH
var graph = new AmCharts.AmGraph();
graph.title = "red line";
graph.valueField = "visits";
graph.bullet = "round";
graph.bulletBorderColor = "#FFFFFF";
graph.bulletBorderThickness = 2;
graph.bulletBorderAlpha = 1;
graph.lineThickness = 2;
graph.lineColor = "#5fb503";
graph.negativeLineColor = "#efcc26";
graph.hideBulletsCount = 50; // this makes the chart to hide bullets when there are more than 50 series in selection
this.chart.addGraph(graph);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
this.chart.addChartScrollbar(chartScrollbar);
this.chart.creditsPosition = "bottom-right";
// WRITE
this.chart.write("latencyChart");
this.chart.write("chartdiv");
},
// this method is called when chart is first inited as we listen for "dataUpdated" event
zoomChart: function() {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
this.chart.zoomToIndexes(this.chartData.length - 40, this.chartData.length - 1);
},
generateChartData: function(){
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 10);
for (var i = 0; i < 10; 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.random() * 40) - 20;
this.chartData.push({
date: newDate,
visits: visits
});
}
},
this.chart is a global variable in my js code, and it's already initialized. And the chart is shown in my page like below.
But Chrome console give some error info like below.
I debugged for some time and find out that the error happens in this.chart.write("latencyChart"). The error is cannot read property 'call' of undefined. Then I created a new div in this page called "chartdiv" to know whether the program can still work, and I added this.chart.write("chartdiv"); after the original one. and I found that there is no chart in "chartdiv" and the error goes on.
The issue is how you're assinging the zoomChart method to your dataUpdated event - that.zoomChart() is calling the zoomChart method, rather than assigning it to the event. You need to create a function that calls zoomChart so that it has access to your object's chart property during the event, i.e.
this.chart.addListener("dataUpdated", function() {
that.zoomChart()
});
Here's a fiddle with this fix.
Alternatively, you can use the dataUpdated event's argument object to access the chart object that way instead of fiddling with this/that/etc, for example:
this.chart.addListener("dataUpdated", that.zoomChart);
// ...
zoomChart: function(e) {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
e.chart.zoomToIndexes(e.chart.dataProvider.length - 40, e.chart.dataProvider.length - 1);
},
Fiddle
I am trying to plot a twitter streaming ,tweet sentiment score on per minute basis using ChartJs 1.0.2 .The xlables are getting overlapped after sometime. How can i plot the graph for a limited number of xAxis Labels to avoid the overlap. I am using Apache Zeppelin and AngularJs interpreter for the plotting. The code is as follows.
lineChartData = {}; //declare an object
lineChartData.labels = []; //add 'labels' element to object (X axis)
lineChartData.datasets = []; //add 'datasets' array element to object
//FIRST GRAPH: score
var line = 0
y = [];
lineChartData.datasets.push({}); //create a new line dataset
dataset = lineChartData.datasets[line]
dataset.fillColor = "rgba(0, 0, 0, 0)";
dataset.strokeColor = "rgba(75,192,192,0.4)";
dataset.lineColor = "rgba(75,192,192,0.4)";
dataset.label = "Score"
dataset.data = []; // value data
angular.forEach(newValue, function(x) {
y.push(x._3);
if (line === 0)
lineChartData.labels.push(x._2); //adds x axis labels
})
lineChartData.datasets[line].data = y; //send new line data to dataset
//end FIRST GRAPH: score
var options = {
responsive: true,
animation: false,
multiTooltipTemplate: function(dataset) {
//console.log(dataset)
return dataset.datasetLabel+ " : " + dataset.value ;
dataset.strokeColor='red';
} ,
}
ctx = canvas.getContext("2d");
myLineChart = new Chart(ctx).Line(lineChartData, options);
var legend = myLineChart.generateLegend();
$("#legendDiv").html(legend);
//document.getElementById("legendDiv").innerHTML = legend;
})
}
if (window.L) {
initMap();
} else {
console.log('Loading Leaflet library');
var sc = document.createElement('script');
sc.type = 'text/javascript';
sc.src = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js';
sc.onload = initMap;
sc.onerror = function(err) { alert(err); }
document.getElementsByTagName('head')[0].appendChild(sc);
}
I can think of following ways.
Get only the data for limited time window to the variable but not get all data.
Group the data to large time point
Example the data for certain interval
BTW, It might be worth to wrap the code which convert to data to visualisation. It will be easier to change to a different chart or use different plot option.
If you don't have strong preference for chart.js, check spark-highcharts to see if it meets your plot needs, or create a similar wrapper to chart.js.
Hi I want to remove the red color balloon from amchart graph which is coming while mouse hovering. Can anyone help me to solve this
my code is
var clicks =document.getElementById('clicks').value;
var cam_name =document.getElementById('cam_name').value;
var views =document.getElementById('views').value;
var camp_clicks =clicks.split('~');
var camp_names =cam_name.split('~');
var camp_imprs =views.split('~');
//var camp_clicks = [1,2,3,1.5,6,3,7];
var chart;
var chartData_camp = [];
/* var camp_names=['hi','hello','hw','r','u'];
var camp_costs=[1,2,3,4,5];
var camp_imprs=[1,2,3,4,5];
var camp_clicks=[1,2,3,4,5];*/
for (var i = 0; i < camp_names.length; i++) {
chartData_camp.push({
camp_name: camp_names[i],
camp_click: camp_clicks[i]
});
}
AmCharts.ready(function () {
// generate some random data first
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = 'http://www.xxx.com/en/Images/';
chart.zoomOutButton = {
backgroundColor: '#fff',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData_camp;
chart.categoryField = 'camp_name';
//graph.balloonText = "[[balloon2]]";
chart.balloon.showBullet = false;
// listen for 'dataUpdated' event (fired when chart is inited) and call zoomChart method when it happens
chart.addListener('dataUpdated', zoomChart);
// var cursorSettings = new AmCharts.ChartCursorSettings();
//cursorSettings.valueBalloonsEnabled = false;
// third value axis (on the left, detached)
camp_clickAxis = new AmCharts.ValueAxis();
// camp_clickAxis.offset = 50; // this line makes the axis to appear detached from plot area
camp_clickAxis.gridAlpha = 0;
camp_clickAxis.axisColor = '#3183D5';
camp_clickAxis.axisThickness = 2;
camp_clickAxis.balloonText = "";
// camp_clickAxis.lineAlpha = 2;
camp_clickAxis.lineColor = "#E5F3F9";
// camp_clickAxis.fillAlphas = 0.3; // setting fillAlphas to > 0 value makes it area graph
chart.addValueAxis(camp_clickAxis);
// GRAPHS
// third graph
var camp_clickGraph = new AmCharts.AmGraph();
camp_clickGraph.valueAxis = camp_clickAxis; // we have to indicate which value axis should be used
camp_clickGraph.type = "smoothedLine"; // this line makes the graph smoothed line.
camp_clickGraph.valueField = 'camp_click';
camp_clickGraph.title = ' ';
camp_clickGraph.bullet = 'round';
camp_clickGraph.bulletSize = 10;
camp_clickGraph.lineColor = '#058DC7';
camp_clickGraph.lineThickness = 3;
camp_clickGraph.hideBulletsCount = 30;
camp_clickGraph.fillAlphas = 0.1;
chart.addGraph(camp_clickGraph);
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = 'mouse';
chart.addChartCursor(chartCursor);
// SCROLLBAR
/*var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);*/
// LEGEND
var legend = new AmCharts.AmLegend();
legend.marginLeft = 110;
chart.addLegend(legend);
// WRITE
chart.write('camp_graph');
});
function zoomChart() {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
chart = new AmCharts.AmSerialChart();
chart.zoomToIndexes(0,30);
}
chartCursor.categoryBalloonEnabled = false;
I found the answer. Add this line for javascript chart to disable balloon
var chartCursor = new AmCharts.ChartCursor();
chart.addChartCursor(chartCursor);
chartCursor.enabled=false;
documentation here