How to set Google Maps API key in PrimeFaces extensions gChart - google-maps

I'm using PrimeFaces extensions (6.1.0) to create some charts using pe:gChart.
One of the charts is a geo chart as appears in the showcase. No problems so far.
Another chart I need to render is a marker geo chart. This is not explained in the PrimeFaces extensions showcase, but I was hoping this would be an easy job. I ended up with this model (which I believe is correct):
GChartModelBuilder builder = new GChartModelBuilder();
builder.setChartType(GChartType.GEO);
builder.addOption("displayMode", "markers");
builder.addOption("region", country);
builder.addColumns("City", "Total");
for (...) {
builder.addRow(city, total);
}
When I run my project I do see a map for this chart. The region is correct, but no markers appear. There is marker data generated though.
My browser console tells me:
Google Maps API error: MissingKeyMapError https://developers.google.com/maps/documentation/javascript/error-messages#missing-key-map-error
Is there any way I can set this API key without creating hacks?
Update
I've created a custom renderer:
public class MyGChartsRenderer extends GChartRenderer
{
#Override
protected void encodeMarkup(FacesContext context, GChart chart) throws IOException
{
...
this.startScript(writer, chart.getClientId());
// Appended ?key=xxxxx to the URL (other lines are not modified)
writer.writeAttribute("src", "https://www.google.com/jsapi?key=xxxxx", null);
this.endScript(writer);
}
}
And loaded it in the faces-config.xml:
<render-kit>
<renderer>
<component-family>org.primefaces.extensions.component</component-family>
<renderer-type>org.primefaces.extensions.component.GChartRenderer</renderer-type>
<renderer-class>MyGChartsRenderer</renderer-class>
</renderer>
</render-kit>
But the Google Maps API error keeps appearing in my console.

DISCLAIMER: I created an answer, not because it is the answer but because it is so much information that it won't fit in a comment in any way any way (hmmm ;-))
DISCLAIMER 2: I might have missed some things and did not actually try... Hope you don't mind.
Note: Three months ago PrimeFaces extensions updated to a newer Google charts api version according to the commits and issue 452 with upcoming changes so I focussed on that!
In the PrimeFaces-extensions gchart.js I noticed
google.charts.load('current', {
packages : [ 'corechart', 'geochart', 'orgchart' ]
});
jQuery(document).ready(function() {
google.charts.setOnLoadCallback(function() {
that.draw();
});
});
While on on Visualization: GeoChart | Charts | Google Developers I saw
google.charts.load('current', {
'packages':['geochart'],
// Note: you will need to get a mapsApiKey for your project.
// See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings
'mapsApiKey': 'AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY'
});
google.charts.setOnLoadCallback(drawRegionsMap);
Related tot the issue commit/fix/issue, in the PrimeFaces extensions showcase source trunk I also noted they explicitly load
<script src="https://www.gstatic.com/charts/loader.js"></script>
in the xhtml.
Lots of upcoming changes, so the most future proof solution would be to try 6.2-SNAPSHOT and create a real good fix where you
add a mapsApiKey property and getters/setters to GChart.java
add .attr("mapsApiKey", chart.getMapsApiKey()) to GChartRenderer.java
add this.mapsApiKey = cfg.mapsApiKey -and 'mapsApiKey': this.mapsApiKey to gchart.js in the right places

As a workaround / hack I've put this script in my XHTML:
<script src="https://maps.googleapis.com/maps/api/js?key=xxxxx&v=3&callback=google.loader.callbacks.maps&sensor=false"></script>

Related

How to use the BIM360 PushPin Extension with Forge Viewer?

