JavaScript Mouse position over an element (code not working) - mouse

I want to display the mouse position when its inside an element.. heres the code:
Mouse Events Example
function GetMousePositionInElement(ev, element)
{
var osx = element.offsetX;
var osy = element.offsetY;
var bottom = osy + element.height();
var x = ev.pageX - osx;
var y = bottom - ev.pageY;
return { x: x, y: y, y_fromTop: element.height() - y };
}
function handleEvent(oEvent) {
var oTextbox = document.getElementById("txt1");
var elem = document.getElementById("div1");
var xp = GetMousePositionInElement(oEvent, elem).x;
var yp = GetMousePositionInElement(oEvent, elem).y;
oTextbox.value += "\n x = " + xp + "y= " + yp;
}
Use your mouse to click and double click the red square.
div style="width: 100px; height: 100px; background-color: red"
onmouseover="handleEvent(event)"
id="div1"> /div
textarea id="txt1" rows="15" cols="50"> /textarea>
There is a problem in the code. Mouse position is not displayed inside the texArea. What changes do i have to make for the code to work and work correctly? (of-cource not all of the code is displayed and i removed some of the < and > inoder to show you some parts of the code that are not displayed otherwise but the code syntax is correct, thats not the problem)
Thank you.

var osy = element.offsetY;
There's no such property as offsetY. You may be thinking of offsetTop. However note the offsetLeft/​Top values are relative to the offsetParent not the page. If you want page-relative co-ordinates you would need to loop through offsetParents, or, since you seem to be including jQuery, call its offset function that does just that:
var offset= $(element).offset();
var osx= offset[0], osy= offset[1];
var bottom = osy + element.height();
element is a DOM HTMLDivElement object, not a jQuery wrapper object, so it doesn't have the height() method. Either add the wrapper:
var bottom= osy+$(element).height();
or use the equivalent DOM method:
var bottom= osy+element.offsetHeight;
var y = bottom - ev.pageY;
Note pageY is not part of the DOM Events standard and also not available in IE. You can calculate it by using the standard clientY property and adjusting for the page's scrollTop. Again, jQuery does this for you, adding the Firefox pageY extension to all browsers, when you use its own methods to bind your event handler:
$('#div1').mouseover(handleEvent);
instead of the inline onmouseover=... event handler attribute.

Related

ChartJS: Custom tooltip always displaying

Im using ChartJS to create a graph on my website.
Im trying to create a custom tooltip. According to the documentation, this should be easy:
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
custom: function(tooltip) {
// tooltip will be false if tooltip is not visible or should be hidden
if (!tooltip) {
return;
}
}
}
}
});
My problem is that the tooptip is never false and because of this my custom tooltip is always displayed.
Please see this JSFiddle (line 42 is never executed)
Question: Is it a bug that tooltip is never false, or am I missing something?
The custom tooltip option is used for when you want to create/style your own tooltip using HTLM/CSS outside of the scope of the canvas (and not use the built in tooltips at all).
In order to do this, you must define a place outside of your canvas to contain your tooltip (e.g. a div) and then use that container within your tooltips.custom function.
Here is an example where I used a custom tooltip to display the hovered pie chart section percentage in the middle of the chart. In this example I'm generating my tooltip inside a div with id "chartjs-tooltip". Notice how I interact with this div in my tooltips.custom function to position and change the value.
Also, the correct way to check if the tooltip should be hidden is to check it's opacity. The tooltip object will always exist, but when it should not be visible, the opacity is set to 0.
Chart.defaults.global.tooltips.custom = function(tooltip) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set Text
if (tooltip.body) {
var total = 0;
// get the value of the datapoint
var value = this._data.datasets[tooltip.dataPoints[0].datasetIndex].data[tooltip.dataPoints[0].index].toLocaleString();
// calculate value of all datapoints
this._data.datasets[tooltip.dataPoints[0].datasetIndex].data.forEach(function(e) {
total += e;
});
// calculate percentage and set tooltip value
tooltipEl.innerHTML = '<h1>' + (value / total * 100) + '%</h1>';
}
// calculate position of tooltip
var centerX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2;
var centerY = ((this._chartInstance.chartArea.top + this._chartInstance.chartArea.bottom) / 2);
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = centerX + 'px';
tooltipEl.style.top = centerY + 'px';
tooltipEl.style.fontFamily = tooltip._fontFamily;
tooltipEl.style.fontSize = tooltip.fontSize;
tooltipEl.style.fontStyle = tooltip._fontStyle;
tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
};
Here is the full codepen example.
I hope that helps clear things up!

