I have a working Google Combochart. Now i want to remove the highlight on specific moments when i hover over an item in the legend. I used the option "enableInteractivity", but this also removes things like the tooltips.
I want to keep the tooltips of course. I can't seem to find anything on the internet about how this is possible. I know i can disable the tooltips only, but not a method to disable this highlighting (what i want)..
Anybody has an idea how i can achieve this?
Thanks in advance!
Following this approach for styling on hover, you can get rid of the grey outline highlighting on hover by applying this css style.
#mychart svg g g g g rect {
stroke-width:0px;
}
There is no built-in method to do this. The highlights are drawn in to the SVG and the tooltips are also drawn by the google internal charts API code. So either you'd have to find a way to stop the highlights from being drawn in to the SVG (while still allowing the tooltips), or to disable interactivity and implement your own tooltips like this answer does. Answer quoted below (by jeffery_the_wind):
I ended up making a custom tool-tip pop-up that is working pretty
well.
Assuming your div for the bubble chart is defined like this:
<div id="bubble_chart_div"></div>
Then I used the JavaScript below. Please note that I left out that
stuff about how to set up your google chart data and loading the
google charts package. This code just shows how to get your custom
toolip popup.
var mouseX;
var mouseY;
$(document).mousemove( function(e) {
mouseX = e.pageX;
mouseY = e.pageY;
});
/*
*
*instantiate and render the chart to the screen
*
*/
var bubble_chart = new google.visualization.BubbleChart(document.getElementById('bubble_chart_div'));
bubble_chart.draw(customer_product_grid_data_table, options);
/*
* These functions handle the custom tooltip display
*/
function handler1(e){
var x = mouseX;
var y = mouseY - 130;
var a = 1;
var b = 2;
$('#custom_tooltip').html('<div>Value of A is'+a+' and value of B is'+b+'</div>').css({'top':y,'left':x}).fadeIn('slow');
}
function handler2(e){
$('#custom_tooltip').fadeOut('fast');
}
/*
* Attach the functions that handle the tool-tip pop-up
* handler1 is called when the mouse moves into the bubble, and handler 2 is called when mouse moves out of bubble
*/
google.visualization.events.addListener(bubble_chart, 'onmouseover', handler1);
google.visualization.events.addListener(bubble_chart, 'onmouseout', handler2);
Related
I have created a webpage with multiple charts using D3 and Object Oriented Programming.
Working code link--> https://codepen.io/mohan-ys/pen/LYLwqrK
The problem I am facing is that the tooltip is not at the mouse location, it is somewhere else.
I tried using d3.event.pageX & d3.event.pageY instead of vis.mouse[0] & vis.mouse[1] which is in the code above but it does not work.
I am getting the tooltip as shown. When the mouse is at the right end of the graph, the tool tip moves further right, it gets closer somewhere in the middle & it goes to the other side by the time the cursor is on the left end of the chart!
The page is resized, then it is a totally different behaviour!
Can anyone help get the tooltip right a the mouse pointer (top-left corner at the mouse pointer) for all graphs & even when the page is resized (the graphs scale with page resize).
The vertical line follows the mouse perfectly!, so, if there is another way of creating the tooltip instead of a div, that is also ok for me.
The underlying problem is addressed here but the answer doesn't directly solve your problem. Basically, there's a second and optional argument to d3.pointer called target such that:
If target is not specified, it defaults to the source event’s
currentTarget property, if available. If the target is an SVG element,
the event’s coordinates are transformed using the inverse of the
screen coordinate transformation matrix...
You can make use of this argument per below noting that it will break your vertical tracking line if you try and just update vis.mouse:
// mouse moving over canvas
vis.mouse = d3.pointer(event); // keep this for the vertical tracking line
vis.mouse2 = d3.pointer(event, d3.select(vis.chartLocation)); // <--- NEW VARIABLE!
Now vis.mouse2 has a relative x and y - so use them where you set the style of the div:
d3
.select(vis.chartLocation)
.selectAll("#tooltip")
.html((d, i) => {
vis.xDate = d.values[vis.idx - 1].date;
return vis.xDate.toLocaleDateString("pt-PT");
})
.style("display", "block")
.style("left", vis.mouse2[0] + "px") // use vis.mouse2
.style("top", vis.mouse2[1] + "px") // use vis.mouse2
The clue is in that your first selection is vis.chartLocation.
This application is made with Easeljs, to work in HTML5 canvas.
I want to be able to draw different kinds of arrows on the board. I tried inserting arrows as images and then making them draggable and resizable, but that made these images pretty ugly.
To illustrate:
Field to draw on
Arrows to draw on the field
The functionality should be as follows:
Click on the button
Draw a line
At mouseup event: convert line into corresponding arrow
Arrow should be draggable and resizable
How would I get this result?
You can fairly easily draw arrows using the Graphics API. I spent about 20 mins making this demo:
http://jsfiddle.net/lannymcnie/ukjb1g2g/2/
http://jsfiddle.net/lannymcnie/ukjb1g2g/3/
Code:
var w = startX - endX;
var h = startY - endY;
var lineLength = Math.sqrt(w*w+h*h);
arrow.graphics.clear().setStrokeStyle(3).beginStroke("#000").moveTo(0,0);
// Logic to draw to the end. This is just a straight line
arrow.lineTo(lineLength-arrowHeadSize, 0);
arrow.graphics.beginFill("#000");
arrow.graphics.drawPolyStar(lineLength, 0, arrowHeadSize, 3);
// Rotate
arrow.rotation = Math.atan2(h, w) * 180/Math.PI;
Drawing it straight and rotating it is the easiest way to add effects to the line. The demo I posted draws a sort of sine-wave like one of your examples. There is some more magic in there to make it the right length, etc.
Im using snap.svg an snap.svg.zpd libraries. Same issue I have if I use snap.svg and jQuery panzoom library combination.
Code sample you can find here.
var mySvg = $("#plan")[0];
var snap = Snap("#plan");
//create an image
var imagePlan = snap.image("http://upload.wikimedia.org/wikipedia/commons/4/42/Cathedral_schematic_plan_fr_vectorial.svg", 10, 10, 900, 500);
var group = snap.group(imagePlan);
snap.zpd();
var pt = mySvg.createSVGPoint(); // create the point;
imagePlan.click(function(evt)
{
console.log(evt);
pt.x = evt.x;
pt.y = evt.y;
console.log(mySvg.getScreenCTM().inverse());
//When click, create a rect
var transformed = pt.matrixTransform(mySvg.getScreenCTM().inverse());
var rect1 = snap.rect(transformed.x, transformed.y, 40, 40);
group.add(rect1);
});
Problem is...if you click on initial svg it will add rectangle to the mouse position. If you pan/zoom image and then add rectangle it will be shiffted.
It looks like problem is in method mySvg.getScreenCTM().inverse(). Matrix returned is always same one, panning and zooming does not change it. It always use matrix from initialy rendered svg. However, if I inspect svg element, I can see that pann/zoom change transform matrix directly on element (image below).
Does anybody know how to fix this. My requirement is to be able to drag and drop elements outside svg into svg on any zoom scale or pan context, so I need transformation from mouse click point to svg offset coordinates. If you know any other approach or any other library combination that could done this, it would be ok for me.
Thanks in advance.
Problem is, the transform isn't in mySvg. Its on the 'g' group element thats inside the svg. Zpd will create a group to operate on as far as I know, so you want to look at that.
To hightlight this, take a look at
console.log(mySvg.firstElementChild.getScreenCTM().inverse());
In this case its the g element (there's more direct ways of accessing it, depending on whether you want to just work in js, or snap, or svg.js).
jsfiddle
Its not quite clear from your description where you want the rect (within the svg, separate or whatt) to go and at what scale etc though, and if you want it to be part of the zoom/panning, or static or whatever. So I'm not sure whether you need this or not.
I'm guessing you want something like this
var tpt = pt.matrixTransform( mySvg.firstElementChild.getScreenCTM().inverse() )
var rect1 = snap.rect(tpt.x, tpt.y, 40, 40);
I've got a canvas on which I can add layers, these layers I can move, select, rotate, resize etc. Below the canvas I display the properties of the layer (x, y, width, height).
What I am trying to do is when I change the values in the textboxes containing the x and y coördinates the layer should be repositioned to the coördinates I typed in.
I've tried several things but everything seems to mess up the canvas, I am using this to move the layer on mousemove now:
else if (layerState == MOVING && mouseDown) {
selectedLayer.offsetX += e.pageX - canvasOffsetX - mousePrevX;
selectedLayer.offsetY += e.pageY - canvasOffsetY - mousePrevY;
drawMarker(selectedLayer);
}
And I use this to get the x and y of the layer:
document.getElementById('x').value = Math.round(layer.offsetX*100)/100;
document.getElementById('y').value = Math.round(layer.offsetY*100)/100;
A working example of my canvas and the code can be found here:
http://cdpn.io/fjzcv
I've also tried to work with these examples but couldn't get any of them to work:
http://chimera.labs.oreilly.com/books/1234000001654/ch03.html#text_arranger_version_2.0
http://fabricjs.com/controls/
I have tried setting an eventListener on the texboxes but when I do this the canvas will dissapear.
If anyone knows how to do this it would be great!
EDIT:
I found out a way to change the coördinates onchange with the textbox but now I can just change them to a set number instead of taking the value I filled in the textbox:
document.getElementById('x').onchange=function(){selectedLayer.offsetX = 100;
drawMarker(selectedLayer);
};
document.getElementById('y').onchange=function(){selectedLayer.offsetY = 100;
drawMarker(selectedLayer);
};
Anyone knows how to get it to move to the filled in coördinate?
I tried editing the HTML on the code pen and I think this should work.
Firstly add an event listener to your text boxes, where you've got the canvas ones.
document.getElementById('x').addEventListener('onchange',updatePos,false);
canvas.addEventListener('mousemove', mouseMoveEvent, false);
....
Then create a similar function to your mouseMoveEvent(e) to change the selected layer values
function updatePos(e) {
var temp = document.getElementById('x').value;
selectedLayer.offsetX = canvas.offsetX + temp;
drawMarker(selectedLayer);
}
Obviously you may need to add in validation or change this to suit your code, but it should get the object moving around.
You may have seen JavaScript sliders before:
http://dev.jquery.com/view/tags/ui/1.5b2/demos/ui.slider.html
What I'm envisioning is a circular slider. It would consist of a draggable button at one point on the circle -- and that button can be dragged anywhere along the ring. The value depends on what position the button is at (think of a clock).
define a center point c
current mouse point at m
in your mouse drag event handler, you'd have
var dx = m.x-c.x;
var dy = m.y-c.y;
var scale = radius/Math.sqrt(dx*dx+dy*dy);
slider.x = dx*scale + c.x;
slider.y = dy*scale + c.y;
radius would be some preset value of the slider,
How about this: http://www.thewebmasterservice.com/dev-blog/curved-rounded-or-circular-sliders-javascript-jquery-ui
Some explanations and a demo.
I have written a jQuery plugin which supports full/half circle sliders.
Demo Page & Documentation
Check the jQuery roundSlider plugin from here http://roundsliderui.com/. This is what you want exactly.
This roundslider having the similar options like the jQuery ui slider. It support default, min-range and range slider type. Not only the round slider it also supports various circle shapes such as quarter, half and pie circle shapes.
For more details check the demos and documentation page.
Please check the demo from jsFiddle.
Related answers: https://stackoverflow.com/a/31367164/1845801 and https://stackoverflow.com/a/31369265/1845801
Screenshots: