I am trying to render a custom axis over the existing Highcharts
chart.renderer.rect(0, chart.chartHeight - BAR_XAXIS_PADDING, 420, 5)
.attr({
fill : "black"
//fill: "url('#hatching2d63c14a-4bcf-4b6c-9511-891d8abca5c4')"
}).add(axisGroup);
where the 0, BAR_XAXIS_PADDING is a hardcoded value. Is there a way to get the existing axis co-ordinate so that i can bind the custom axis to it?
Get extremes from
var ex = chart.yAxis[0].getExtremes();
Then get y-coordinates for the axis:
var yBottom = chart.yAxis[0].toPixels(ex.min);
var yTop = chart.yAxis[0].toPixels(ex.max);
Now render rect:
chart.renderer.rect(chart.plotLeft, yTop, width, yBottom - yTop).add();
Related
Is there a parameter to set a minimum radius for features to cluster? - so that when a set of points or features are within some minimum distance, they form a cluster, otherwise not?
ol.source.Cluster() has two parameters that look promising, but don't seem to work as expected.
distance: Minimum distance in pixels between clusters. Default is 20.
extent: An array of numbers representing an extent: [minx, miny,
maxx, maxy].
Not quite sure what "but don't seem to work as expected." means?? How does it not work as expected??
distance property of ol.source.Cluster tells the layer when to group objects based on the distance set. It can be changed when creating the cluster layer. For example:
var locationSource = new ol.source.Vector({
url: loc_url,
format: new ol.format.GeoJSON({
defaultDataProjection :'EPSG:3857'
}),
loader: vectorLoader,
strategy: ol.loadingstrategy.all
});
var LOCclusterSource = new ol.source.Cluster({
distance: 5,
source: locationSource
});
I usually change the distance object until I find the desired distance so group/cluster object look right on the map.
The radius of a group object on a map layer can be change via a style function for the map layer. Many example of style functions exist here on stack.
Here is a hacked up example that I use to increase the radius of cluster/group objects on the map layer so it's visually obvious that it is a group/cluster object:
NOTE: You can have different shapes on the same layer too using a style function. https://openlayers.org/en/latest/examples/regularshape.html
// Location Map Layer Properties
var locLyrProps = {
"radius": 8,
"CORadius": 12,
"groupRadius": 10,
"borderWidth": 2,
"color": [0, 0, 0, 0.5],
"txtMaxRes": 20,
"txtOffsetY": -20
};
var styleFunction = function() {
return function(feature,resolution) {
var style;
var props = locLyrProps;
var radius;
var lyrTyp;
var gotGroup = false;
var features = feature.get('features');
if (features.length == 1) { //Individual map object because length = 1
style = new ol.style.Style({ //Square layer object
image: new ol.style.RegularShape({
radius: radius,
points: 4,
angle: Math.PI / 4,
fill: createFillStyle(feature),
stroke: createStrokeStyle(feature, resolution)
}),
text: createTextStyle(feature, resolution)
});
} else {
var rad = props.radius;
if (features.length > 1) { //If cluster/group of features increase radius of group object so group objects stand out a bit
rad = props.groupRadius; //If cluster/group object is found, set cluster/group radius for it
gotGroup = true;
}
console.log('circle radius: ' + rad);
style = new ol.style.Style({
image: new ol.style.Circle({
radius: rad,
fill: createFillStyle(feature),
stroke: createStrokeStyle(feature, resolution, gotGroup)
}),
text: createTextStyle(feature, resolution, props, gotGroup)
});
}
return [style];
};
};
I have a heatmap where the X and Y axis are populated dynamically. I have used the following code to render a circle at the intersection of X and Y. This is based off a fiddle where it was done for a scatter plot and worked in pre-5 highcharts. Now it doesn't work. Any help would be greatly appreciated.
This is the portion of the code that is added to the sales heatmap:
var circleX = 'Lukas';
var circleY = 'Wednesday';
var circleR = 1.0;
function addCircle(chart){
if (this.circle){
$(this.circle.element).remove();
}
var pixelX = chart.xAxis[0].toPixels(chart.xAxis[0].categories.indexOf(circleX));
var pixelY = chart.yAxis[0].toPixels(chart.yAxis[0].categories.indexOf(circleY));
var pixelR = chart.xAxis[0].toPixles(circleR) - chart.xAxis[0].toPixels(0);
Here is a fiddle: Fiddle
I'm trying to make a simple app doing something similar to the Layer Spy Example, but instead of a circle flowing the mouse pointer, I would like to do the clipping based on a rectangle which is always centered in the map.
(preferably with "fixed" size" i.e. changes "extent" when zooming)
Any help appreciated
Thanks
Frode
You can do it like in the example that you are referring to. But instead of context.arc() use context.rect() with a fixed position to clip the layer. Something like:
imagery.on('precompose', function(event) {
var ctx = event.context;
var pixelRatio = event.frameState.pixelRatio;
ctx.save();
ctx.beginPath();
var x = ctx.canvas.width / 2 - 100;
var y = ctx.canvas.height / 2 - 100;
ctx.rect(x, y, 100, 100);
ctx.clip();
});
http://jsfiddle.net/eo1c1x78/
In the highchart documentation is says:
positioner: Function
A callback function to place the tooltip in a default position. The callback receives three parameters: labelWidth, labelHeight and point, where point contains values for plotX and plotY telling where the reference point is in the plot area.
Add chart.plotLeft and chart.plotTop to get the full coordinates.
http://api.highcharts.com/highcharts#tooltip.positioner
But I'm not sure where I am supposed to add plotLeft, or plotTop
I don't see it on the scope, and I can't see it in the "chart" property options.
Can anyone explain?
Example for you: http://jsfiddle.net/j92p2/
tooltip: {
positioner: function (w, h, p) {
var chart = this.chart, // get chart
plotLeft = chart.plotLeft, // get plotLeft
plotTop = chart.plotTop; // get plotTop
console.log(this, plotTop, plotLeft); // watch console while hovering points
return { x: 80, y: 50 };
}
}
See inline comments. Let me know if you have any more questions.
In Highcharts 2, it was easy to add a point using series.addPoint(p) where the x value of that point fell between the x-values of two existing points.
Example: Let's say you wanted to create a chart with one series containing two points:
var p1 = {x: 100, y: 50};
var p2 = {x: 200, y: 40};
var data = [];
data.push(p1);
data.push(p1);
var c = new Highcharts.Chart({
...//code omitted
type: 'line',
data: data,
...//code omitted
});
In version two you could call add a point between those two by going:
var p3 = {x: 150, y: 60};
c.series[0].addPoint(p3, true);
For 'line' charts, highcharts 2 would automatically determine that the x value of p3 falls between the x values of p1 and p2 and so the line would be plotted through the points in the order: p1, p3, p2.
We are finding that in highcharts 3, the line gets plotted through the points in the order p1, p2, p3 - which implies that it "turns back on itself".
I have prepared the following jsFiddle examples, which add 50 points to an existing series with randomized x and y value.:
Highcharts 2.1.9: http://jsfiddle.net/HdNh2/4/
Highcharts 3.0.0: http://jsfiddle.net/HdNh2/5/
Is this something that could be fixed or do we need to try and circumvent the issue?
Thanks in advance...
H
So just to close this issue: Highcharts has confirmed that the logic changed since 2.2.x.
In our case it was simple enough to just re-render the entire chart, but I suspect series.setData() would also have been an option.
Here's a workaround. This will sort points on their x-values as they're added manually. This events object is in the chart object options block.
events: {
click: function(e) {
// find the clicked values and the series
var series = this.series[DIA.currentSeriesIndex],
x = parseFloat(e.xAxis[0].value),
y = parseFloat(e.yAxis[0].value);
// Add it
series.addPoint([x, y]);
if ( series.data.length > 1) {
// grab last point object in array
var point = series.data[series.data.length-1];
// sort the point objects on their x values
series.data.sort(function (a, b)
{
//Compare "a" and "b" and return -1, 0, or 1
return (a.x - b.x);
});
// force a redraw
point.update();
}
}
}