References in axis using chart.js (or another library)

Im trying to make a graph like this:
https://www.google.com/finance?q=BCBA:PAMP
I have a line chart in chart.js, now I want to add labels (like the letters A, B, C) for certain dates.
Can't find a doc/example to start from. Any idea?
If its more simple to do with another library a recommendation is more than welcome.
Thanks!
Unfortunately, there is no native support in chart.js for what you are wanting. However, you can certainly add this capability using the plugin interface. This requires that you implement your own logic to draw the canvas pixels at the locations that you want them. It might sound challenging, but its easier than it sounds.
Here is an example plugin that will add a value above specific points in the chart (based upon configuration).
Chart.plugins.register({
afterDraw: function(chartInstance) {
if (chartInstance.config.options.showDatapoints || chartInstance.config.options.showDatapoints.display) {
var showOnly = chartInstance.config.options.showDatapoints.showOnly || [];
var helpers = Chart.helpers;
var ctx = chartInstance.chart.ctx;
var fontColor = helpers.getValueOrDefault(chartInstance.config.options.showDatapoints.fontColor, chartInstance.config.options.defaultFontColor);
// render the value of the chart above the bar
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize + 5, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillStyle = fontColor;
chartInstance.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
if (showOnly.includes(dataset.data[i])) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
var scaleMax = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
var yPos = (scaleMax - model.y) / scaleMax >= 0.93 ? model.y + 20 : model.y - 5;
ctx.fillText(dataset.data[i], model.x, yPos);
}
}
});
}
}
});
It allows you to configure which points you want to annotate using this new configuration. The showOnly option contains the points that you want to label.
options: {
showDatapoints: {
display: true,
showOnly: [3, 10, 9]
},
}
Obviously, this only adds the datapoint value at the specified points, but you can just change the plugin to paint whatever you want to show instead. Simply replace ctx.fillText(dataset.data[i], model.x, yPos) with different code to render something different on the canvas.
Here is a codepen example to show you want it looks like.

sencha touch n3dv charts

