charting plugin

Just need to be able to run this:  

\<html\> \<head\> \<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"\>\</script\> \<script type="text/javascript"\> google.charts.load("current", {packages:["corechart"]}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([['Task', 'Hours per Day'], ['Work', 11], ['Eat', 2], ['Commute', 2], ['Watch TV', 2], ['Sleep', 7] ]); var options = { title: 'My Daily Activities', pieHole: 0.4, }; var chart = new google.visualization.PieChart(document.getElementById('donutchart')); chart.draw(data, options); } \</script\> \</head\> \<body\> \<div id="donutchart" style="width: 900px; height: 500px;"\>\</div\> \</body\> \</html\>

While I haven’t used google charts or any data analytic software, 

I suggest redirecting them to some dashboard online showing all the graphs.

Corona supports webView’s where you can include blocks on the page that contain the contents of a web page via a URL, or you can have local HTML in your project that you can show in your webView. The webView uses native webView controls. On iOS, macOS and Android this will include full HTML5 support. For Windows, I believe it’s using the Internet Explorer controls which depending on the version of Windows, the level of HTML5 support will vary.  

You can use the HTML locally inside a webView.

When we say we don’t support HTML5 (yet), we are talking about outputting your app as an web page were people can run your app from a web page. FYI, we are working on it!

We also have an SVG plugin that might work on your SVG files that produces a display object that you can include in your app like any other image. See the Nano SVG plugin:  https://marketplace.coronalabs.com/plugin/nano-svg

Rob

What Rob said.

So if I put this in my code: webView:request( “localfile.html”, system.ResourceDirectory )

and my localfile.html looked like:

\<html\> \<head\> \<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"\>\</script\> \<script type="text/javascript"\> google.charts.load("current", {packages:["corechart"]}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([['Task', 'Hours per Day'], ['Work', 11], ['Eat', 2], ['Commute', 2], ['Watch TV', 2], ['Sleep', 7] ]); var options = { title: 'My Daily Activities', pieHole: 0.4, }; var chart = new google.visualization.PieChart(document.getElementById('donutchart')); chart.draw(data, options); } \</script\> \</head\> \<body\> \<div id="donutchart" style="width: 900px; height: 500px;"\>\</div\> \</body\> \</html\>

It would render a pie chart in my app?  

I guess you would have to try it out  if it works.

I dont have some of the files you have so it would probably not work for me.

And thanks for the like :wink:

Hi,

In theory your code above “should” work depending on cross-origin policies.

This looks interesting as well https://github.com/GlitchGames/GGChart

