Let me start with explaining the fiddle I have provided.
https://jsfiddle.net/abcdlearner/a4y3cge4/1
In the right most part of the chart, there are four bubbles clubbed together. So When I mouseover any of the bubbles in that group, I should get the count as four always. because the group contains four bubbles. Whereas, in the fiddle, it will show different count when hovering over different bubbles.
In short, for instance, if there are 8 bubbles linked/clubbed together, it should show the count as 8 when hovering over any of the bubbles in that group of 8. I need the group count, instead of the count of the bubbles intersecting the hovered bubble. This can be achieved through recursion I suppose. But I am stuck with this. Any timely help on this would be greatly appreciated!
series: [{
tooltip: {
pointFormatter: function () {
var _this = this;
var overlapCount = this.series.data.reduce(function (sum, point) {
return sum + (point !== _this && areOverlapping(_this, point));
}, 0) + 1;
return 'Overlapping bubbles: ' + overlapCount;
}
}
From what I understand, you want to count all bubbles that are chained together. I created recursive code that collect all bubbles that are chained in one group and returns them in an array. Take a look at the example I posted below.
Example:
https://jsfiddle.net/m53tevbq/
As you said, your script needed some recursion.
You wasn't very far from the desired result. My logic follows the transitivity relation:
So imagine A, B and C are chart bubbles. If A overlaps B that overlaps C (A doesn't overlaps C), the total amount of overlapping bubbles is 3.
So A doesn't "know" C, but both are overlapping B.
If you have any questions about the logic or the code, feel free to ask. I put some comments into the code to explain you what I've done.
Finally, here is your working fiddle.
Related
Consider the following high chart
At 15 jun, category II has no data, what if I dont want that spacing left for it, Is there anyway to remove such spaces.
for code reference
`http://jsfiddle.net/G5S9L/8/`
I don't see anything in the API that allows you to do this. As a kludgy workaround you could shift the columns yourself in the onload callback:
, function(chart){
var barLeft = $(chart.series[0].data[1].graphic.element);
var barRight = $(chart.series[2].data[1].graphic.element);
barLeft.attr('x',parseInt(barLeft.attr('x')) + parseInt(barLeft.attr('width'))/2);
barRight.attr('x',parseInt(barRight.attr('x')) - parseInt(barRight.attr('width'))/2);
});
Updated fiddle.
This is how Highcharts work. It calculates the space for categories, then divide it between series. It doesn't matter if you have data or not, space is given for possible points.
I am showing two lines in a single graph updating them each second with a value that is saved into a global variable (both have different global variables). An example of the code can be found here: jsFiddle example.
As you can see the two lines are on top of each other, even though they have different values when the ymin and ymax are added to the lines (you can see this in the console).
The cause appears to be in the first addPoint call (line 118). If the first boolean is set to true (like the second addPoint call) the lines are shown correctly but the animation is wrong: jsFiddle example.
Does anyone know why the lines are on top of each other while their values are obviously different? And more importantly: how can I fix this while keeping the smooth animation?
Previous (possibly related) question: Chart not moving fluently when adding value to two lines on interval.
The problem is with using the same variable emptyarray for both series. This is known issue with Highcharts (roported on github) that Highcharts overwrites some of options passed to the chart. Possible solution is to use function which will return that empty array, for example:
function generateArray(){
var emptyarray = [],
time = (new Date()).getTime(),
i;
for (i = -50; i <= 0; i++) {
emptyarray.push({
x: time + i * 1000,
y: 230
});
}
return emptyarray;
}
chartinfo.series = [{
name: 'Minimum Voltage',
data: generateArray(),
color: '#FFFFDD'
}, {
name: 'Maximum Voltage',
data: generateArray(),
color: '#B72E8D'
}];
Working jsFiddle: http://jsfiddle.net/XAHa4/2/
It looks like strange with your setInerval functions, because minified example http://jsfiddle.net/DxqUj/ works properly.
I am drawing a line chart with monthly data points. However, I want the scale to display year strings only.
So far, so easy. However, as far as I can see, Highcharts will always draw the xAxis labels relative to the ticks... and I am required to display them centered between ticks.
Is there some simple way of doing this that I am missing, please...?
According to my understanding, the behavior you desire is: http://jsfiddle.net/msjaiswal/U45Sr/2/
Let me break down the solution :
1. Monthly Data Points
One data point corresponding to one month :
var data = [
[Date.UTC(2003,1),0.872],
[Date.UTC(2003,2),0.8714],
[Date.UTC(2003,3),0.8638],
[Date.UTC(2003,4),0.8567],
[Date.UTC(2003,5),0.8536],
[Date.UTC(2003,6),0.8564],
..
]
2. Scale to display only yearly ticks
Use chart options like this:
xAxis: {
minRange : 30 * 24 * 3600 * 1000, //
minTickInterval: 12* 30 * 24 * 3600 * 1000 // An year
},
There is no simple, out-of-the-box solution. You have to use events and reposition the labels accordingly. Here is a sample solution that also works when resizing the browser window (or otherwise forcing the chart to redraw), even when the tick count changes: http://jsfiddle.net/McNetic/eyyom2qg/3/
It works by attaching the same event handler to both the load and the redraw events:
$('#container').highcharts({
chart: {
events: {
load: fixLabels,
redraw: fixLabels
}
},
[...]
The handler itself looks like this:
var fixLabels = function() {
var labels = $('div.highcharts-xaxis-labels span', this.container).sort(function(a, b) {
return +parseInt($(a).css('left')) - +parseInt($(b).css('left'));
});
labels.css('margin-left',
(parseInt($(labels.get(1)).css('left')) - parseInt($(labels.get(0)).css('left'))) / 2
);
$(labels.get(this.xAxis[0].tickPositions.length - 1)).remove();
};
Basically, it works like this:
Get all existing labels (when redrawn, this includes newly added ones). 2. Sort by css property 'left' (they are not sorted this way after some redrawing)
Calculate offset between the first two labels (the offset is the same for all labels)
Set half of the offset as margin-left of all labels, effectively shifting them half the offset to the right.
Remove the rightmost label (moved outside of chart, by sometimes partly visible).
This can be done with a workaround by manually adjusting the label positioning via a callback (called on both load and redraw). Please see the fiddle linked to in my comment on this post: Highcharts - how can I center labels on a datetime x-axis?
There are several xAxis options which may help do what you want.
http://api.highcharts.com/highcharts#xAxis.labels
Take a look at 'align' which specifies whether the labels are to the left or right of the tick, and also 'x' which allows you to specify a x-offset for the label from the tick.
Have you tried to use tick placement ? http://api.highcharts.com/highcharts#xAxis.tickmarkPlacement
long shot question here!
My chart has 3 views, in one of the views it shows the days of the month (1-31 etc)
My client wants to the highlight the Y-axis gridLines of days that are weekends, to be a darker color.
The other caveat is, I can't specify the stylistically different gridLines when creating the graph, only when I redraw the graph.
(Because this view isn't the initially view and I am redrawing me graph as the user navigates through the views.
ATM between redraws I am removing the old series, adding a new one, changing the chart title etc
Does anyone know how to do this?
While I think that #mg1075's solution of using the plot bands is the best way of doing this, if you wanted to get really crazy you can modify the gridlines through the dom. For example, make every other line red:
$.each($('.highcharts-grid path'),
function(i, elem) {
if (i % 2 != 0)
{
$(elem).attr('stroke','red');
}
});
});
Fiddle here.
I've looked high and low and can't seem to find an answer to what appears to be quite a straightforward issues (I would think).
I have a line chart where there is data at several points in a series but only only one set of points link up.
Does anyone know why this is? Is it to do with my data? If it is, I am struggling to see any relationships in the data that may explain this behavior.
Here is what I mean:
As you can see, the red diamonds should be connecting - the same could be said about the blue squares and the dark blue triangles. Any thoughts?
Apologies if my colors are wrong - I'm colorblind.
Okay, so I worked this out.
Firstly, in order to get the lines to join up, you need to set the EmptyPoint colour for the series.
select your series in your chart
In the properties tab (not the dialog) drill down into the EmptyPoint property and set the colour to be Black
This will get them joining up - yay! But part of the line is colour and the other part is black, right? That's a bit silly, especially considering if you leave the colour to Automatic on the EmptyPoint that it will be transparent.
So, then we need to get the series and the EmptyPoint's colours in sync.
Using code from here. I added some code to the code of the report.
1). Right click on an empty space on the report and select "Report Properties"
2). In the code tab, paste the following:
Private colorPalette As String() = {"#418CF0", "#FCB441", "#E0400A", "#05642E", "#1A3B69", "#BFBFBF", "#E0400A", "#FCB441", "DarkBlue", "Tomato", "Orange", "CornflowerBlue", "Gold", "Red", "Green", "LightBlue", "Lime", "Maroon", "LightSteelBlue", "Tan", "Silver"}
Private count As Integer = 0
Private mapping As New System.Collections.Hashtable()
Public Function GetColor(ByVal groupingValue As String) As String
If mapping.ContainsKey(groupingValue) Then
Return mapping(groupingValue)
End If
Dim c As String = colorPalette(count Mod colorPalette.Length)
count = count + 1
mapping.Add(groupingValue, c)
Return c
End Function
Then we need to call this code when setting the colour of the series and of the EmptyPoint.
Select your series
In the properties tab paste something the following (replace WhateverTheGroupIsForYourSeries with your series group name): =Code.GetColor(Fields!*WhateverTheGroupIsForYourSeries*.Value)
Drill down to the color element of the EmptyPoint Series property
Paste the same text as from point two [e.g. =Code.GetColor(Fields!*WhateverTheGroupIsForYourSeries*.Value)]
And voila! You're done!
I can't believe how unnecessarily difficult this is :D
I just had a problem where it was showing markers but not the lines. I ended up solving it by wrapping the expression in a CInt() to convert it to an integer.
Another way to handle this is to do a recursive select (if you have very large data sets don't do this, it kills performance). So you could make your dataset:
SELECT *, ROW_NUMBER() over(partition by Store order by Date desc) as rn
FROM StorePerformance
Now you can have your category group be rn (it should group by rn and sort by rn) but select date for its label. This will still display the date on your x axis, but since you are grouping by rn the data will still be continuous and all of the lines will connect. Also your legend will still match.
I still haven't looked deeply into how much this shifts the data points since we are plotting with row number and displaying date, but if you are mainly concerned with visualizing trends in the lines and aren't as concerned with where they are at a given point in time in relation to one another, it will serve you just fine. Otherwise I would leave the chart the way it is and just read the plot points, which are still valid data.
Solution
Just put your Fields!(YourSeriesGroup).Value in Series Groups to above of
Fields!(YourCategoryGroup).Value in Category Groups, your series group should be in both Series Groups and Category Groups (should be above of your initial category group).
And after that right click horizontal axis and select Horizontal Axis Properties. Set Axis Type to Scalar and click OK.
Result