I am trying to use the PushPin extension to load issues in my custom Forge viewer, I follow the steps described in the official documentation but getting the following error after calling PushPinExtension.createItem:
issues.forEach(function (issue) {
var issueAttributes = issue.attributes;
var pushpinAttributes = issue.attributes.pushpin_attributes;
// Notice the last rendering condition, which will enforce rendering the pushpin on the current sheet.
// We simply compare the issue sheet metadata against the current sheet.
if (pushpinAttributes && issueAttributes.sheet_metadata &&
issueAttributes.sheet_metadata.sheetGuid === viewerApp.selectedItem.guid()) {
PushPinExtensionHandle.createItem({
id: issue.id, // The issue ID.
label: issueAttributes.identifier, // The value displayed when you select the pushpin.
// The shape and color of the pushpin, in the following format: ``type-status`` (e.g., ``issues-open``).
status: issue.type && issueAttributes.status.indexOf(issue.type) === -1 ?
`${issue.type}-${issueAttributes.status}` : issueAttributes.status,
position: pushpinAttributes.location, // The x, y, z coordinates of the pushpin.
type: issue.type, // The issue type.
objectId: pushpinAttributes.object_id, // (Only for 3D models) The object the pushpin is situated on.
viewerState: pushpinAttributes.viewer_state // The current viewer state. For example, angle, camera, zoom.
});
} // if
} // forEach
};
Looking at the source code of that extension, it seems there is now a pushPinManager which is responsible for adding items, but I couldn't figure out quickly enough how to use it.
It would help if you could provide a working example using the latest version of that extension and also make sure your doc is up-to-date, which will avoid some tension on the third party devs side ;)
:) how are you!
yes you found the truth that the document does not update with the latest change of the extension. While the Pushpin sample has been migrated to the latest version. It demos the workflow of loading issues and creating new issues with Pushpin extension.
https://github.com/Autodesk-Forge/forge-bim360-issues/blob/master/bim360issues/wwwroot/js/BIM360IssueExtension.js
Please let us know if it does not answer your question.
I have forwarded the suggestion asking for document updating.

Adding API's to chromium build in Electron framework

I would like to write custom functions in Window API in chromium source code. So how do we do it?
In case of doubts about window API here's a link to what I mean click here. I would like to have custom property functions analogus to those shown in the link.
It's for a github electron project.
Well after a week of searching I finally found the solution. Thanks to a pull request by magicae#github.
You need to look create your custom function in
electron/atom/browser/api/lib/atom_api_web_contents.cc
as say
bool WebContents::GetOkOk() {
return true;
}
And define the same in it'h header file
electron/atom/browser/api/lib/atom_api_web_contents.h
as
bool GetOkOk();
Lastly you need to export the function through the webContents method located in
electron/atom/renderer/lib/web-view/web-view.js
as
/* Public-facing API methods. - modified by Akshay Thakare */
methods = ['getOk','getURL', ... ];
And you are good to go.
Finally after you compile your electron app,
in the main.js file add,
console.log(mainWindow.webContents.getOk());
and your done.
As JS is prototype oriented, you could simply extend the BrowserWindow API
var BrowserWindow = require('electron').BrowserWindow; // main process
var BrowserWindow = require('electron').remote.BrowserWindow; // renderer process
BrowserWindow.foo = function() {
console.log('foo');
}
Not sure if you're looking for someting more specific, but I'm not sure you can extend it with heavy impacts on the system, could you explain exactly what you are trying to do ?

Google Maps API v3 DrawingManager : Change title attributes

I'm using Google Maps API V3 and the DrawingManager.
When the mouse hovers my DrawingManager, the title attribute of the icons appears, but I'd like to change this title ("Dessiner une forme" here in French version) and put my own.
I try to use :
$("div.gmnoprint img[src$='drawing.png']").last().attr("title", "My custom title");
And this works, but :
This solution seems ugly.
It works in my browser's console, but I need an event drawingmanager_complete to run this code only when the manager is fully loaded, but according to the documentation , it doesn't exist...
Is there any clean and reliable way to accomplish this ?
Thank you
Unfortunately, the API or the Library does not provide any end points that can be edited by the developer's to create there own custom once. The best way to do this is to just omit the pre-existing controls and then build your own.
One way to do this is by using this approach:
$(map.getDiv()).one('mouseover','img[src="https://maps.gstatic.com/mapfiles/drawing.png"]',function(e){
$(e.delegateTarget).find('img[src="https://maps.gstatic.com/mapfiles/drawing.png"]').each(function(){
$(this).closest('div[title]').attr('title',function(){
switch(this.title){
case 'Add a marker':
return 'Add New Location';
break;
case 'Draw a circle':
return 'Draw an area';
break;
default:return this.title;
}
});
});
});
And this will work with English as a language. To achieve it regardless of the language you'll have to check the top-property of the button-image(this seems to be the only detail that may be used to determine the type of shape the button is used for).

