Highchart Crosshair not touching x axis - javascript

I want to increase height of my xAxis crosshair to touch the x axis. Is there a way to achieve this. Below i have attached screen shot and code snippet for the same
Highcharts.chart(container, {
title: {
text: ""
},
xAxis: {
type: "datetime",
crosshair: true
}
}
I tried using it as tooltip option
tooltip: {
crosshairs: {
color: 'green',
width: 2,
height: 10
}
}
It takes width but does not take the height options
Js fiddle example

Currently the crosshair goes to where the x-axis baseline is expected to be (not accounting for offset), as also described by Mike Zavarello in the comments.
One workaround from my understanding of your situation is to extend Highcharts and instead draw the crosshair from the maximum value of your first y-axis (the one nearest the top) to the bottom of your second y-axis (the one nearest the bottom).
For example (JSFiddle):
(function (H) {
H.wrap(H.Axis.prototype, 'drawCrosshair', function (proceed, e, point) {
let old_function = H.Axis.prototype.getPlotLinePath;
H.Axis.prototype.getPlotLinePath = function (value, lineWidth, old, force, translatedValue) {
// copy paste handling of x value and sane value threshold
translatedValue = Math.min(Math.max(-1e5, translatedValue), 1e5);
x1 = x2 = Math.round(translatedValue + this.transB);
// max displayed value of your top y-axis
y1 = this.chart.yAxis[0].toPixels(this.chart.yAxis[0].max);
// min displayed value of your bottom y-axis
y2 = this.chart.yAxis[1].toPixels(this.chart.yAxis[1].min);
return this.chart.renderer.crispLine(
['M', x1, y1, 'L', x2, y2],
lineWidth || 1
);
};
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
H.Axis.prototype.getPlotLinePath = old_function;
});
}(Highcharts));
Note that this approach is very much directly addressing your problem by extending Axis.drawCrosshair, and within that extension rewriting the Axis.getPlotLinePath function to alter the path given for the crosshair. It does also not address crosshairs along the y-axis. Still, this could probably be solved in a similar way. It should be thoroughly tested for artifacts.

The length of the the crosshair is the same as xAxis height, so depending on the result you want to achieve set right xAxis height. Axis offset does not affect to the crosshair.
xAxis: {
crosshair: true,
height: 343, // yAxis[1].top - yAxis[0].top + yAxis[1].height
offset: -174
}
Live demo: http://jsfiddle.net/BlackLabel/w5c82ja9/

Related

Highcharts with custom scaling in upper regions

I would like to know how to achieve a custom scale for a chart in Highcharts. I want to display a boxplot which has very high whiskers. The normal values to display are between 500 and 1000 but there are some anomalies which are about 6000 on y-axis. This is causing the whole chart to be squeezed and the scaling is so small that you can't determine the boxplots correctly. I would like to increase the tick-size between 1000 and 6000 to decrease the heigt of the chart.
Highcharts provides breaks functionality that seems to be ideal for your case: https://api.highcharts.com/highcharts/yAxis.breaks
Another approach is to change the yAxis type to logarithmic: https://api.highcharts.com/highcharts/yAxis.type
EDIT
The discussion in the comments section reveals that the OP needs rather custom y axis formatting than breaks functionality.
Here's how to approach this issue:
The problem here is that axes in Highcharts can only have either constant or logarythmic scales. Your example shows irregular scale - the values are not in constant or logarythmic order ([0, 3, 10, 30, 150]).
Here's what I've done to mimic that kind of look and behaviour:
I set tickPositions to [0, 1, 2, 3, 4] - these are the actual values that appear on the chart. As you can see the distance between all these numbers is constant: 1.
Then I used formatter to display corresponding number from ranges array for each label.
yAxis: {
tickPositions: [0, 1, 2, 3, 4],
labels: {
formatter: function() {
return ranges[this.pos];
}
}
},
Before I passed the data to the chart constructor I converted all the values so that they're between 0 and 4:
series: [{
data: [2, 120].map(function(val) {
var range = findRange(val);
var y = range.index + (val - range.low) / (range.high - range.low);
return {
y: y,
originalValue: val
};
})
}]
Finally I used originalValue property in tooltip.format string to print to the user the number before the conversion.
tooltip: {
pointFormat: "<span style='color:{point.color}'>\u25CF</span> {series.name}: <b>{point.originalValue}</b><br/>"
},
This example is simplified to the line series case but can be easily adjusted to boxplot series. The code serves only for the example purposes and should be improved - it's easy to cause an error within it.
Live working demo: https://jsfiddle.net/kkulig/ytjz1jej/
API references:
https://api.highcharts.com/highcharts/tooltip.pointFormat
https://api.highcharts.com/highcharts/yAxis.tickPositions
https://api.highcharts.com/highcharts/xAxis.labels.formatter

C3 Bar Graph x-axis labels are too congested

I have created a Bar graph using C3 JS plugin, The graph is working fine but the problem is with the x-axis labels looks too congested like as shown below
Working JSFiddle
My Code is as given below
var chart = c3.generate({
bindto: "#chart",
data: {
x : 'x',
columns: [
['x', "2016-04-01","2016-04-08","2016-04-15","2016-04-22","2016-04-29","2016-05-06","2016-05-13","2016-05-20","2016-05-27","2016-06-03","2016-06-10","2016-06-17","2016-06-24","2016-07-09","2016-07-10","2016-07-11","2016-07-12","2016-07-13","2016-07-15","2016-07-16","2016-07-17","2016-07-18","2016-07-19","2016-07-20","2016-07-21","2016-07-22","2016-07-23","2016-07-24","2016-07-25","2016-07-26","2016-07-27","2016-07-28","2016-07-29","2016-07-30","2016-07-31","2016-08-01","2016-08-02","2016-08-03","2016-08-04","2016-08-05","2016-08-06","2016-08-07","2016-08-08","2016-08-09","2016-08-10","2016-08-11","2016-08-12","2016-08-13","2016-08-14","2016-08-15","2016-08-16","2016-08-17","2016-08-18","2016-08-19","2016-08-20","2016-08-21","2016-08-22","2016-08-23","2016-08-24","2016-08-25","2016-08-26","2016-08-27","2016-08-28","2016-08-29","2016-08-30","2016-08-31","2016-09-01","2016-09-02","2016-09-03","2016-09-04","2016-09-05","2016-09-06","2016-09-07","2016-09-08","2016-09-09","2016-09-10","2016-09-11","2016-09-12","2016-09-13","2016-09-14","2016-09-15","2016-09-16","2016-09-17","2016-09-18","2016-09-19","2016-09-20","2016-09-21","2016-09-22","2016-09-23","2016-09-24","2016-09-25","2016-09-26","2016-09-27","2016-09-28","2016-09-29","2016-09-30","2016-10-01","2016-10-02","2016-10-03","2016-10-04","2016-10-05","2016-10-06","2016-10-07","2016-10-08","2016-10-09","2016-10-10","2016-10-11","2016-10-12","2016-10-13","2016-10-14","2016-10-15","2016-10-16","2016-10-17","2016-10-18","2016-10-19","2016-10-20","2016-10-21","2016-10-22","2016-10-23","2016-10-24","2016-10-25","2016-10-26","2016-10-27","2016-10-28","2016-10-29","2016-10-30","2016-10-31","2016-11-01","2016-11-02","2016-11-03","2016-11-04","2016-11-09"],
['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2748,2748,2694,2694,2694,2694,2694,2694,2694,2668,2668,2668,2668,2576,2572,2572,3043,3084,3084,3084,3084,3084,3156,3521,3521,3550,3542,3542,3573,3580,3629,3579,3584,3542,2757,2791,2696,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3369,3376,3371,3373,3371,3379,3363,3373,3347,3348,3382,3402,3410,3434,2579,2579,2369],
['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,2375,2425,2475,2500,2500,2087,2087,2087,2087,2091,2087,1767,1767,1767,1633,1498,1498,1642,1637,1633,1609,1841,1713,1702,1862,1888,1888,1888,1949,1976,1977,2014,2014,2014,1946,1966,1973,2224,2252,2318,2318,2318,2327,2373,2513,2535,2543,2534,2539,2823,2849,2990,3142,3142,3108,2513,2687,2678,2856,2860,2861,2862,2866,2869,2870,2875,2874,2874,2874,2879,2885,2886,2883,2889,2896,2895,2899,2903,2909,2911,2913,2913,2913,2916,2922,2933,2937,2943,2942,2943,2947,1811,1826,1837,1840,1840,1841,1843,1511,1854,1853,1851,1852,1853,1849,1852,1874,1857,1883,1886,1888,1904,1903,1924,1947,2060,2068,2068,2082,1582,1344,836,839,788]
],
type: 'bar'
},
axis: {
x: {
type: 'category',
tick: {
rotate: -60,
multiline: false
},
height: 130
}
}
});
Can anyone please tell me some solution for this
What I did to solve it
I have used timeseries type instead of category type, after that the label issue got resolved but the graph was been plottted with more white spaces for the month of march like as shown below
Working JSFiddle
You can use c3's tick count setting for this, so here we say 20 labels.
However there is an added gotcha in that ticks that now resolve to a fractional category value won't show - i.e. the 2nd equally spaced tick out of 20 may be the 2.6667th element in the x category axis - so you need to have a little format function that adjusts for this, otherwise you just get the end and start labels. (Or you could figure out a tick count that divides into your data count + 1 as a whole number.)
tick: {
format: function (x) {
var cats = this.api.categories();
return cats[Math.round(x)];
},
count: 20,
rotate: -60,
multiline: false
},
http://jsfiddle.net/fz0t10yb/7/
One of the possible solution could be to use x-axis labels at required indexes only & leaving others blank.
['x', "2016-04-01","","","","2016-04-29","","","",...]
['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,...]
['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,...]
You can position labels so that it would capture the date and at same time it looks good also.

Flot Bubbles Plugin - Bubble Size

I am using the Bubbles plugin with the Flot charting library for JQuery. The data I have is dynamic and can be quite varied within the X, Y, and Z values. The main issue I am having is the size of the bubbles. If the X and Y values are somewhat close to each other but the Z value is much larger the bubble simply takes over the chart. Setting the axis min and max for the X and Y axes helps a bit but not in every case. I have tried to look for other options and settings but did not find anything useful. Is there any type of way to control the size of the bubble?
For instance Flex used to automatically create bubble sizes relative to the screen and axes where Flot seems to always set the bubble size to the same scale as the X and Y values. I have included just a sample of data. I would like to continue to use Flot as the plugin because I have many other chart types in my application and would like to use the same code base. However if there is another plugin that would be better I am open to ideas. Thanks!
https://jsfiddle.net/llamajuana/zd4hd7rb/
var d1 = [[30,339,139856], [30, 445,239823], [30,1506,127331]];
var options = {
series: {
//color: '#CCC',
color: function(x, y, value) {
var red = 55 + value * 10;
return 'rgba('+red+',50,50,1)';
},
bubbles: {
active: true,
show: true,
fill: true,
linewidth: 0,
bubblelabel: {
show: true
},
highlight: {
show: true,
opacity: 0.3
}
}
},
grid:{
hoverable: true,
clickable: true
},
tooltip: {
show: true,
content: "x: %x | y: %y | value: %ct"
}
};
var p4 = $.plot( $("#plot"), [d1], options );
You could try logarithmic scaling.
For the x- and y-axis you can do this using the transform property in the axis options or changing the data before drawing the plot.
For the bubbles you have to do this by hand, either by changing the data before drawing or by replacing the drawbubble function of the bubbles plugin (see the User draw example here).
See this fiddle for the full example. Changes from your fiddle:
1) You could change this directly in the bubbles plugin, if you wanted.
// index of bubbles plugin is dynamic, you better search for it
var defaultBubbles = $.plot.plugins[1].options.series.bubbles.drawbubble;
var logBubbles = function(ctx, serie, x, y, v, r, c, overlay){
defaultBubbles(ctx, serie, x, y, v, Math.log(r), c, overlay);
}
2) In the series options:
xaxis: {
transform: function (v) {
return Math.log(v);
},
inverseTransform: function (v) {
return Math.exp(v);
}
},
yaxis: {
transform: function (v) {
return Math.log(v);
},
inverseTransform: function (v) {
return Math.exp(v);
}
},
3) In the radiusAtPoint() function in the bubbles plugin:
// added Math.log function here too
return parseInt(series.yaxis.scale * Math.log(series.data[radius_index][2]) / 2, 0);

Is it possible to change properties of xAxis.labels individually in HighCharts?

I would like to set different properties for my labels on the xAxis (Here is my problem).
I know how to do this for dataLabels : API.
It is similar to this.
But I don't find anything to do the same thing for xAxis.labels.
Does it exist a way to do this ?
Solution :
It changes only y property of xAxis labels.
Here is a jsFiddle.
chart: {
renderTo: 'container',
type: 'column',
events: {
load: function () {
var xAxis = this.xAxis[0];
var serie = this.series[0];
for (var current_tick in xAxis.ticks) {
var tick = xAxis.ticks[current_tick];
if(serie.data[current_tick]){
if (serie.data[current_tick].y > 0) {
tick.label.attr({
y: tick.label.y + 18
});
}
}
}
}
}
}
I am not aware of a way to do that.
What I would probably do in this situation is create to x axes, one for the positive values, and one for the negative.
{{edit - although, it seems the axis offset plugin only works (at least from what I am seeing) if you have opposite: true set for the axis.
SO, you have to offset the labels on one of them. example:
http://jsfiddle.net/jlbriggs/S48eX/

Compare two data points inside the tooltip in a Highcharts combination chart

I have a combination bar-line chart sharing a single Y axis.
The data points for both the bar and the line chart always share the same Y values. I'd like to be able to calculate the difference between the two X values in the tooltip.
Here's the chart I'm working with:
Combo Chart
Got it to work. The trick was in the shared and formatter properties of tooltip:
tooltip: {
shared: true,
formatter: function() {
var s= this.points[1].y - this.points[0].y;
return s;
}
},

Categories

Resources