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
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 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.
Hi I am trying to implement scroller from Teechart libraries. I have encountered an issue while implementing the scroller. Loading data to the scroller might have gone wrong in my case. But same data loading works well with a slider implementation. I have attached my code for data loading as well as scroller here. I can see data loading after performing fast forward or play of signal, which is a different function for data loading. However, the scroller does not move freely on the canvas. It only moves initial 10 secs later it hangs up unless I load data from a play function. Is there a way I can set Min and max values instead of specifying intial length for the scroller axes. I have observed that when i setminmax value data loading parts gets affected too.
function AddDataSeries() {
Chart1.series.items=[]; // empty previous content
// Take care of boundaries
// Stop at both ends when scrolling/shifting on time
if (onset<0) {
cancelAnimationFrame(myAnimation);
onset = 0;
} // Reach the start
if (onset>nPoints-timeInterval) {
cancelAnimationFrame(myAnimation);
onset = nPoints-timeInterval;
} // Reach the end
// 1. Data Segmentation for current display
var ch = 0;
for (var i=1; i<=header_nChannels; i++) {
// Declare local version data to store the data
var str = "var Y"+i+"=[];"; // var Yi = []
eval(str);
// Segment using onset
var str = "Y"+i+"=Y"+i+"_all.slice(onset, onset+timeInterval);"; // Yi = Yi_all.slice(onset, onset+timeInterval);
eval(str);
}
}
Draw teechart function along with a scroller
function draw_TeeChart() {
var w = window.innerWidth, h = window.innerHeight;
// Initialize Teechart
Chart1 = new Tee.Chart("canvas");
document.getElementById("canvas").style.position = "relative";
document.getElementById("canvas").width= Math.round(0.82*w);document.getElementById("canvas").height= Math.round(0.89*h); //Chart1.bounds.x = Math.round(0.01*w);
Chart1.bounds.x = 14;Chart1.bounds.y= 10;
Chart1.bounds.width = Math.round(chartW*w);Chart1.bounds.height= Math.round(0.88*h);
Chart1.legend.visible = false; Chart1.panel.transparent = true;
Chart1.title.visible = false;Chart1.axes.bottom.title.text = " ";
Chart1.axes.left.increment = 1;
Chart1.panel.transparent = true;
Chart1.legend.visible = false;
// Chart1.axes.bottom.setMinMax(0, 1);
Chart1.axes.bottom.setMinMax(onset, onset+timeInterval);
Chart1.title.visible = false;
Chart1.axes.bottom.title.text = " ";
Chart1.zoom.enabled = false;
Chart1.scroll.mouseButton = 0;
Chart1.cursor = "pointer";
Chart1.scroll.direction = "horizontal";
scroller = new Tee.Scroller("canvas2", Chart1);
scroller.min=0;
scroller.max=nPoints;
scroller.position=onset;
scroller.useRange=false;
scroller.thumbSize=12;
scroller.cursor ="pointer";
scroller.scroller.onDrawThumb = "";
Chart1.draw();
// cancelAnimationFrame(myAnimation); // no auto-play
AddDataSeries();
//Slider implementation
var slider=new Tee.Slider(Chart1);
slider.min=0;
slider.max=nPoints;
slider.position=onset;
slider.useRange=false;
slider.thumbSize=12;
slider.horizontal=true;
slider.bounds.x=Math.round(0.052*w);
slider.bounds.y= Math.round(0.85*h);
slider.bounds.width=Math.round(sliderW*w);
slider.bounds.height=25;
// Text position at cursor
chartTop = Chart1.bounds.y;
chartLeft = slider.bounds.x;
chartWidth = slider.bounds.width;
chartHeight = Chart1.bounds.height;
// Tools Add beforehand
Chart1.tools.add(slider); // slider
// Chart1.tools.add(scroller); //scroller
nTools = Chart1.tools.items.length; // remove the extra texts out of range;
slider.onChanging=function(slider,value) {
var x = Math.round(value);
if (x<0){
onset = 0;
}
else if(x>nPoints-timeInterval){
onset = nPoints-timeInterval;
}
else{
onset = x;
}
cancelAnimationFrame(myAnimation); // no auto-play
AddDataSeries();
}
I have a line chart and every time the page refresh it changes the data, which is great but I need to to refresh by a user click. This is because there will eventually be other input fields on the page and refreshing the page would destroy their current session.
jsfiddle - http://jsfiddle.net/darcyvoutt/dXtv2/
Here is the code setup to create the line:
function economyData() {
// Rounds
var numRounds = 10;
// Stability of economy
var stable = 0.2;
var unstable = 0.6;
var stability = unstable;
// Type of economy
var boom = 0.02;
var flat = 0;
var poor = -0.02;
var economyTrend = boom;
// Range
var start = 1;
var max = start + stability;
var min = start - stability;
// Arrays
var baseLine = [];
var economy = [];
// Loop
for (var i = 0; i < numRounds + 1; i++) {
baseLine.push({x: i, y: 1});
if (i == 0) {
economyValue = 1;
} else {
var curve = Math.min(Math.max( start + ((Math.random() - 0.5) * stability), min), max);
economyValue = Math.round( ((1 + (economyTrend * i)) * curve) * 100) / 100;
}
economy.push({x: i, y: economyValue});
}
return [
{
key: 'Base Line',
values: baseLine
},
{
key: 'Economy',
values: economy
}
];
}
Here is what I tried to write but failed for updating:
function update() {
sel = svg.selectAll(".nv-line")
.datum(data);
sel
.exit()
.remove();
sel
.enter()
.append('path')
.attr('class','.nv-line');
sel
.transition().duration(1000);
};
d3.select("#update").on("click", data);
Here is what I did differently with your code.
// Maintian an instance of the chart
var chart;
// Maintain an Instance of the SVG selection with its data
var chartData;
nv.addGraph(function() {
chart = nv.models.lineChart().margin({
top : 5,
right : 10,
bottom : 38,
left : 10
}).color(["lightgrey", "rgba(242,94,34,0.58)"])
.useInteractiveGuideline(false)
.transitionDuration(350)
.showLegend(true).showYAxis(false)
.showXAxis(true).forceY([0.4, 1.6]);
chart.xAxis.tickFormat(d3.format('d')).axisLabel("Rounds");
chart.yAxis.tickFormat(d3.format('0.1f'));
var data = economyData();
// Assign the SVG selction
chartData = d3.select('#economyChart svg').datum(data);
chartData.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
Here's how the update() function looks like:
function update() {
var data = economyData();
// Update the SVG with the new data and call chart
chartData.datum(data).transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
};
// Update the CHART
d3.select("#update").on("click", update);
Here is a link to a working version of your code.
Hope it helps.
I anticipate using panBy but I'm not sure how to detect when mouse is "close" to the bounding box. Not even sure where to start here.
Ok, here's how I ended up doing it.
google.maps.event.addListener(map, 'mousemove', function(event) {
///
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
///
var point = map.getCenter();
var projection = overlay.getProjection();
var pixelpoint = projection.fromLatLngToDivPixel(point);
///
var thelatlng = event.latLng;
var proj = overlay.getProjection();
var thepix = proj.fromLatLngToDivPixel(thelatlng);
var mapBounds = map.getBounds();
var mB_NE = mapBounds.getNorthEast();
var mB_SW = mapBounds.getSouthWest();
var nE = proj.fromLatLngToDivPixel(mB_NE);
var sW = proj.fromLatLngToDivPixel(mB_SW);
var north = nE.y;
var east = nE.x;
var south = sW.y;
var west = sW.x;
var appx_north, appx_east, appx_south, appx_west = false;
if (Math.round(thepix.y) <= Math.round(north+20)) {appx_north = true;}
if (Math.round(thepix.x) >= Math.round(east-20)) {appx_east = true;}
if (Math.round(thepix.y) >= Math.round(south-20)) {appx_south = true;}
if (Math.round(thepix.x) <= Math.round(west+20)) {appx_west = true;}
if (appx_north) {
pixelpoint.y -= 5;
point = projection.fromDivPixelToLatLng(pixelpoint);
map.setCenter(point);
}
if (appx_east) {
pixelpoint.x += 5;
point = projection.fromDivPixelToLatLng(pixelpoint);
map.setCenter(point);
}
if (appx_south) {
pixelpoint.y += 5;
point = projection.fromDivPixelToLatLng(pixelpoint);
map.setCenter(point);
}
if (appx_west) {
pixelpoint.x -= 5;
point = projection.fromDivPixelToLatLng(pixelpoint);
map.setCenter(point);
}
});
There may be a more efficient way to do this, but nobody has said anything, and this works, so it will do.