I've added a nvd3 chart to my sencha touch app.
Apparently though the size of the box where the chart will be inserted is undefined at the time the chart is created. This turns out in a graph with standard dimensions (960x350 approx), way too large!
How can I modify the widht and height of the chart? The visual error I get is that the chart has a larger width, the component containing it are smaller and the chart is not completely
visible (it's like it misses a resize effect to adapt its size to the containing box).
My code, which is inside a sencha component goes like this:
nv.addGraph(Ext.bind(function(){
var chart = nv.models.discreteBarChart()
.x(function(d) { return d.label; })
.y(function(d) { return d.value; })
.staggerLabels(true)
.tooltips(false)
.showValues(true);
var w = 550;
var h = 280;
var svg = d3.select(this.innerElement.dom).append('svg');
// setting axis property doesn't work:
var x = d3.scale.ordinal()
.domain(d3.range(10))
.rangeRoundBands([0, w], 1);
chart.xAxis
.tickFormat(d3.format(',f'));
chart.xAxis.scale(x);
chart.yAxis
.tickFormat(d3.format(',f'));
//setting svg properties doesn't work:
svg.attr("width", w)
.attr("height", h);
svg.datum(this.getChartData()).transition().duration(500).call(chart);
//if I comment this, nothing changes, what is this method for?
nv.utils.windowResize(chart.update);

jqplot tooltip display on touch instead of jqplotDataHighlight or higlightMouseOver or highlightMouseDown

I am using the jqplotDataHighlight option to display the tooltip on a chart on MouseOver.
$("#"+sTargetId).bind('jqplotcustomDataHighlight',
function (ev, seriesIndex, pointIndex, data) {
var chart_left = $("#"+sTargetId).offset().left,
chart_right = ($(window).width() - ($("#"+sTargetId).offset().left + $("#"+sTargetId).outerWidth())),
chart_top = $("#"+sTargetId).offset().top,
x = oPlot.axes.xaxis.u2p(data[0]), // convert x axis units to pixels
y = oPlot.axes.yaxis.u2p(data[1]);;
var tooltipData = data[1]*scale;
$('#tooltip').css({left:chart_left+x, top:chart_top+y, marginRight:chart_right});
$('#tooltip').html('<span style="font-family: Arial;font-size:'+sTooltip+';font:bold;color:#000000;">' +sXDisplay+': '+ tooltipData + '</span>');
$('#tooltip').show();
});
$("#"+sTargetId).bind('jqplotcustomDataUnhighlight',
function (ev, seriesIndex, pointIndex, data) {
$('#tooltip').empty();
$('#tooltip').hide();
});
It works fine.On iPad, i want the tooltip to be displayed on some touch event.How can i implement it?
// prop: highlightMouseOver
// True to highlight slice when moused over.
// This must be false to enable highlightMouseDown to highlight when clicking on a slice.
this.highlightMouseOver = true;
// prop: highlightMouseDown
// True to highlight when a mouse button is pressed over a slice.
// This will be disabled if highlightMouseOver is true.
this.highlightMouseDown = false;
I have observed that only the above two options are available. How can I implement it on touchstart or so?
Displaying the tooltip on doubleclick or any other event would also be helpful
Maybe you already figured this out. Here's what works for me. I am using jquerymobile, in jquery.jqplot.js version 0.9.7r635 line No: 2290 change mousemove to vmousemove. If you are using cursor: {followMouse: true} , then things should work out of the box, I have a fixed position for my tooltip, but on mousemove the top and left values did not get applied so i hardcoded the top and left for the tooltip div .jqplot-cursor-tooltip to appear in the same position as it does on click. Although its not a very good solution but I havent seen weird behavior till now. Hope this helps !

VEMap Pan triggers VEMap.onclick

I'm using the Virtual Earth (or Bing!...) SDK and need to attach an event when someone clicks the map. Unfortunately panning the map also triggers the onclick event. Does anyone know of a work around?
function GetMap(){
map = new VEMap('dvMap');
map.LoadMap(new VELatLong(35.576916524038616,-80.9410858154297), 11, 'h',false);
mapIsInit = true;
map.AttachEvent('onclick', MapClick);
}
function MapClick(e){
var clickPnt = map.PixelToLatLong(new VEPixel(e.mapX,e.mapY));
Message('Map X: ' + clickPnt.Longitude + '\nMap Y: ' + clickPnt.Latitude + '\nZoom: ' + e.zoomLevel);
}
I'm encountering the same problem. It is certainly not what I would expect, a click event in my terminology implies that the distance between mouseDown and mouseUp is below a certain threshold.
Here is some code that works in my experiments:
<script type="text/javascript">
var mouseDownLocation;
var mouseClickThreshold = 5;
function init()
{
var map = new VEMap('myMap');
map.LoadMap(new VELatLong(-27.15,153),8,'r' ,false);
map.AttachEvent("onmousedown", function(e) {
var x = e.mapX;
var y = e.mapY;
mouseDownLocation = new VEPixel(x, y);
});
map.AttachEvent("onmouseup", function(e) {
var x = e.mapX;
var y = e.mapY;
if(Math.abs(mouseDownLocation.x - x) +
Math.abs(mouseDownLocation.y - y) > mouseClickThreshold) {
return;
}
pixel = new VEPixel(x, y);
var LL = map.PixelToLatLong(pixel);
document.getElementById("myMapInfo").innerHTML =
"Pixel X: " + x + " | Pixel Y: " + y +
"<br /> LatLong: " + LL +
"<br/>" + e.eventName;
});
}
</script>
The message will be displayed only if the mouse didn't move too much between the down and up events, i.e. a normal click should trigger it, a drag shouldn't.
This is using the VE API in version 6.2 and expects two divs with IDs "myMap" and "myMapInfo". It's also code that's experimental and could be improved upon, but the general approach seems ok.
It all depends on what you're trying to do. You could check for which mouse button was pressed during the onclick event handler. For example: If it was the Left Mouse Button then do nothing, else if it's the Right Mouse Button then do your logic to display a message, or plot pushpin, etc.
To clarify, only Panning the Map using the Mouse will trigger the onclick event. If you use the little arrows on the navigation dashboard, it will not trigger the onclick event.
Thanks Peter, that is working great with 6.3 as well. I'm discovering Bing maps and I'm a bit lost in the event handlers, so that helped!