I have a question regarding Google Charts (Column Charts) in specific.
"How do I make the "date" clickable so I can open up a modal dialog (jQuery) with an external page?"
I have added an example to illustrate what I mean, this is obviously done in Photoshop.
I am able to bring up a alert dialog when I click any of the bars, but that's not really what I am looking for.
I have tried to search for it, but was unable to find something.
Attached is the code I used for making the bars clickable, maybe someone knows how to modify that without having to Google for it.
var handler = function(e) {
var sel = chart.getSelection();
sel = sel[0];
if (sel && sel['row'] && sel['column']) {
var message = "Hi..";
alert(message);
}
}
google.visualization.events.addListener(chart, 'select', handler);
Any assistance would be very much appreciated.
- Robert.
If you use a 'click' handler instead of a 'select' handler, you can more easily interact with other parts of the chart.
Here's an example: http://jsfiddle.net/6LJhv/6/
Your event object, e, will have a targetID property.
This targetID is not well documented, but if you run the debugger, you can get a sense of what IDs look like.
On the various axis charts (Line, Column, etc.) the targetID of the axis labels look something like this: hAxis#0#label#1. To break that down, it means that you clicked on the second label of the first horizontal axis (0 based index).
Given that, we can dissect the targetID to figure out which label you clicked on from the data if it's discrete.
(If your data is continuous, there isn't necessarily a 1:1 relationship with the labels and rows of data)
var handler = function(e) {
var parts = e.targetID.split('#');
if (parts.indexOf('label') >= 0) {
var idx = parts[parts.indexOf('label') + 1];
alert(data.getValue(0, parseInt(idx)));
}
};
google.visualization.events.addListener(chart, 'click', handler);
Related
I am new to D3 /Javascript / html and I just made my first interactive viz. Its 93% done, but I have coded myself into a corner. There is a toggle switch on the graph which changes the numbers from counts to percentages. When the toggle is switched the graph appears, but I can't figure out how to get the graph to render upon loading without the click event while maintaining the functionality of the toggle feature which happens to load the data.
The likely culprits are here:
document.addEventListener('DOMContentLoaded', function () {
//Initialize with vanilla counts
var fileName = "data.csv"
var checkbox = document.querySelector('input[type="checkbox"]');
checkbox.addEventListener('change', function () {
if (checkbox.checked) {
The full code is available here:
https://www.philippou.us/jensweb/interactive_viz.html
How can I get my D3 graph to load without someone clicking on the toggle switch?
Put all the code after "checkbox.addEventListener('change', function () {", i.e., from "if (checkbox.checked) {" down, into a function, e.g., "function drawGraph() { ...}". Calling the function in the change event will be exactly what you're doing now. Then add a call to the function at the end of loading the page, e.g., "[script]drawGraph();[/script]" just before the "[/body]" statement. (Note: I'm using square brackets rather than angle brackets around script and body because they don't display otherwise and I don't know how to make them display. Sorry.)
The situation: My web application shows a map with different trails of interest (my so called POIs) and a sidebar with information about each POI. Selecting a panel of the sidebar, the related POI should be selected/highlighted on the map.
Data and platforms used: I work with Leaflet and JavaScript, no jQuery. The data are added within Leaflet as GeoJSON. The trails are represented as polylines, but I call them POIs (just to clarify). I do not and cannot use jQuery.
What works: The trails (polylines) are added like this:
var pois = L.geoJson(pois,
{
style: style_pois,
onEachFeature: onEachFeature
});
pois.addTo(map);
function onEachFeature(feature, layer)
{
layer.on('click', function (e)
{
sidebar.open('pois');
//get the ID of the clicked POI
number = feature.properties.number;
//Open the accordion tab
var panel = document.getElementsByClassName('accordion-panel');
panel[number-1].style.display="block";
//highlight the selected POI
var selectedFeature = e.target;
selectedFeature.setStyle(style_pois_selected);
});
}
What does not work: Selecting a panel of the accordion, I get the ID of the related trail (polyline), but I cannot access and highlight this certain polyline feature within Leaflet.
This is the JavaScript code, where the accordion behavior is controlled:
var acc = document.getElementsByClassName('accordion');
var panel = document.getElementsByClassName('accordion-panel');
for (var i = 0; i < acc.length; i++)
{
(function(index){
acc[i].onclick = function()
{
// Toggle between adding and removing the "active" class,
//to highlight the button that controls the panel
this.classList.toggle("active");
//Toggle between hiding and showing the active panel
var panel = this.nextElementSibling;
console.log("panel " + acc[0]);
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
var myIndex = index + 1;
alert("INDEX " + myIndex);
}
})(i);
}
Question: Is there a possibility, based on a layer that is included as GeoJSON in Leaflet to access a certain feature based on any property?
What I tried: I only came across solutions where the different behavior of a certain polyline is accessed within the onclick function. There it is easily possible to apply another color (setStyle). I need to access it from outside the layer. I already tried to again load the pois layer as I did above, just inside the accordion JavaScript and filter it for the certain ID so that only the one polyline is represented, but it only gave me an error that it is an invalid GeoJSON object (maybe a scope issue?).
I appreciate any help!
For anyone who might come across the same problem - I found a solution.
I looked for hours to find out, if one can access a specific feature from a GeoJSON layer within Leaflet, but it seemed that there is no such method.
Although there is no official method for it, for me worked the following.
When inside the accordion, one can just access the already loaded GeoJSON dataset, in my case pois and get the layer (this actually gets the feature, not the layer! a bit misleading) at the index position. For this one, a style can then be applied.
pois.getLayer(index).setStyle(style_pois)
To read out the index of the clicked accordion panel, I asked another question and was pointed in the right direction: Simple JavaScript accordion - how to get the index of the clicked panel?
NOTE: I'd recommend you to set some JFiddle to reproduce your problem.
A solution I often use is to set the ID/Class property in each of the markers/points:
$.getJSON("data/displacement.geojson", function(data){
pathsLayer = L.geoJson(data,{
className: function(feature){ //Sets the class on element
//Assuming your JSON has a property called ID
return "ID-" + feature.properties.ID;
},
style: function (feature) {
//If needed, you can also set style based on properties
},
})
});
After that you can set a global variable to keep record of the selection ID, and then use it to select and modify the specific element. Since Leaflet uses SVG elements, I recommend you to use D3.js to select/modify elements, for instance:
var selectedID = null; //Declare global variable
// You modify selectedID by actions on sidebar, e.g.:
selectedID = 001
d3.select(".ID-" + selectedID)
.transition() //You can set easily transitions on attribute changes
.duration(1000) // in ms
.attr("attributeName", "attributeValue");
You can find an example here (although I know is a bit tricky to read using View Page Source (Ctrl + U))
I am using a canvas to present several UI components. I am setting canvas.title to present the help for each component.
...
if(mouse.y >= y && mouse.y <= y + w && mouse.over){
if(currentId !== tool.id){
canvas.title = tool.help;
}
currentId = tool.id;
...
The problem is that when the mouse moves the tool tip is hidden and will not re display until I move the mouse out and then move back onto the canvas.
I would like to change the behaviour so that the tool tip displays again when I hover over another UI component without leaving the canvas element?
Implementing your custom tooltip gives more freedom and control.
This is a simple example http://jsfiddle.net/mynetx/5qbP3/
You can take ideas and build from here. Another advantage is control over the CSS which in cases like yours, where you want to provide help.
window.addEventListener("load", function () {
var couponcodes = document.getElementsByClassName("couponcode");
for (var i = 0; i < couponcodes.length; i++) {
couponcodes[i].addEventListener("mouseover", function () {
var coupontooltip = this.getElementsByClassName("coupontooltip")[0];
coupontooltip.removeAttribute("style");
});
couponcodes[i].addEventListener("mouseout", function () {
var coupontooltip = this.getElementsByClassName("coupontooltip")[0];
coupontooltip.style.display = "none";
});
} });
Tooltips are part of the system the browser runs in and sadly aren't accessible in any way from JavaScript.
I would recommend implementing your own tooltip, which is not very hard (both on canvas and using an extra element).
If you are worried about accessibility—it's possible to give an element "tooltip" role: http://accessibility.athena-ict.com/aria/examples/tooltip.shtml
You can use fabric.js. see this.
I'm writing a vb.net program to automate and manage an online game. I'm using the Awesomium webcontrols to display and manipulate the pages of the game.
There is a point where I need to grab the data that's not shown in the source until the user hovers over a certain element, how can I use javascript (Not jquery please) to hover over it programatically until the data I need becomes available and then grabbed?
I apologise if this has been asked before (Which it has but from the perspective of someone who owns the web page) but I have been searching for hours for a solution and cant find anything.
What I've tried to use but failed is:
function findBpDate(){
document.getElementById('tileDetails').children[1].children[0].children[1].children[0].fireEvent('onmouseover');
return document.getElementsByClassName('text elementText')[0].textContent;
}
This returns "undefined" when it calls back to my application, I'm certain I'm pointing to the right DOM elements though.
This is what I want the javascript to "hover" on:
<span class="a arrow disabled">Send troops</span>
Once this element has been "hovered" on, this elements text changes to the text I need to grab:
<div class="text elementText">Beginners protection until 20/07/13 07:51 am.</div>
I've shown above what the element looks like when the mouse "hovers" on the element I need it to, however this changes a lot depending on which element the user hovers over while playing the game, from what i gather it's where the source keeps the text for each tooltip in the game.
So I need a function that will hover over a certain element and then while it's hovering, grab the text from the tooltip text/"text elementText" element.
Try WebView.InjectMouseMove(x, y).
Something like
public Point GetElementPosition(dynamic element)
{
dynamic rect = element.getBoundingClientRect();
using (rect)
{
return new Point(rect.left, rect.top);
}
}
dynamic element = webView.ExecuteJavascriptWithResult("document.getElementById('id')");
Point pos = GetElementPosition(element);
webView.InjectMouseMove(pos.X, pos.Y);
this is 10x easier with js/dom. http://jsfiddle.net/pA2Vd/
Do this...assuming you can get reference to elements somehow using by Id would have been lot easier.
var elm = document.getElementsByClassName('a arrow disabled')[0];
var txt = document.getElementsByClassName('text elementText')[0];
var evt = new Event('mouseover');
elm.dispatchEvent(evt);
var status = txt.innerText;
(helpfuL stuff down) otherwise you need to capture event, detect who fired it, check if that has this class and tag name. Lot of processing.
var txt,spn,status='';
document.getElementByTagName('span').forEach(function(d){
if (d.tagName=="div" && d.className == 'text elementText'){
var txt = d;
}
}
window.onmouseover = function(e) {
var elm = e.target;
if (elm.tagName=="SPAN" && elm.className == 'a arrow disabled') {
status=txt.innerText;
}
}
I want to drag and drop images into an aloha editable field.
I am looking at the at.tapo.aloha.plugins.Image plugin which seems great.
However, i need to adapt this plugin in order to work with thumbnail. I drag the thumbnail and when I drop it into the aloha editable, the html code is modified on the fly in order to use the real image.
GENTICS.Aloha.EventRegistry.subscribe(GENTICS.Aloha, 'editableCreated', function(event, editable) {
var the_obj = editable.obj;
jQuery(editable.obj).bind('drop', function(event){
var e = event.originalEvent;
var files = e.dataTransfer.files;
var count = files.length;
if (count < 1) {
var node = e.dataTransfer.mozSourceNode;
if (node.tagName === 'IMG') {
var html = '<img ....>'; //build the real image html code
/// The current selection but I want the drop position
var range = GENTICS.Aloha.Selection.getRangeObject();
if (!jQuery.isEmptyObject(range)) {
GENTICS.Utils.Dom.insertIntoDOM(jQuery(html), range, the_obj);
}
return false;
}
return true;
}
}
It works ok when something is selected in the aloha field. I can get a range and insert the html into the DOM at the selection position.
However, I would like to get a range object that correspond to the place where my image is dropped. How to do that?
Thanks in advance for ideas.
There isn't an easy way that I know of to do this in general. You could obtain pixel coordinates for the drop point (possibly from a mousemove event) and then attempt to get a range for that point. For that task, the answer to the following question sums it up nicely:
Creating a collapsed range from a pixel position in FF/Webkit
Tim Down showed me that there is no easy way and I finally used a workaround:
GENTICS.Aloha.EventRegistry.subscribe(GENTICS.Aloha, 'editableCreated', function(event, editable) {
var the_obj = editable.obj;
jQuery(editable.obj).bind('drop', function(event){
setTimeout(function () {
//at this point the html is updated and can be postprocessed
//in order to turn thumbnails into the real image
//force the focus in order to make sure that the editable is activated
//this will cause the deactivated event to be triggered, and the content to be saved
the_obj.focus();
}, 0);
});
});