Openlayers 3 Feature Label Background - openlayers-3

we are using OpenLayers 3 and want to add labels to our features. To improve visibility, we also want to add a background to those labels.
I have looked at: http://openlayers.org/en/v3.4.0/examples/vector-labels.html
but could not find another solution than increasing the overdraw width. But this results in bumby backgrounds and seems to be more like a hack for my problem.
Sadly we are not able to use another layer for the labels, cause the feature has to be on the same level as the corresponding label so that you can alway see a feature with its label in case it is overlapping with another feature (not only labels overlapping the features).
So I wanted to ask if you know a way to set the background of a label without using overdraw or a separate layer?
Best regards and thanks in advance
Basti
Updated description:
We want to render cars on a map. These cars should have labels with a rectangular background (in a color we can change) for the text so the user can read them more easily. Furthermore should the label be on the same level as the corresponding car. The reason behind this is that if cars are overlapping each other the labels should too and there should alway be one car with its label on top. I hope this description makes things a little bit clearer.

I managed to solve a similar problem by using a SVG shape behind the Text element and fill-up the shape with color, to achieve the same result.
I had to resize the background shape to match the size of text element and it wasn't as straightforward as I was hoping for.
The main blocks were:
SVG items don't have background style, and fill attribute on text element would only change the text color not its background color. That's why I had to use another shape in the first place.
When a SVG element is used as the source of an image element, all the javascript code inside it is ignored for security reasons. Therefore, you can't dynamically check/change sizes.
Shapes and Paths inside the SVG element are not part of DOM, so you can't access or style them with JavaScript or CSS.
First thing I did was to use the following code -- that I found somewhere on Stackoverflow, to get the width of the rendered text in pixels:
/* Get the rendered size of a text, in pixels */
/* _text: "Blah blah" */
/* _fontStyle: "Normal 12px Arial" */
function getTextWidth ( _text, _fontStyle ) {
var canvas = undefined,
context = undefined,
metrics = undefined;
canvas = document.createElement( "canvas" )
context = canvas.getContext( "2d" );
context.font = _fontStyle;
metrics = context.measureText( _text );
return metrics.width;
}
Then I used it inside my other function which was generating the marker and its label:
...
labelFontStyle = "Normal 12px Arial";
labelWidth = getTextWidth( _text, labelFontStyle );
labelWidth = labelWidth + 10;
iconSVG = '<svg ' +
'version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' +
'x="0px" y="0px" width="' + labelWidth + 'px" height="16px" ' +
'viewBox="0 0 ' + labelWidth + ' 16" enable-background="new 0 0 ' + labelWidth + ' 16" xml:space="preserve">'+
'<rect x="0" y="0" width="' + labelWidth + '" height="16" stroke="#000000" fill="#DEEFAE" stroke-width="2"></rect>' +
'<text x="5" y="13" fill="#000000" font-family="Arial" font-size="12" font-weight="normal">' + _text + '</text>' +
'</svg>';
imageElement = new Image();
imageElement.src = 'data:image/svg+xml,' + escape( iconSVG );
iconStyle = new ol.style.Style({
"image": new ol.style.Icon({
"img": imageElement,
"imgSize":[labelWidth, 66],
"anchor": [0.5, 0.5],
"offset": [0, -50]
})
});
feature = new ol.Feature({
"geometry": new ol.geom.Point(
ol.proj.fromLonLat( [_longitude, _latitude] )
)
});
feature.setStyle( iconStyle );
return feature;
This is my answer that I originally posted here

Related

Leaflet .bindpopup using variable

I want to select which item to use in a .bindpopup based on a previous calculation as shown:
setColour(styleHambleden)
var popupChoose = 'popup' + styleHambleden;
+ L.geoJSON(plannerHambleden, {
color: color,
weight: weight,
Opacity: opacity
}).addTo(map).bindPopup(popupChoose);
but this just displays the name of the calculated variable rather than trigger the desired popup - using code like this:
var popupRed = L.popup()
.setContent('<iframe src="popupRed.html" width = "375"; height ="350"></iframe>');
Gratgeful for thoughts on how this might be accomplished.

jsPDF- html() new function has no feature to set margin to pdf page

i am using jsPDF into vue cli application, but i am unable to find any solution to set the margins to the pdf page. all the text and images are getting overflowed on the pages.
i want to set all the four margins. the syntax to set margins given in the jsPDF documentation is also not working.
this is my function to generate and download pdf:
downloadpdf() {
var pdf = new jsPDF("p", "pt", "a4");
pdf.setFontSize("10");
pdf.setLineWidth("100");
pdf.setTextColor("darkblue");
// Printing text
var vuejsinformation = `JQuery is a lightweight, "write less, do more", JavaScript library.`;
pdf.text(vuejsinformation, 10, 10);
//pdf.save("Sample.pdf");
// Printing a complete div container who has class pdfrapper
pdf.html(window.jQuery(".pdfwrapper").get(0), {
callback: function (pdf) {
pdf.save("Sample.pdf");
},
x: 10,
y: 10,
});
},
how to set all the four margins ?
You can add an option var in the jspdf.html() method like this:
jspdf.html(src, {
margin: number,
html2canvas: {width: number, height: number, ...}
...
})
However there seems to be an issue where the margin is ignored when using this method see https://github.com/MrRio/jsPDF/issues/2924.
It will probably be fixed soon :).
Here's the documentation for the jspdf.html() method http://raw.githack.com/MrRio/jsPDF/master/docs/module-html.html
This example for jsPDF version 2.1.1 should give you an idea on how to setup the margins.
var pageWidth = 8.5,
lineHeight = 1.2,
margin = 0.5,
maxLineWidth = pageWidth - margin * 2,
fontSize = 24,
ptsPerInch = 72,
oneLineHeight = (fontSize * lineHeight) / ptsPerInch,
text =
"Two households, both alike in dignity,\n" +
"In fair Verona, where we lay our scene,\n" +
"From ancient grudge break to new mutiny,\n" +
"Where civil blood makes civil hands unclean.\n" +
"From forth the fatal loins of these two foes\n" +
"A pair of star-cross'd lovers take their life;\n" +
"Whole misadventured piteous overthrows\n" +
"Do with their death bury their parents' strife.\n" +
"The fearful passage of their death-mark'd love,\n" +
"And the continuance of their parents' rage,\n" +
// Notice that the following will be wrapped to two lines automatically!
"Which, but their children's end, nought could remove, Is now the two hours' traffic of our stage;\n" +
"The which if you with patient ears attend,\n" +
"What here shall miss, our toil shall strive to mend.",
doc = new jsPDF({
unit: "in",
lineHeight: lineHeight
}).setProperties({ title: "String Splitting" });
// splitTextToSize takes your string and turns it in to an array of strings,
// each of which can be displayed within the specified maxLineWidth.
var textLines = doc
.setFont("helvetica")
.setFontSize(fontSize)
.splitTextToSize(text, maxLineWidth);
// doc.text can now add those lines easily; otherwise, it would have run text off the screen!
doc.text(textLines, margin, margin + 2 * oneLineHeight);
// You can also calculate the height of the text very simply:
var textHeight = (textLines.length * fontSize * lineHeight) / ptsPerInch;
doc
.setFont("Helvetica", "bold")
.text(
"Text Height: " + textHeight + " inches",
margin,
margin + oneLineHeight
);

Donut chart image icons centering - Highchart

I am using Highchart pie-donut chart for a project and I'm facing issues regarding the centering of icons within different slices of the donut. I am having 3 slices within the donut chart, and for each slice particular icon (using the URL) needs to be rendered.
Here's the specific code that attaches the icon to the corresponding slice of donut.
var chartIconsUrl = {
'suitcase': 'https://s18.postimg.org/jju1bg1o9/suitcase.png',
'home': 'https://s18.postimg.org/xnrqpb9rt/home.png',
'notes': 'https://s13.postimg.org/a5r39jv8n/notes.png'
}
dataLabels : {
enabled : true,
useHTML : true,
formatter : function() {
if(this.y!=0)
return '<img src = ' + chartIconsUrl[this.key] + '><img>';
},
distance : -30
}
https://jsfiddle.net/dsharm/anva3gaz/.
Please note that icons are rendered at different positions on different browsers, in IE icons are shifted down. I have cross browser compatibility as my requirement as well.
Edit:
formatter: function(){
return '<img style="width:20px; height: 20px" src =' + chartIconsUrl[this.key] + '><img>';
}
I can't directly add the width, height, x and y to the label as I have requirement of variable slice size i.e., y values can change dynamically.

dimple tooltip too wide

I am using dimple.js on a mobile device but when the text is too long for the tool tip is just goes off the screen instead of wrapping down. Is there a way to set a maximum width for the tooltip? I am currently using this code to show only certain info:
s.getTooltipText = function (e) {
return [
"Product Description: " + e.aggField[0],
"Volume: " + e.yValue
];
};
Thanks!
The quick and dirty way would be just to use CSS:
.dimple-tooltip{
width: 200px !important;
}
Note that this won't auto-wrap text though.

ExtJS Quicktip constrains problem

I've got a column renderer defined that creates a HTML fragment which contains the ext.qtip attributes to create a quicktip. All works fine, the image renders in the grid cell, when i hover over the image a tooltip with the larger image is shown ... all nice but the quicktip on the bottom row expands beyond the constraints of the panel, is there any way to make it stay inside the panel boundaries?
var thumbRenderer = function(value, meta, record){
var thumbPath = Config.baseUrl + 'images/thumb/' + record.get('filename');
var previewPath = Config.baseUrl + 'images/big/' + record.get('filename');
return String.format('<img src="{0}" ext:qwidth="312" ext:qtip="<img style=\'margin: 2px 0;width:300px;\' src=\'{1}\' />" width="60" class="pic" />', thumbPath, previewPath);
}
You may want to look at the showAt method:
tip.showAt([x,y]);
Where x and y are the respective x and y co-ordinate positions.
EDIT: You can also use the showBy() method on a QuickTip instance:
http://dev.sencha.com/deploy/dev/docs/source/Tip.html#method-Ext.Tip-showBy

Resources