-
13 Jan 2013 6:47 AM #1
Answered: Drawing and charting interactive map not working
Answered: Drawing and charting interactive map not working
Hi Sencha community,
I am trying to add an interactive map to my app. A good start in that development would be to use the interactive map of the USA in the "Drawing and charting example" in Sencha Try.
I have embedded the code in a Ext.Panel, here is the code :
Code:/** * * InteractiveMapView defintion * * in MyApp by Jeremy Lauraire * v 0.1, 10/01/2012 * */ Ext.define('MyApp.view.map.InteractiveMapView', { extend: 'Ext.Panel', xtype : 'interactivemapview', requires: ['Ext.draw.sprite.Path'], initialize: function() { this.callParent(arguments); (CODE FROM THE SENCHA TRY EXAMPLE GOES HERE) } });
I get nothing but this error :
TypeError: 'undefined' is not a constructor (evaluating 'new Ext.draw.Matrix()') Target.js:33
Do you have any clue about this problem? I use Sencha Touch 2.1 Free Commercial Version with Sencha Cmd v3.0.0.250... and so far no problem with any other example given about charting and drawing on the Sencha doc...
Thank you,
Jay.Last edited by jeremylauraire; 13 Jan 2013 at 1:47 PM. Reason: error in code....
-
Best Answer Posted by jeremylauraire
Thank you for your help,
Sorry I use a full GPL version of Sencha Touch 2.1 that embeds Ext.Chart.* and Ext.Draw.*... if not I would get an error on, right?Code:requires: ['Ext.draw.sprite.Path']
After a while I figure out what the error was : I did not add the correct require config. But I must admit that the error log is not clear about that. So after adding the requires: ['Ext.Draw.Component'] config it works.
If anyone is interested, here is the full code slightly modified of the Container :
I can move on my new problem : build the geo data from a .svg file... Easy compare to debug this...Code:/** * * InteractiveMapView definition * * in MyApp by Jeremy Lauraire * v 0.1, 10/01/2012 * */ Ext.define('MyApp', { extend: 'Ext.Container', xtype : 'interactivemap', requires: [ 'Ext.draw.sprite.Path', 'Ext.draw.Component' ], config: { layout: 'fit' }, initialize: function() { this.callParent(arguments); var geo_data = [HERE GOES THE DATA]; geo_data = geo_data.map(function (path) { item = Ext.create("Ext.draw.sprite.Path", { path: path, fx: { duration: 200 }, highlightCfg: { shadowColor: 'black', shadowBlur: 8, shadowOffsetX: 3, shadowOffsetY: 3, fillStyle: '#f18729', zIndex: 100 }, modifiers: ['highlight'] }); return item; }); geo_data[0].setAttributes({ highlight: true }); var lastHighlight = geo_data[0]; var interactiveMap = new Ext.draw.Component({ sprites: geo_data, resizeHandler: function (size) { var surface = this.getSurface('main'), bbox = surface.getItems().getBBox(true); scaling = Math.min((size.width - 30) / bbox.width, (size.height - 30) / bbox.height) * 0.95; surface.setRegion([0, 0, size.width, size.height]); surface.getItems().setAttributes({ fill: '#b7b6b6', stroke: 'black', translationX: -(bbox.x + bbox.width / 2) * scaling + size.width / 2, translationY: -(bbox.y + bbox.height / 2) * scaling + size.height / 2, scalingCenterX: 0, scalingCenterY: 0, scalingX: scaling, scalingY: scaling }); }, listeners: { element: 'element', tap: function (e) { // hightlights the selected area... var items = this.getSurface().getItems().items; var i, ln = items.length, item, mat = items[0].attr.inverseMatrix, x = mat.x(e.pageX, e.pageY), y = mat.y(e.pageX, e.pageY), bbox, highlight = null; for (i = 0; i < ln; i += 1) { item = items[i]; bbox = item.getBBox(true); if (bbox.x <= x && x <= bbox.x + bbox.width && bbox.y <= y && bbox.y <= bbox.y + bbox.height) { if (item.attr.path.isPointInPath(x, y)) { highlight = item; break; } } } if (lastHighlight !== highlight) { if (lastHighlight) { lastHighlight.setAttributes({ highlighted: false }); } if (highlight) { highlight.setAttributes({ highlighted: true }); } lastHighlight = highlight; } } } }); this.add(interactiveMap); console.log('InteractiveMap:initialize'); } });
Thank you,
J.
-
15 Jan 2013 7:42 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 34,121
- Vote Rating
- 453
- Answers
- 3160
The 2.1.0 commercial version doesn't come with Ext.chart.* and Ext.draw.* classes unless you buy support package that includes it like Sencha Complete.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
16 Jan 2013 1:55 AM #3
Forgot requires statement....
Forgot requires statement....
Thank you for your help,
Sorry I use a full GPL version of Sencha Touch 2.1 that embeds Ext.Chart.* and Ext.Draw.*... if not I would get an error on, right?Code:requires: ['Ext.draw.sprite.Path']
After a while I figure out what the error was : I did not add the correct require config. But I must admit that the error log is not clear about that. So after adding the requires: ['Ext.Draw.Component'] config it works.
If anyone is interested, here is the full code slightly modified of the Container :
I can move on my new problem : build the geo data from a .svg file... Easy compare to debug this...Code:/** * * InteractiveMapView definition * * in MyApp by Jeremy Lauraire * v 0.1, 10/01/2012 * */ Ext.define('MyApp', { extend: 'Ext.Container', xtype : 'interactivemap', requires: [ 'Ext.draw.sprite.Path', 'Ext.draw.Component' ], config: { layout: 'fit' }, initialize: function() { this.callParent(arguments); var geo_data = [HERE GOES THE DATA]; geo_data = geo_data.map(function (path) { item = Ext.create("Ext.draw.sprite.Path", { path: path, fx: { duration: 200 }, highlightCfg: { shadowColor: 'black', shadowBlur: 8, shadowOffsetX: 3, shadowOffsetY: 3, fillStyle: '#f18729', zIndex: 100 }, modifiers: ['highlight'] }); return item; }); geo_data[0].setAttributes({ highlight: true }); var lastHighlight = geo_data[0]; var interactiveMap = new Ext.draw.Component({ sprites: geo_data, resizeHandler: function (size) { var surface = this.getSurface('main'), bbox = surface.getItems().getBBox(true); scaling = Math.min((size.width - 30) / bbox.width, (size.height - 30) / bbox.height) * 0.95; surface.setRegion([0, 0, size.width, size.height]); surface.getItems().setAttributes({ fill: '#b7b6b6', stroke: 'black', translationX: -(bbox.x + bbox.width / 2) * scaling + size.width / 2, translationY: -(bbox.y + bbox.height / 2) * scaling + size.height / 2, scalingCenterX: 0, scalingCenterY: 0, scalingX: scaling, scalingY: scaling }); }, listeners: { element: 'element', tap: function (e) { // hightlights the selected area... var items = this.getSurface().getItems().items; var i, ln = items.length, item, mat = items[0].attr.inverseMatrix, x = mat.x(e.pageX, e.pageY), y = mat.y(e.pageX, e.pageY), bbox, highlight = null; for (i = 0; i < ln; i += 1) { item = items[i]; bbox = item.getBBox(true); if (bbox.x <= x && x <= bbox.x + bbox.width && bbox.y <= y && bbox.y <= bbox.y + bbox.height) { if (item.attr.path.isPointInPath(x, y)) { highlight = item; break; } } } if (lastHighlight !== highlight) { if (lastHighlight) { lastHighlight.setAttributes({ highlighted: false }); } if (highlight) { highlight.setAttributes({ highlighted: true }); } lastHighlight = highlight; } } } }); this.add(interactiveMap); console.log('InteractiveMap:initialize'); } });
Thank you,
J.
-
16 Jan 2013 4:16 AM #4
Own geo Data?
Own geo Data?
How would we get our own Geo Data? I have seen in Adobe Illustrator the export SVG to code option but the output looks different.
Is it possible to get a world map Geodata code from somewhere I wonder?
Thanks
-
16 Jan 2013 7:50 AM #5
Interesting question #tylardurdan... that I have solved partially and still looking to improve...
My goal is to build an interactive map, looking just like the USA map example presented in the Sencha Touch docs.... but with my own geo map (south of France to be clear or any other example).
First thing to know is that a .svg file contains all those data : it is just a specific format based upon XML. But you can not use it without a parser.
The question is : what is the proper parser to go from a .svg file found anywhere on the web to the proper geo data (which look like that "m 0.344 5.765 L 765.5 56.55............. L 656.77 45.4 z " to define the path in Ext.Draw.sprite.path)?
I found the Raphael solution that works for a very simple example : http://readysetraphael.com. Basically, you provide the .svg file and the output is the file parsed to the Raphael format which is slightly different from what we need... so far I have manually extracted the data I need.
That's it
! Then you can just set the geo_data var in the previous code and it should render your svg file as a Draw Component in the Panel.
What I intend to do is to have a direct method to parse that kind of file.... work in progress unfortunately.
Hope this is clear enough to help you.
J.
-
17 Jan 2013 4:30 AM #6
Update : trouble with isPointInPath(x, y)
Update : trouble with isPointInPath(x, y)
Hi again,
On the same example : interactive map of the USA... I have trouble with the isPointInPath method which does not respond correctly.
The only differences with the original example is that I embedded it into a Container and I had to set fullscreen to false for the Ext.draw.Component...
The code :
If you have any clue about what I am doing wrong...Code:for (i = 0; i < ln; i += 1) { item = items[i]; bbox = item.getBBox(true); if (bbox.x <= x && x <= bbox.x + bbox.width && bbox.y <= y && bbox.y <= bbox.y + bbox.height) { if (item.attr.path.isPointInPath(x, y)) { // THERE IT DOES NOT RETURN THE PROPER TRUE/FALSE... highlight = item; break; } } }
This,
J.
-
4 Feb 2013 12:18 PM #7
Hi Jeremy,
I had the same problem. You'll need to use the e.browserEvent.offsetX and e.browserEvent.offsetY instead of pageX and pageY.
x = mat.x(e.browserEvent.offsetX, e.browserEvent.offsetX),
y = mat.y(e.browserEvent.offsetX, e.browserEvent.offsetY),
Bob


Reply With Quote