Google Maps and Richfaces 3.3.3 (prototype.js 1.6.0.3) possible incompatibility

I have a web application based on RichFaces 3.3.3 that uses Google Maps (maps-api v3), that was working fine until recently.
Lately is failing to draw the map's user controls. Map is drawn fine but the controls don't appear, map type or zoom control, for example.
Investigating a little, it seems a compatibility problem with prototype.js.
If you simply add this line to the example in developers.google.com:
<script src="http://prototypejs.org/assets/2008/9/29/prototype-1.6.0.3.js"></script>
js console in chrome browser logs this:
Uncaught TypeError: undefined is not a function prototype-1.6.0.3.js:641
And the user controls dissapear...
Somebody knows how to solve this problem??
Now I'm going to try to change prototype.js in richfaces for a more modern version... I'll update when I know more.
Thanks in advance!
--- UPDATE ---
Using production version of Google Maps solves the problem. Now is necessary explicitly put v=3 in src in script tag. Thanks Dr.Molle.
Updating prototypejs to (1.7.2). Works fine with experimental too. Thanks #eepete.
--- UPDATE 2 ---
Using v=3 isn't working anymore with richfaces 3.3.3 (prototype-1.6.0.3.js) if you need to use this old version of prototype, now you need to explicitly use v=3.17 in google maps.
In other words, use this in your page for backguards compatibility with prototype-1.6.0.3.js:
<script src="https://maps.googleapis.com/maps/api/js?v=3.17"></script>
I had the same problem this morning. Got the same error, controls like the zoom control would not render. I upgraded my prototype.js to the latest version (1.7.2) from version (1.7) and things worked again. Am using google maps api V3, the production version. Don't know if it was the newer version prototype.js or if Google changed something and then fixed something, but it's happy now.
Yes!! the solution for me was change the line from:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false" />
to
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3" />
Thanks!!
Change to version v3, the conflict with prototype will disappear, I have tried in my site, it works fine.
This function at line number 629ish in prototype.js is causing the exception. Simply add try catch blocks as shown below. It works with any Google Maps API.
collect: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
var results = [];
try {
this.each(function(value, index) {
results.push(iterator(value, index));
});
} catch (err) {}
return results;
}

Custom plugin in MVVMCross

I'm working on MVVMCross v3 and I want to create my own plugin, I followed this tutorial (which is for the vNext)
http://slodge.blogspot.fr/2012/10/build-new-plugin-for-mvvmcrosss.html
To be compatible for the v3 I changed IMvxServiceConsumer and GetService to Mvx.Resolve.
But on the tutorial there are :
Then, for WinRT, WindowsPhone and MonoTouch clients, you also need to provide a Loader accessor in setup.cs - like:
protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
{
loaders.AddConventionalPlugin<MyCompany.MvvmCross.Plugins.Mega.WindowsPhone.Plugin>();
base.AddPluginsLoaders(loaders);
}
How can I do that in v3?
Thanks
If you want to write a new plugin, then :
the up-to-date sample is https://github.com/slodge/MvvmCross-Tutorials/tree/master/GoodVibrations
there are some notes on this sample in https://speakerdeck.com/cirrious/plugins-in-mvvmcross
For plugin initialisation, the nuget packages now do this via bootstrap files - e.g. see the files added for Location at:
(WinRT, WinPhone, Droid) - https://github.com/slodge/NPlus1DaysOfMvvmCross/blob/master/N-08-Location/Location.Droid/Bootstrap/LocationPluginBootstrap.cs
(Touch) - https://github.com/slodge/NPlus1DaysOfMvvmCross/blob/master/N-08-Location/Location.Touch/Bootstrap/LocationPluginBootstrap.cs
The bootstrap way is the normal way to do initialisation now.
If you did want to use a non-bootstrap technique then you can do this:
In WinRT, WinPhone, and Droid, you don't need to use a loader, but you do need to call MyPlugin.PluginManager.Instance.EnsureLoaded before the plugin can be used.
In Touch, you would need to provide a loader during protected override void AddPluginsLoaders(MvxLoaderPluginRegistry loaders) - and you'd then still need to call EnsureLoaded() before the plugin can be used.
For examples of this 'old way' of working, see Setup.cs in the UI projects in https://github.com/slodge/MvvmCross-Tutorials/tree/master/Sample%20-%20TwitterSearch