ExtJS Quicktip constrains problem - tooltip

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

Related

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.

Openlayers 3 Feature Label Background

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

Highcharts - resize legend on chart resize?

Is there anyway to dynamically set a specific width of legend items when resizing the chart? I have some really long item names possible in the legend so I need to specify a width to force the text to wrap, but I would like to change the width when the width the chart changes. Thanks.
I found a better work around for this:
chart.legend.options.width = newwidth;
chart.legend.itemStyle.width = newwidth;
for(var index in this.chart.series) {
chart.legend.destroyItem(chart.series[index]);
}
chart.legend.render()
Generally it is not possible, but you can disable highcharts legend, and prepare your own div (positioned absolutely) which will include list of all series and click event. Simple example is available here
$legend = $('#customLegend');
$.each(chart.series[0].data, function (j, data) {
$legend.append('<div class="item"><div class="symbol" style="background-color:'+data.color+'"></div><div class="serieName" id="">' + data.name + '</div></div>');
});
$('#customLegend .item').click(function(){
var inx = $(this).index(),
point = chart.series[0].data[inx];
if(point.visible)
point.setVisible(false);
else
point.setVisible(true);
});
http://jsfiddle.net/N3KAC/10/
Than only what you need is adapt this to your chart by catching $(window).resize() function and resize element.

jquery ui sortable - clicking scrollbar breaks it

Scrolling a div that is within a .sortable() container will start dragging the div when you release the scrollbar
In the fiddle, there are 3 different sortables, 1 of them is a scrolling one
http://jsfiddle.net/wnHWH/1/
Bug: click on the scrollbar and drag it up or down to scroll through the content, when you release the mouse, the div starts to drag, which makes it follow your mouse around and there is no way to unstick it without refreshing the page.
You can use .mousemove event of jquery like this:
$('#sortable div').mousemove(function(e) {
width = $(this).width();
limit = width - 20;
if(e.offsetX < width && e.offsetX > limit)
$('#sortable').sortable("disable");
else
$('#sortable').sortable("enable");
});
I have create fiddle that works here http://jsfiddle.net/aanred/FNzEF/. Hope it meets your need.
sortable() can specify a selector for a handle much like draggable() does. Then only the matched elements get the click events. You specify the handle selector like this:
$('#sortable').sortable( {handle : '.handle'});
You already have most of what you need for the rest. The inner div on your overflowing element makes a suitable handle, like this:
<div style="height: 200px;overflow:auto">
<div class="handle" style="height: 300;">
blah
blah
blah
Then you need to restore the sortability of everything else. You'd think you could just give those divs the handle class, but it's looking for children, so you need to wrap all of them like so:
<div><div class="handle">asadf</div></div>
Modified fiddle
Supplement to SubRed's answer:
This worked perfectly for my needs. However, rather than rely on the width of the scrollbar being 20 pixels (as above), I used the code from:
How can I get the browser's scrollbar sizes?
This allows the code to handle different scrollbar widths on different setups. The code is pasted here for convenience:
function getScrollBarWidth ()
{
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild (inner);
document.body.appendChild (outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild (outer);
return (w1 - w2);
}
I've also used the width value for the height of the scrollbar and modified SubRed's code to suit. This now works with one or both scrollbars.
I also used code from:
Detecting presence of a scroll bar in a DIV using jQuery?
To determine the presence of either scroll bar and adapted the turning on/off of the sortable code accordingly.
Many thanks.

How do I adjust where the calendar appears for the datePicker in the Grails UI plugin without the position changing when the page is resized?

I wanted to change where the calendar appeared for the datePicker portion of the Grails UI plugin. After a bit of digging, I found it in the InputTagLib.groovy file:
out << """
YAHOO.util.Event.on("${showButtonId}", "click", function() {
var buttonRegion = YAHOO.util.Dom.getRegion('${showButtonId}');
var buttonHeight = buttonRegion.bottom - buttonRegion.top;
var buttonWidth = buttonRegion.right - buttonRegion.left;
var xy = YAHOO.util.Dom.getXY('${showButtonId}');
var newXY = [xy[0] + buttonWidth, xy[1] + buttonHeight];
YAHOO.util.Dom.setXY('${id}_calContainer_c', newXY);
GRAILSUI.${jsid}Panel.show();
if (YAHOO.env.ua.opera && document.documentElement) {
// Opera needs to force a repaint
document.documentElement.className += "";
}
});"""
The position is set on this line:
YAHOO.util.Dom.setXY('${id}_calContainer_c', newXY);
The YAHOO.util.Dom.setXY() method takes two arguments.
The first argument of the setXY method is either the ID of an HTMLElement, or an actual HTMLElement object. The second argument is an array containing two values: [x, y] where x is the distance from the left edge of the document, and y is the distance from the top edge of the document.
Source: http://developer.yahoo.com/yui/examples/dom/setxy.html
So I can easily adjust where the calendar appears by changing the values in the newXY variable that is passed to the setXY method and it works fine.
However, if I resize the page, the calendar positions its top left corner directly under the showButton's bottom left corner. What is it that makes the repositioning happen when the page is resized and how can I resolve it?
EDIT : A little more info:
This happens in the most recent versions of IE, Firefox, and Chrome
If I resize the page and then click the button to show the calendar, the calendar shows in the expected place but it will reposition if I resize the page again once the calendar is open

Resources