I have a leaflet project with around 150 points that should be displayed. The idea is to show the progress of a project, therefore there are 257 symbols which could be assigned to a point. And there is also a pop up which display additional infos.
The "database" is an excel sheet which gets updated regularly. So I have a python script which updates my leaflet script. This part is running fine and does what it should.
Current code
var map = L.map('map').setView([47.0, 9.0], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// show the scale bar on the lower left corner
L.control.scale({imperial: false, metric: true}).addTo(map);
var symb_A2_22_1 = L.icon({
iconUrl: 'folder/KB-11.png',
iconSize: [42, 20]
});
var A2_22_1 = L.marker([47.4678,8.7049],{icon: symb_A2_22_1}).addTo(map)
A2_22_1.bindPopup("<b>A2-22-1</b><br>x<br>PWD<br>x<br>x")
var symb_A2_22_100 = L.icon({
iconUrl: 'folder/RS-11.png',
iconSize: [42, 20]
});
var A2_22_100 = L.marker([47.4708,8.7059],{icon: symb_A2_22_100}).addTo(map)
A2_22_100.bindPopup("<b>A2-22-100</b><br>x<br>PWD<br>x<br>x)
Now I want to add a search option to search by the name of the point. I already searched for solutions. I think I have to bring all my points into one layer. So the here (Putting multiple markers in Layer Group )presented solution seems to be a good idea (create markers, add to layer, and then add the layer to the map and not the single markers).
However how I get the popup content and my custom symbol into the list?
Or do you have another solution to make my markers searchable?
Related
I'm writing a simple JavaFX7 application where I display data pulled out of database using a StackedBarChart. I also provide the user with the ability to filter the displayed data sets based on a specific property's value. The problem that I'm facing is that there seems to be some caching issues. Consider the following scenario
Initial load, display everything to the user - no filtering involved.
Say our categories are named 1,2,3,4 and 5, and are rendered in that order (consider them sorted)
The user now selects a filter value. This leads to only categories 1,2,4 and 5 being on the screen (again, in that order - this is the expected behavior)
The user now resets the filter to "do-not-filter".
The expected output of step 3 would be 1,2,3,4 and 5, in that order. However, it is 1,2,4,5,3. Notice the category that got filtered out is added back at the end of the array instead of where it should be.
Things I've tried so far:
Assigning a new ObservableList via Axis.setCategory. this doesn't work.
Same as above, but also force the category list to null before hand.
Sorting the category list. This doesn't work either.
I can't (yet) update to Java 8 - I also can't just leave this as a broken feature because this is expected to roll out to users before we upgrade to Java 8. So JavaFX 8's FilteredList is out of question (and a backport is very much annoying just from looking at the changes to ObservableList). I also don't want to entirely recreate the graph if I can avoid it.
At this point, I'm out of ideas. Any suggestions are welcome. Below is the function that populates the chart.
private void refreshContents() {
this.vaguesTotal.getData().clear();
this.vaguesDone.getData().clear();
this.vaguesPending.getData().clear();
this.xAxis.setCategories(null);
this.chartCategories = FXCollections.observableArrayList();
// Already sorted here
for (VagueLight vagueInfo : context.getVagues()) {
if (this.categoryFilter != null && this.categoryFilter != vagueInfo.getCategory())
continue;
int dossiersTraites = vagueInfo.getNbDossiersTraites();
int dossiersPending = vagueInfo.getNbDossiersATraiter();
String vagueIdentifier = Integer.toString(vagueInfo.getId());
this.vaguesTotal.getData().add(new Data<String, Number>(vagueIdentifier, 0, vagueInfo));
this.vaguesDone.getData().add(new Data<String, Number>(vagueIdentifier, dossiersTraites, vagueInfo));
this.vaguesPending.getData().add(new Data<String, Number>(vagueIdentifier, dossiersPending, vagueInfo));
this.chartCategories.add(vagueIdentifier);
}
// This just sets up event handlers and styles for the series
for (Series<String, Number> dataSeries : this.barChart.getData()) {
for (Data<String, Number> dataNode : dataSeries.getData()) {
initializeDataNode(dataNode, dataSeries);
}
}
// This is where the "bug" happens
this.xAxis.setCategories(this.chartCategories);
layout(true);
}
I'm using gwt-visualization to display some Google Charts.
Everything works fine except that I can't set up a continuous X-axis for my column chart. From my understanding, I only need to define the first column of the chart to NOT be STRING - but I always end up with a discrete X-axis.
Here's what I do:
DataTable dataTable = DataTable.create();
dataTable.addRows(rawData.getNumberOfRows());
dataTable.addColumn(DATE, "time interval");
for (Category category : rawData.getCategories()) {
dataTable.addColumn(NUMBER, category.getName());
}
int row = 0;
for (Date month : rawData.getMonths()) {
dataTable.setValue(row++, 0, month);
}
// set other data for categories
Is there something wrong with what I'm doing? Or does the Java library not support this?
This issue has been solved on Google Groups by asgallant (a true hero of Google Visualization support):
asgallant's comment:
That sounds like the wrong chart package is getting loaded. Can you post the javascript produced by your code (open in a browser, view source, and copy it here)?
skirsch's response:
Ah well, that was a great hint.
It does actually load the "areachart" instead of the "corechart". Seems like the latest version available via Maven dates back to 2009, being obviously outdated.
Answer
Make sure that you are loading the appropriate chart package, otherwise you cannot use continuous axes.
I am using Visualr http://googlevisualr.herokuapp.com/ with Rails and having a good amount of success creating dynamic charts. However, I am wondering if it's possible to allow the user to click on the column in a 'column chart' and be linked to a page? I am happy to know the java version if you aren't familiar with visualr.
Thanks!
It now is available!
There has recently been an update on this issue. Therefore I want to update this SO Q&A.
Resources:
Google Visualr Github Pull Request #39
Google Visualr Github Issue #36
Code example
xxx_controller.rb
#table = GoogleVisualr::Interactive::ColumnChart.new(g, options_g)
#table.add_listener("select", "function(e) {
EventHandler(e, chart, data_table)
}")
And then in a JS file e.g. app/assets/javascripts/application.js:
function EventHandler(e, chart, data) {
var selection = chart.getSelection();
if (selection.length > 0) {
var row = selection[0].row;
var department = data.getValue(row, 0);
alert(department + " | " + row)
}
}
Google Charts (whether you access them directly or via a wrapper gem like Visualr) are simple images, so the straight answer is "No", at least not without doing some work of your own. In order to achieve this you would need to place your own transparent clickable links (or divs or whatever) over the image, in the right place, to correspond to the columns that google generate in the image.
I'd imagine this would be tricky and error prone - it might actually be easier for you to just generate the columns yourself in html and css, using the data you would previously have sent to google to set the height (in %) of the columns. Then, each column would be a seperate html element and could link to whatever you want.
So, more control = more work. As usual :)
I am unable to fetch all sports events happening in the state of
Georgia. Is this the right way to use this, since its currently
retrieving all events across the country.
FacebookClient publicFbClient = new DefaultFacebookClient();
Connection<Event> events = publicFbClient.fetchConnection(
"search", Event.class,
Parameter.with("category", "Sports"),
Parameter.with("location", "Georgia"),
Parameter.with("type", "event"));
There's no mention in the doc of the ability to limit results geographically except center (latlong) and distance (radius) when the type place is defined.
You can set the radial search variables for events but doing so doesn't appear to change the results.
As a hobby project I am exploring the ways to save a web page (HTML) as image, mostly programatically using c/c++/javascript/java. Till now I have come across the following ways:
Get the IHTMLElement of page body and use it to query for IHTMLElementRender and then use its DrawToDC method (Ref: http://www.codeproject.com/KB/IP/htmlimagecapture.aspx ). But the problem is that it did not work for all the pages (mostly pages having embedded iframes).
Another way which i can think of is to use some web browser component and when the pages is fully loaded then capture it using BitBlt (Ref: http://msdn.microsoft.com/en-us/library/dd183370%28VS.85%29.aspx ). But the problem is that the page I have requested may be longer than my screen size and it will not fit into the web browser component.
Any direction/suggestion to resolve above issues or an alternative approach is greatly appreciated.
If you use Python, there's pywebshot and webkit2png. Both of them have some dependencies, though.
Edit: Oops, Python is not in your list of preferred languages. I'll leave this answer here anyway, because you said "mostly" and not "exclusively".
Another (somewhat roundabout) option would be to run a server like Tomcat and use Java to call a command-line tool to take a screenshot. Googling for "command line screenshot windows" comes up with some reasonable-looking possibilities. Besides running a server, though, I don't know a good way to run local executables from javascript. This method would make it cross-browser, though, which is a plus (just make an ajax call to the script when you want a screenshot).
Unfortunately I don't actually know how to deploy war files. It might be more trouble to use Tomcat; I mentioned it because Java was a preferred language. It would be fairly simple to run XAMPP and use this PHP snippet, and you wouldn't really have to learn php:
<?php
exec("/path/to/exec args");
?>
EDIT
You know, I'm not sure that really answers your question. It's one way, but it's coming at it from the JavaScript end rather than the scripting end. If you want to do it via scripting, you could always use Selenium. It supports capturing screenshots of an entire page, and can be controlled via Java.
Well finally able to crack it by going through these two articles:
http://www.codeproject.com/KB/GDI-plus/WebPageSnapshot.aspx [c# code - IE]
http://www.codeproject.com/KB/graphics/IECapture.aspx [c++ & GDI - IE]
Can't share the code, but the above two articles will give you the best possible solution.
Also have a look at:
https://addons.mozilla.org/en-US/firefox/addon/3408/ [firefox + javascript]
Above things are still ok. BUT not guaranteed to work always. Check the below link:
How do I render the scrollable regions of a canvas with IViewObject::Draw?
If you are OK using javascript for it, I suggest going with phantomjs
Example from http://fcargoet.evolix.net/
var page = new WebPage(),
address = 'http://dev.sencha.com/deploy/ext-4.0.7-gpl/examples/feed-viewer/feed-viewer.html';
page.viewportSize = {
width : 800,
height : 600
};
// define the components we want to capture
var components = [{
output : 'feed-viewer-left.png',
//ExtJS has a nice component query engine
selector : 'feedpanel'
},{
output : 'feed-viewer-preview-btn.png',
selector : 'feeddetail > feedgrid > toolbar > cycle'
},{
output : 'feed-viewer-collapsed.png',
//executed before the rendering
before : function(){
var panel = Ext.ComponentQuery.query('feedpanel')[0];
panel.animCollapse = false; // cancel animation, no need to wait before capture
panel.collapse();
},
selector : 'viewport'
}];
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
} else {
/*
* give some time to ExtJS to
* - render the application
* - load asynchronous data
*/
window.setTimeout(function () {
components.forEach(function(component){
//execute the before function
component.before && page.evaluate(component.before);
// get the rectangular area to capture
/*
* page.evaluate() is sandboxed
* so that 'component' is not defined.
*
* It should be possible to pass variables in phantomjs 1.5
* but for now, workaround!
*/
eval('function workaround(){ window.componentSelector = "' + component.selector + '";}')
page.evaluate(workaround);
var rect = page.evaluate(function(){
// find the component
var comp = Ext.ComponentQuery.query(window.componentSelector)[0];
// get its bounding box
var box = comp.el.getBox();
// box is {x, y, width, height}
// we want {top, left, width, height}
box.top = box.y;
box.left = box.x;
return box;
});
page.clipRect = rect;
page.render(component.output);
});
// job done, exit
phantom.exit();
}, 2000);
}
});