AmCharts. Aligning balloons - amcharts

I've spent a lot of time finding the solution, but i can't see any property in AmChatrts documentation that can align balloons not vertically. Actually, I just want to see all balloons, but not in one column. Can anybody help me?

There is currently no way to make the balloons stack in any different way than in once column. However, there are a few alternatives you can consider.
1) Displaying just one balloon.
To do that, set oneBalloonOnly to true:
var chart = AmCharts.makeChart("chartdiv",{
...
"chartCursor": {
"oneBalloonOnly": true
}
});
This will make the cursor display just one balloon of the closest graph.
2) Disable balloons and use a legend instead.
To disable balloons, simply set [valueBalloonsEnabled][3] in chart cursor's settings to false.
var chart = AmCharts.makeChart("chartdiv",{
...
"chartCursor": {
"valueBalloonsEnabled": false
},
"legend": {}
});
The legend will show relative value next to each graph title when you hover over the chart.
3) Consolidate values from multiple graphs into a single balloon.
To do that, use graph's balloonText property. It lets you reference to any field in data, so you can make it display values from any graph.
Here's a good example of the above.
Here's a good demo on how to do that.

Related

How to align legend dynamically on top-center of the chart in c3.js?

I want to put the same legend top center of the chart. Legend items will be dynamic, likes sometimes 2,5 or 9, etc.
So, it should take space dynamically like how it is acting on the bottom.
I tried with inset functionality but it seems this is not looking better like the bottom one.
and there are few more complexity like I want it like a flat, so now if I define step size 3 then maybe, for now, it looks good for 9 items. but when there will be 2 items, it will show as a list!!
Although I solved that problem through the following solution:
// get parent elements
let parentEle = d3.selectAll("#chartID svg");
let childrenEle = parentEle
//Convert selection to selection representing the children
.selectAll(function () { return this.childNodes; })
.filter('g');
// putting legends position on TOP
d3.select(childrenEle._groups[0][2]).attr('transform', 'translate(0, 5)');
you have to keep eye on chart width - height and according to this, you may have to control padding in TOP for the chart.
might be this is not a good solution but it works fine for me :D

snapping brush to the next x value? [dc.js]

I have a line chart and data in the form
[{
time: "2016-4-29"
total: 23242
},
{
time: "2016-5-16
total: 3322
}
...
]
I'm trying to filter on the x-axis with the brush, however, since I don't have every single date, if I brush in a small range, the filter handler seems to return an empty array for my filters
I've set up my line chart's x-axis like so:
.x(d3.time.scale().domain([minDate,maxDate]))
is there a way to make it so a user can only filter on dates that are in the dataset?
I would like the brush to snap to dates in the dataset.
it seems like whats happening is that you are able to brush between ticks..so it doesn't know what it selected.
I'm going to answer the easier question: How do I create a brush that will not allow nothing to be selected?
In other words, if the brush contains no data, do not allow it to take.
There are two parts to the solution. First, since any chart with a brush will remove the old filter and then add the new filter, we can set up the addFilterHandler to reject any filter that does not contain non-zero bins:
spendHistChart.addFilterHandler(function(filters, filter) {
var binsIn = spendHistChart.group().all().filter(function(kv) {
return filter.isFiltered(kv.key) && kv.value;
});
console.log('non-empty bins in range', binsIn.length);
return binsIn.length ? [filter] : [];
});
That's the straightforward part, and incidentally I think you could probably modify it to snap the brush to existing data. (I haven't tried it, though.)
The more tricky part is that this won't get rid of the brush, it just doesn't apply the filter. So the chart will end up in an inconsistent state.
We need to detect when the brush action has finished, and if there is no filter at that point, explicitly tell the chart to clear the filter:
spendHistChart.brush().on('brushend.no-empty', function() {
if(!spendHistChart.filters().length)
window.setTimeout(function() {
spendHistChart.filterAll().redraw();
}, 100);
});
We need a brief delay here, because if we respond to brushend synchronously, the chart may still be responding to it, causing bickering and dissatisfaction.
As a bonus, you get kind of a "nah-ah" animation because of the unintentional remove-brush animation.
demo fiddle

Amcharts - Remove balloon

I've got a multi-axis chart with several lines in the graph.Currently as I move the mouse over the chart, several balloons appear at each point showing the values of the various lines at that point. At the same time, the legend at the bottom of the graph also displays values for these points. Is there a way I can disable the balloon text from appearing when I hover over the chart. The values appearing in the legend area is sufficient.
Just insert "showBalloon": false for each graph. Reference
use baloon object in graph option to enable and disable amchart baloon.
"graphs": [
{
"valueAxis": "item1",
"balloon": {
"enabled": false
}
]

DC.js Choropleth filtering Issue

I am trying to filter data on my choropleth chart from a bargraph. Strange thing is that it is not showing correct value on selecting a bar from the accompanying bar chart.
Here is the jsfiddle: https://jsfiddle.net/anmolkoul/jk8LammL/
The script code begins from line 4794
If i select WIN004 from the bar chart, it should highlight only five states and the tooltip should reflect the values for the data. Some states are highlighted for whom WIN004 does not exist.
I changed the properties of the choropleth from
.colors(d3.scale.quantize().range(["#F90D00", "#F63F00", "#F36F01", "#F09E01", "#EDCB02", "#DDEA03", "#ADE703", "#7EE404", "#50E104", "#24DE05", "#05DB11"]))
.colorDomain([-1, 1])
To
.colors(d3.scale.linear().range(["green", "white", "red"]))
.colorDomain([-2, 0, 2])
But i get a lot of white states where its hard to discern what has been highlighted. The tool tip for some white-ed-out states show -0.00 :/
Here is the fiddle http://jsfiddle.net/anmolkoul/jk8LammL/1/
So i guess either its a problem with my color range or how my data is getting parsed.
I would ideally like to specify the data ranges in the .colorDomain based on the top and bottom values of the riskIndicator dimension. My functions are not working though. Should i use d3.max or riskIndicator.top here?
EDIT:
I got the color domain dynamic by using the min and max values but still the graph is not performing as expected? Could this be an issue with the geochoropleth chart? I further took a working geochoropleth example and ported my data to it and even that gave me the same issue of representing data incorrectly. I thoughit could be a data problem but i validated using a couple of good BI tools and their map charts displayed data correctly.
Could this be an issue with the dc choropleth?
Thank you.
Anmol
This has the same root cause as the issue in this question:
Crossfilter showing negative numbers on dc.js with no negative numbers in the dataset
In short, floating point numbers don't always cancel out to zero when added and subtracted. This "fake group" will ensure they snap to zero when they get close:
function snap_to_zero(source_group) {
return {
all:function () {
return source_group.all().map(function(d) {
return {key: d.key,
value: (Math.abs(d.value)<1e-6) ? 0 : d.value};
});
}
};
}
Added it to the FAQ!

d3 autospace overlapping tick labels

Is there a way in d3 to not draw overlapping tick labels? For example, if I have a bar chart, but the bars are only 5 pixels wide and the labels are 10 pixels wide, I end up with a cluttered mess. I'm currently working on an implementation to only draw the labels when they do not overlap. I can't find any existing way to do that, but wasn't sure if anyone else had dealt with this problem.
There is no way of doing this automatically in D3. You can set the number of ticks or the tick values explicitly (see the documentation), but you'll have to figure out the respective numbers/values yourself. Another option would be to rotate the labels such that there is less chance of them overlapping.
Alternatively, like suggested in the other answer, you could try using a force layout to place the labels. To clarify, you would use the force layout on the labels only -- this is completely independent of the type of chart. I have done this in this example, which is slightly more relevant than the one linked in the other answer.
Note that if you go with the force layout solution, you don't have to animate the position of the labels. You could simply compute the force layout until it converges and then plot the labels.
I've had a similar problem with multiple (sub-)axis, where the last tick overlaps my vertical axis in some situations (depending on the screen width), so I've just wrote a little function that compares the position of the end of the text label with the position of the next axis. This code is very specific to my use case, but could adapted easily to your needs:
var $svg = $('#svg');
// get the last tick of each of my sub-axis
$('.tick-axis').find('.tick:last-of-type').each(function() {
// get position of the end of this text field
var endOfTextField = $(this).offset().left + $(this).find('text').width();
// get the next vertical axis
var $nextAxis = $('line[data-axis="' + $(this).closest('.tick-axis').attr('data-axis') + '"]');
// there is no axis on the very right, so just use the svg width
var positionOfAxis = ($nextAxis.length > 0) ? $nextAxis.offset().left : $svg.offset().left + $svg.width();
// hide the ugly ones!
if (endOfTextField > positionOfAxis) {
$(this).attr('class', 'tick hide');
}
});
The ticks with color: aqua are the hidden ones:

Resources