While that specific Google API is depreciated, they state they have no plans on shutting it down (https://developers.google.com/chart/image/).

But the webView wrapper might be your best bet.

-dev

I have tried GGChart and it does still work.  But you of course couldn’t include that in any type of app you are building for someone.  If this wrapper works I might “upgrade”  GGChart to use the wrapper instead of the old google api.   Also, using a remove server to render stuff for you makes your app depend on the network.  I have seen GGChart fail a lot in spotty network situations.  But I guess that is the world we live in.  

I can confirm that loading this page using 

local webView = native.newWebView( display.contentCenterX, display.contentCenterY, 320, 480 )

webView:request( “localfile.html”, system.ResourceDirectory )

 

does work when the html in localfile.html is a request for a chart from google charts.

the only thing I don’t understand now is how to build the localfile.html dynamically based on user input.

 

The doc seems to indicate to me that it has to come out of a system file. Is there a system directory

I can write to?

You can write to system.TemporaryDirectory, system.CachesDirectory and system.DocumentsDirectory. I would probably recommend using the temporary directory for this usage.

This is what I did for a weather app I built for my wife. I need a Google Map with an overlay from Weather Underground. I need to provide several variables to the html.  

local header = [[\<!DOCTYPE html\> \<html\> \<head\> \<title\>Google Maps JavaScript API v3 Example: Map Simple\</title\> \<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"\> \<meta charset="utf-8"\> \<style\> html, body, #map\_canvas { margin: 0; padding: 0; height: 100%; } \</style\> \<script src="https://maps.googleapis.com/maps/api/js?key=mykeyhere"\>\</script\> \<script\> var map; var radarOverlay; var mapBounds; var API\_calls = 0; var rateLimitTimer;]] local body = [[function initialize() { var myLatLong = new google.maps.LatLng(latitude, longitude); var mapOptions = { zoom: 8, center: myLatLong, mapTypeId: google.maps.MapTypeId.ROADMAP, zoomControl: false, scaleControl: false, panControl: false, streetViewControl: false, overviewMapContro: false }; map = new google.maps.Map(document.getElementById('map\_canvas'), mapOptions); google.maps.event.addListener(map, 'idle', function() { API\_calls++; if (API\_calls \> 9) { // rate limit return(true); } var center = map.getCenter(); var bounds = map.getBounds(); var zoom = map.getZoom(); ne = bounds.getNorthEast(); sw = bounds.getSouthWest(); var URL = 'http://api.wunderground.com/api/mykeyhere/animatedradar/image.gif?num=5&delay=50&maxlat=' + ne.lat() + '&maxlon=' + sw.lng() + '&minlat=' + sw.lat() + '&minlon=' + ne.lng() + '&width=' + screenWidth + '&height=' + screenHeight + '&rainsnow=1&smooth=1&noclutter=1'; if (radarOverlay) { radarOverlay.setMap(null); } radarOverlay = new google.maps.GroundOverlay( URL, bounds ); radarOverlay.setMap(map); }); rateLimitTimer = setInterval(function () { API\_calls--; if (API\_calls \< 0) { API\_calls = 0; } }, 30000); } google.maps.event.addDomListener(window, 'load', initialize); \</script\> \</head\> \<body\> \<div id="map\_canvas"\>\</div\> \</body\> \</html\>]]

So there are two parts, some fixed HTML for the head and another part that represents a bulk of the body.  I then write some JS code in between the two:

 if event.phase == "will" then local path = system.pathForFile( "radar.html" , system.TemporaryDirectory ) local fp = io.open( path, "w" ) if fp then fp:write(header) fp:write("var latitude = " .. tostring(myData.latitude) .. ";\n") fp:write("var longitude = " .. tostring(myData.longitude) .. ";\n") fp:write("var screenWidth = " .. tostring( display.contentWidth) .. ";\n") fp:write("var screenHeight = " .. tostring( display.contentHeight - 50) .. ";\n") fp:write(body) fp:close() end else webView = native.newWebView( display.contentCenterX, display.contentCenterY - 25, display.contentWidth, display.contentHeight - 50 ) local path = system.pathForFile( "radar.html" , system.TemporaryDirectory ) local fp = io.open( path, "r" ) if fp then fp:close(); webView:request( "radar.html", system.TemporaryDirectory ) else webView:request( "radar.html", system.ResourceDirectory ) end end

In the scene:show’s will phase, I write out header, the JS to construct the var’s with my unique values for the user, then the body. Once I get to the “did” phase, I create the webView and if I can get a path to the HTML I just wrote out (should always unless there is some storage issue), I have the webView load the HTML I wrote out, if I can’t open that file for some reason, I fall back to a complete HTML file in the resource directory that won’t have customized location data.  This is a lot, but I wanted to include the pretty much complete example.

Hope this helps.

Rob

Hi,

I’ve put together a module that will return a PNG from the Google Charts API here https://github.com/develephant/google-charts-corona

Seems to work fine on Android, but I have not had a chance to test on an iOS device as I currently don’t have a developers account.

If someone can test the demo project on iOS and let me know if it works I can add in a way to create the pages dynamically.

-dev

Hi,

I optimized the module a little bit. Would still love to know if the demo project (in the demo directory) runs on iOS if anyone has a chance to test it out.

https://github.com/develephant/google-charts-corona

-dev

Jan 17 01:04:36.464 ERROR: build command failed: xcrun actool --output-format human-readable-text --warnings --notices --export-dependency-info "/var/folders/5d/wyygg2ls5vz1d40dw35gpc4c0000gn/T/CLtmpFu4oy7/assetcatalog\_dependencies" --output-partial-info-plist "/var/folders/5d/wyygg2ls5vz1d40dw35gpc4c0000gn/T/CLtmpFu4oy7/assetcatalog\_generated\_info.plist" --compress-pngs --enable-on-demand-resources YES --product-type com.apple.product-type.application --compile "/Volumes/Macintosh HD/Media/Projects/Omnigeek Media/AppBuilds/demo.app" --target-device iphone --target-device ipad --minimum-deployment-target 8.0 --platform iphoneos --app-icon AppIcon "Images.xcassets" Jan 17 01:04:36.465 ERROR: with exit code 1 and output:&nbsp; Jan 17 01:04:36.465 captureCommandOutput: cat /tmp/lua\_p3hKjl Jan 17 01:04:36.494 ERROR: while compiling icons:&nbsp; Jan 17 01:04:36.494 BUILD ERROR:&nbsp; Jan 17 01:04:36.495&nbsp; Jan 17 01:04:36.510 iOS build failed (12) after 11 seconds Jan 17 01:04:36.802 ERROR: Build Failed:&nbsp; Jan 17 01:04:36.803&nbsp;

Not happy building for iOS

@Rob - Ouch!

Well thank you very much for taking the time to do that. I really appreciate it.

Is it possible it’s because I removed all the icons and the image.xcassests stuff? Are those required for iOS build?

-dev

I don’t know why we would check for icons, but the error certainly looks like that’s the cause.

Rob

Hi,

Well, hopefully the module itself should work. I’m not too concerned about the demo project at the moment.

I should have my developers account renewed in the next couple weeks and I’ll tweak on it.

Thanks again.

-dev

OK, so I am testing the webView option and I am running into this:  

Native display objects are separate from Corona’s OpenGL drawing canvas and always appear in front of normal display objects.

So is there any way around this?   My drop downs in my app are covered up by this web screen so the user can’t select anything from a pick list.   How did you draw on this for your wife’s weather app?   

Hi,

The module I created will return an image which can used with a displayObject, so you wouldn’t have that issue.

It’s not using the old Google API either, it is all based on the current one.

The demo project isn’t fit for IOS at the moment, but if you use the module in your own project it should work.

FWIW.

-dev

native.* objects sit in front of display objects. There is nothing that can be done about it. Honestly I think @develephant’s module might be a great option if you can pass the data you need to it.

Rob

@Develephant

OK,  I am trying to give your code a try and it seems the listener is called but the url never has data:image in it.  So I never get inside this if stmt: 

 print ("googlecharts webListener", event.url ) if event.url and string.find(event.url, "#data:image") then print ("googlecharts webListener2", event.url ) webView:stop() webView:removeSelf() local b64\_encoded = split(event.url, ",")[2] local file\_path = \_processPng( dest\_file, dest\_dir, b64\_encoded ) return listener({ filename = dest\_file, baseDir = dest\_dir }) end

When I look at my log it looks like the listener is called 3 times but never with the url having the word image in it. 

Does this thing work in the simulator?  That is where I am trying it.