├── .DS_Store
├── LICENSE
├── README.md
├── build.xml
├── classic
└── Readme.md
├── examples
├── .DS_Store
├── Readme.md
├── basicMap
│ ├── basicMap-example1.html
│ ├── basicMap-example1.js
│ ├── basicMap-example2.html
│ ├── basicMap-example2.js
│ ├── basicMap-example3.html
│ ├── basicMap-example3.js
│ ├── basicMap-example4.html
│ └── basicMap-example4.js
├── cartoAccount
│ ├── cartoAccount-example1.html
│ └── cartoAccount-example1.js
├── chartMap
│ ├── chartMap-example1.html
│ └── chartMap-example1.js
├── fireMap
│ ├── fireMap-example1.html
│ ├── fireMap-example1.js
│ ├── fireMap-example2.html
│ ├── fireMap-example2.js
│ ├── fireMap-example3.html
│ └── fireMap-example3.js
├── gridMap
│ ├── gridMap-example1.html
│ ├── gridMap-example1.js
│ ├── gridMap-example2.html
│ ├── gridMap-example2.js
│ ├── gridMap-example3.html
│ ├── gridMap-example3.js
│ ├── gridMap-example4.html
│ ├── gridMap-example4.js
│ ├── gridMap-example5.html
│ ├── gridMap-example5.js
│ ├── gridMap-example6.html
│ ├── gridMap-example6.js
│ ├── gridMap-example7.html
│ └── gridMap-example7.js
├── gridpanel
│ ├── gridPanel-example3.js
│ ├── gridpanel-example1.html
│ ├── gridpanel-example1.js
│ ├── gridpanel-example2.html
│ ├── gridpanel-example2.js
│ └── gridpanel-example3.html
├── layerDemo
│ ├── layerDemo-example1.html
│ └── layerDemo-example1.js
├── playMap
│ ├── playMap-example1.html
│ └── playMap-example1.js
├── storeBinding
│ ├── storeBinding-example1.html
│ └── storeBinding-example1.js
└── tornados
│ ├── tornado-example.html
│ └── tornado-example.js
├── licenses
└── Readme.md
├── modern
└── Readme.md
├── overrides
└── Readme.md
├── package.json
├── resources
└── Readme.md
├── sass
├── Readme.md
├── config.rb
├── etc
│ └── Readme.md
├── example
│ ├── custom.js
│ ├── fashion.html
│ ├── render.js
│ └── theme.html
├── src
│ └── Readme.md
└── var
│ └── Readme.md
└── src
├── .DS_Store
├── AbstractLayer.js
├── CartoBasemaps.js
├── CartoDataModel.js
├── CartoFilter.js
├── CartoGroupBy.js
├── CartoMap.js
├── CartoProxy.js
├── CartoSqlMixin.js
├── CartoStore.js
├── CountryCodesLatLongISO3166.js
├── LayerManager.js
├── LeafletFunctionsMixin.js
├── Readme.md
├── css
├── Css.js
├── HeatMap.js
├── Intensity.js
├── Line.js
├── Point.js
├── Polygon.js
├── Torque.js
└── TorqueCat.js
├── layer
├── LayerBase.js
├── LayerGroup.js
└── Torque.js
├── mixin
└── DataContainingLayer.js
├── sql
├── CartoField.js
├── CartoFrom.js
├── CartoSql.js
└── CartoTable.js
├── sublayer
├── CartoDb.js
└── SubLayerBase.js
└── util
├── LayerCollection.js
├── SubLayerCollection.js
└── TableCollection.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CrestoneDigital/extjs-carto/a67036b54c48717290eb6cfc996cd37644cdc46f/.DS_Store
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # extjs-carto
2 | Native components for ExtJS to interact with Carto map layers, data and visualizations.
3 |
4 |
5 | ## CartoMap.js
6 |
7 | ### Configs
8 |
9 | Name | Type | Default | Description
10 | --- | --- | --- | ---
11 | `cartoMap` | [L.map] | [L.map] | The leaflet map for this component.
12 | `zoom` | Number | 4 | A zoom value to initialize the `cartoMap` with.
13 | `scrollWheelZoom` | Boolean | true | `true` to allow the map to be scrolled by the mouse wheel.
14 | `basemap` | String Object [L.tileLayer] | 'positronLite' | The basemap to be used for the `cartoMap`.
15 | `bounds` | [LatLngBounds] | null | The bounds of the `cartoMap`.
16 | `minZoom` | Number | 3 | The minimum possible zoom level of the `cartoMap`.
17 | `maxZoom` | Number | 18 | The maximum possible zoom level of the `cartoMap`.
18 | `mapLock` | Boolean | false | `true` for the map to update the filters in every store found in `storesToLock` when the `cartoMap` bounds change.
19 | `layers` | Carto.util.LayerCollection | null | A collection of the layers of the `cartoMap`.
20 | `selection` | [Ext.data.Model] | null | The selected record of the `cartoMap`.
21 | `selectedAction` | String String[] | null | The actions to take when a record is selected.
22 | `stores` | [Ext.data.Store] | null | The stores associated with each subLayer of the `cartoMap`.
23 | `storesToLock` | String[] | null | An array of storeIds to be passed the `cartoMap`'s bounds when `mapLock` is true.
24 |
25 | ### Instance Properties
26 |
27 | Name | Type | Default | Description
28 | --- | --- | --- | ---
29 | `maskWhileLoading` | Boolean | false | `true` to mask the map component while tiles are loading.
30 | `loadingMessage` | String | 'Loading Tiles...' | The message to display while the tiles are loading.
31 |
32 | ### Binding
33 |
34 | The `map`'s selection is two-way bindable, similarly to other Extjs components. This means it plays well with things like `grid`s.
35 |
36 | #### Example
37 |
38 | ```javascript
39 | {
40 | xtype: 'grid',
41 | bind: {
42 | selection: '{selectedItem}',
43 | store: '{sampleStore}'
44 | }
45 | }, {
46 | xtype: 'cartoMap',
47 | bind: {
48 | selection: '{selectedItem}'
49 | },
50 | basemap: 'darkMatterLite',
51 | layers: [{
52 | subLayers: [{
53 | bind: '{sampleStore}'
54 | }]
55 | }]
56 | }
57 | ```
58 |
59 | #### Available Basemaps
60 |
61 | * positron
62 | * positronLite
63 | * positronLabelsBelow
64 | * darkMatter
65 | * darkMatterLite
66 | * darkMatterLabelsBelow
67 | * cartoWorldEco
68 | * cartoWorldFlatBlue
69 | * cartoWorldMidnightCommander
70 | * cartoAntique
71 | * toner
72 | * tonerLite
73 | * tonerLabelsBelow
74 | * tonerBackground
75 | * tonerLines
76 | * tonerHybrid
77 | * watercolor
78 |
79 | ##### Example Usage
80 |
81 | ```javascript
82 | {
83 | xtype: 'cartoMap',
84 | basemap: 'darkMatterLite'
85 | }
86 | ```
87 |
88 | #### Available Selected Actions
89 |
90 | * placeMarker
91 | * panTo
92 |
93 | ##### Example Usage
94 |
95 | ```javascript
96 | {
97 | xtype: 'cartoMap',
98 | selectedAction: 'panTo'
99 | }
100 | ```
101 |
102 | ```javascript
103 | {
104 | xtype: 'cartoMap',
105 | selectedAction: ['panTo', 'placeMarker']
106 | }
107 | ```
108 |
109 | ## Layers
110 |
111 | Layers are a combination of data (from SQL) and styling (from CartoCSS) that render the map.
112 | Carto has multiple different types of layers (see the [demo][Layer Demos] for some examples), but there are some configs common to them all.
113 |
114 | ### Configs
115 |
116 | Name | Type | Default | Description
117 | --- | --- | --- | ---
118 | `cartoLayer` | Layer | null | The underlying Layer object.
119 | `layerId` | String | Auto-generated id | The key by which this layer can be retrieved, removed, etc.
120 | `username` | String | '' | The username for the associated carto account.
121 | `table` | String | '' | The table that this layer draws from.
122 | `hidden` | Boolean | false | Set to `true` to hide this layer.
123 | `mapZIndex` | Number | null | Defines the order that the layers are rendered on the `map`.
124 |
125 | ## Layer Groups
126 |
127 | Carto can combine multiple layers into one layer group that is created and rendered as one layer, rather than multiple.
128 |
129 | ### Configs
130 |
131 | Name | Type | Default | Description
132 | --- | --- | --- | ---
133 | `subLayers` | Carto.util.SubLayerCollection | null | The collection of [Carto.sublayer.SubLayerBase] objects associated with this layer group.
134 |
135 | ## SubLayers
136 |
137 | ### Configs
138 |
139 | Name | Type | Default | Description
140 | --- | --- | --- | ---
141 | `layer` | [Carto.layer.LayerGroup] | null | The [Carto.layer.LayerGroup] that owns this subLayer.
142 |
143 | See also: [Carto.mixin.DataContainingLayer]
144 |
145 | ## Torque Layers
146 |
147 | Torque layers combine with [Carto.css.Torque][CartoCSS] to create powerful layer objects that can accomplish much more than traditional map layers.
148 |
149 | See also: [Carto.mixin.DataContainingLayer]
150 |
151 | ##### Example Usage
152 |
153 | ```javascript
154 | {
155 | xtype: 'cartoMap',
156 | layers: [{
157 | type: 'torque',
158 | css: {
159 | type: 'torque' // or heatmap, torquecat
160 | },
161 | ...
162 | }]
163 | }
164 | ```
165 |
166 | ## DataContainingLayer.js
167 |
168 | Most layers (like [Carto.layer.Torque] and [Carto.sublayer.SubLayerBase]) contain data.
169 | This mixin defines the SQL, CartoCss, and store functionality for layers that render data.
170 |
171 | ### Configs
172 |
173 | Name | Type | Default | Description
174 | --- | --- | --- | ---
175 | `store` | [Carto.CartoStore] | null | A [Carto.CartoStore] associated with this layer. If defined, it will create the SQL for this layer.
176 | `sql` | String | '' | SQL for this layer to use when it is created.
177 | `css` | Object String String[] | [Carto.css.Point][CartoCSS] | The CartoCSS definition for this layer.
178 | `selection` | [Ext.data.Model] | null | The layer's current selected record.
179 | `interactivity` | Object | null | Use `enable: true` to enable interactity on this layer.
180 |
181 | ## CartoCSS
182 |
183 | CartoCSS defines how a layer is styled on the map.
184 | There are multiple types that are available to be used as-is or extended as appropriate.
185 |
186 | Name | Type | Description
187 | --- | --- | ---
188 | `point` | Carto.css.Point | A generic point-based style.
189 | `line` | Carto.css.Line | A generic line-based style.
190 | `polygon` | Carto.css.Polygon | A generic polygon-based style.
191 | `intensity` | Carto.css.Intensity | Point style with multiplying effect.
192 | `heatmap` | Carto.css.HeatMap | Torque style with multiplying effect.
193 | `torque` | Carto.css.Torque | Torque style for showing time-based effects.
194 | `torquecat` | Carto.css.TorqueCat | Torque style with added categorical grouping.
195 |
196 | ##### Example Usage
197 |
198 | ```javascript
199 | {
200 | css: {
201 | type: 'point',
202 | // the value config will extend, not overwrite
203 | value: {
204 | markerColor: 'blue'
205 | }
206 | }
207 | }
208 | ```
209 |
210 | ## CartoStore.js
211 |
212 | ### Configs
213 |
214 | Name | Type | Default | Description
215 | --- | --- | --- | ---
216 | `groupBy` | [Carto.CartoGroupBy] | null | A groupBy object defining the GROUP BY clause of the `Carto.CartoProxy`'s SQL.
217 |
218 |
219 | ## CartoProxy.js
220 |
221 | ### Configs
222 |
223 | Name | Type | Default | Description
224 | --- | --- | --- | ---
225 |
226 | ## CartoGroupBy.js
227 |
228 | This is an SQL helper object for defining the GROUP BY clause in the SQL.
229 |
230 | ### Configs
231 |
232 | Name | Type | Default | Description
233 | --- | --- | --- | ---
234 | `fields` | Object[] String[] | null | An array of field configs, in the order they should be presented in the GROUP BY clause.
235 | `countName` | String | 'cnt' | The name of the field that should contain the counts of the different groups.
236 |
237 | In addition, the [Carto.CartoGroupBy] object uses optional extra properties of the [Ext.data.field.Field] that are not native.
238 |
239 | Name | Type | Default | Description
240 | --- | --- | --- | ---
241 | `property` | String | undefined | Specifies the name of the column for this field, if different from the `name` of the field.
242 | `sql` | String | undefined | Use this to force the query to use this SQL for this field. Useful for more complicated queries.
243 | `aggregateType` | String | undefined | An SQL function for aggregating on this field. If specified, this field will not be included in the GROUP BY clause.
244 |
245 | ## Demos
246 |
247 | ### Basic
248 |
249 | * [Visualization of a Map in Ext JS](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/basicMap/basicMap-example1.html)
250 | * [A Map centered on Japan](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/basicMap/basicMap-example2.html)
251 | * [A Map with a simple Carto layer](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/basicMap/basicMap-example3.html)
252 | * [A Map whose layers can be added and removed](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/basicMap/basicMap-example4.html)
253 |
254 | ### Grid/Map
255 |
256 | * [Grid and Map bound to Carto Store](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example1.html)
257 | * [Map with hidden layer and multiple selected actions](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example2.html)
258 | * [Grid locked to Map bounds (with tooltip)](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example3.html)
259 | * [Grid and Map with filter options](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example4.html)
260 | * [Grid and Map with auto filter options](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example5.html)
261 | * [Grid and Map with combo filter](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example6.html)
262 | * [Grid and Map with combo filter](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/gridMap/gridMap-example7.html)
263 |
264 | ### Carto Account
265 |
266 | * [Carto Stores with tables and columns](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/cartoAccount/cartoAccount-example1.html)
267 |
268 | ### Chart/Map
269 |
270 | * [Chart and Map filtered by text input](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/chartMap/chartMap-example1.html)
271 |
272 | ### Layer Demos
273 |
274 | * [Demonstration of multiple layer types (point, polygon, heatmap, torque)](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/layerDemo/layerDemo-example1.html)
275 |
276 | ### Store Binding
277 |
278 | * [Grid and two Maps bound to one Carto Store](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/storeBinding/storeBinding-example1.html)
279 |
280 | ### Fire Map
281 |
282 | * [Wildfire Map with two styled layers](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/fireMap/fireMap-example1.html)
283 | * [Wildfire Map with styled layer and heatmap layer](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/fireMap/fireMap-example3.html)
284 |
285 | ### [Wildfire Exploration](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/fireMap/fireMap-example2.html)
286 |
287 | ### [Carto Map Explorer](http://rawgit.com/CrestoneDigital/extjs-carto/master/examples/playMap/playMap-example1.html)
288 |
289 |
290 | [Ext.data.Model]: http://docs.sencha.com/extjs/6.2.0/classic/Ext.data.Model.html
291 | [Ext.data.Store]: http://docs.sencha.com/extjs/6.2.0/classic/Ext.data.Store.html
292 | [L.tileLayer]: http://leafletjs.com/reference.html#tilelayer
293 | [L.map]: http://leafletjs.com/reference.html#map-usage
294 | [LatLngBounds]: http://leafletjs.com/reference.html#latlngbounds
295 | [Carto.CartoGroupBy]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#cartogroupbyjs
296 | [Carto.sublayer.SubLayerBase]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#sublayers
297 | [Ext.data.field.Field]: http://docs.sencha.com/extjs/6.2.1/classic/Ext.data.field.Field.html
298 | [Carto.layer.LayerGroup]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#layer-groups
299 | [Carto.mixin.DataContainingLayer]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#datacontaininglayerjs
300 | [Layer Demos]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#layer-demos
301 | [CartoCSS]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#cartocss
302 | [Carto.CartoStore]: https://github.com/CrestoneDigital/extjs-carto/blob/master/README.md#cartostorejs
303 |
304 | # Presentations
305 |
306 | ### [SlideShare - SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CARTO via Ext JS Components](https://www.slideshare.net/senchainc/senchacon-2016-integrating-geospatial-maps-big-data-using-cartodb-via-ext-js-components-michael-giddens/1)
307 | [Video can be found here of the talk.](https://www.senchacon.com/videos-slides/#Top)
308 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/classic/Readme.md:
--------------------------------------------------------------------------------
1 | This classic-specific directory can include any (if not all) of the following directories:
2 |
3 | * overrides: Any classes in this directory will be automatically required and included in the classic build.
4 | In case any of these classes define an Ext JS override (using Ext.define with an "override" property),
5 | that override will in fact only be included in the build if the target class specified
6 | in the "override" property is also included.
7 |
8 | - sass: Any classic-specific style rules should reside in this package, following the same structure
9 | as the directory in the package root (see package.json for more information).
10 |
11 | - src: The classic-specific classes of this package should reside in this directory.
--------------------------------------------------------------------------------
/examples/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CrestoneDigital/extjs-carto/a67036b54c48717290eb6cfc996cd37644cdc46f/examples/.DS_Store
--------------------------------------------------------------------------------
/examples/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/examples
2 |
3 | This folder contains example applications demonstrating this package. Each of
4 | these applications will be built as part of the package build:
5 |
6 | cd /path/to/package
7 | sencha package build
8 |
9 | As applications, they can also be built individually:
10 |
11 | cd /path/to/package/examples/example-app
12 | sencha app build
13 |
14 | Or you can build all examples as a group:
15 |
16 | cd /path/to/package
17 | sencha ant examples
18 |
19 | The ideal location for the example builds to reside is the `"./build"` folder:
20 |
21 | /path/to/package/
22 | src/
23 | resources/
24 | ...
25 | examples/
26 | example-app/
27 | other-example/
28 | ...
29 | build/
30 | resources/
31 | examples/
32 | example-app/
33 | other-example/
34 |
35 | This can be specified in the `".sencha/app/build.properties"` file for the
36 | example applications:
37 |
38 | build.dir=${package.build.dir}/examples/${app.name}
39 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Basic Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap'
6 | ]);
7 |
8 |
9 | /**
10 | * The most basic usage
11 | */
12 | Ext.onReady(function () {
13 | Ext.QuickTips.init();
14 |
15 | Ext.create('Ext.container.Viewport', {
16 | layout: 'fit',
17 | items: [{
18 | xtype: "cartomap"
19 | }]
20 | });
21 |
22 | });
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Basic Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example2.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap'
6 | ]);
7 |
8 |
9 |
10 |
11 | /**
12 | *
13 | * Basic map Centered on Japan using Japan ISO3166 code
14 | */
15 | Ext.onReady(function () {
16 | Ext.QuickTips.init();
17 |
18 | Ext.create('Ext.container.Viewport', {
19 | layout: 'fit',
20 | items: [{
21 | xtype: "cartomap",
22 | center: 'jp'
23 | }]
24 | });
25 |
26 | });
27 |
28 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Basic Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example3.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Carto.CartoStore'
7 | ]);
8 |
9 | /**
10 | *
11 | * Basic map Centered on US with a starter layer
12 | */
13 | Ext.onReady(function () {
14 | Ext.QuickTips.init();
15 |
16 | Ext.create('Ext.container.Viewport', {
17 | layout: 'fit',
18 | items: [{
19 | xtype: "cartomap",
20 | center: 'us',
21 | layers: [{
22 | subLayers: [{
23 | store: {
24 | autoLoad: true,
25 | proxy: {
26 | username: 'extjscarto',
27 | table: 'petroleum_refineries'
28 | }
29 | }
30 | }]
31 |
32 | }]
33 | }]
34 | });
35 |
36 | });
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Basic Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/basicMap/basicMap-example4.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 | var dataStore = Ext.create('Ext.data.Store',{
11 | data: [{
12 | name: 'Petroleum Refineries',
13 | value: 'petroleum_refineries',
14 | mapLayer: {
15 | layerId: 'petroleumLayer',
16 | subLayers: [{
17 | store: {
18 | autoLoad: true,
19 | proxy: {
20 | username: 'extjscarto',
21 | table: 'petroleum_refineries'
22 | }
23 | }
24 | }]
25 | }
26 | }]
27 | });
28 |
29 |
30 | var mapController = Ext.create('Ext.app.ViewController',{
31 | onLayerAdd: function(combo, record, eOpts){
32 | this.lookup('map').addLayer(record.data.mapLayer, function(){
33 | console.log('mapLayerAdded');
34 | });
35 | this.lookup('removeButton').enable();
36 | },
37 | removeMapLayer: function(button, e, eOpts) {
38 | this.lookup('map').removeLayer('petroleumLayer', true);
39 | this.lookup('combo').reset();
40 | button.disable();
41 | }
42 | });
43 |
44 | /**
45 | *
46 | * Basic map w/toolbar Centered on US.
47 | */
48 | Ext.onReady(function () {
49 | Ext.QuickTips.init();
50 |
51 | Ext.create('Ext.container.Viewport', {
52 | layout: 'fit',
53 | items: [{
54 | xtype: 'panel',
55 | layout: 'fit',
56 | controller: mapController,
57 | items: [{
58 | xtype: "cartomap",
59 | center: 'us',
60 | reference: 'map'
61 | }],
62 | tbar: [{
63 | xtype: 'combobox',
64 | reference: 'combo',
65 | fieldLabel: 'Select Layer',
66 | displayField: 'name',
67 | valueField: 'value',
68 | store: dataStore,
69 | listeners: {
70 | select: 'onLayerAdd'
71 | },
72 | width: 350,
73 | editable: false
74 | },{
75 | xtype: 'button',
76 | text: 'Remove Layer',
77 | handler: 'removeMapLayer',
78 | disabled: true,
79 | reference: 'removeButton'
80 | }]
81 | }]
82 | });
83 | });
--------------------------------------------------------------------------------
/examples/cartoAccount/cartoAccount-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Carto Account Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/cartoAccount/cartoAccount-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Carto.CartoStore',
7 | 'Carto.CartoProxy',
8 | 'Carto.CartoBasemaps',
9 | 'Ext.data.Store'
10 | ]);
11 |
12 | var columnsToIgnore = ['cartodb_id', 'the_geom', 'the_geom_webmercator'];
13 | var numberTypes = ['double precision', 'integer', 'number'];
14 |
15 | var mapController = Ext.create('Ext.app.ViewController',{
16 | reset: function(all) {
17 | if (all) {
18 | this.lookup('tableBox').clearValue();
19 | this.getStore('tables').removeAll();
20 | }
21 | this.lookup('fieldBox').clearValue();
22 | this.lookup('numberFieldBox').clearValue();
23 | this.getStore('columns').removeAll();
24 | },
25 | onSelectUsername: function(field, e) {
26 | var value = field.getValue();
27 | if (value !== this.getViewModel().get('username')) {
28 | this.reset(true);
29 | this.getViewModel().set('username', value);
30 | this.getStore('tables').getProxy().setUsername(value);
31 | this.getStore('columns').getProxy().setUsername(value);
32 | this.getStore('tables').load();
33 | }
34 | },
35 | catchError: function(store, records, successful) {
36 | if (!successful) {
37 | Ext.Msg.alert('Error', 'There was a problem loading your tables. Please check your username.', Ext.emptyFn);
38 | }
39 | },
40 | onSelectTable: function(combo, record) {
41 | var value = record.get('table_name');
42 | this.reset(false);
43 | this.getViewModel().set('table', value);
44 | this.getStore('columns').getProxy().setTable(value);
45 | this.getStore('columns').load();
46 | }
47 | });
48 |
49 | Ext.onReady(function () {
50 | Ext.QuickTips.init();
51 |
52 | Ext.create('Ext.container.Viewport', {
53 | layout: 'fit',
54 | items: [{
55 | xtype: 'panel',
56 | layout: {
57 | type: 'vbox',
58 | align: 'center',
59 | pack: 'center'
60 | },
61 | controller: mapController,
62 | viewModel: {
63 | stores: {
64 | tables: {
65 | storeId: 'tablesStore',
66 | sorters: 'table_name',
67 | proxy: {
68 | type: 'carto',
69 | mode: 'tables'
70 | },
71 | listeners: {
72 | load: 'catchError'
73 | }
74 | },
75 | columns: {
76 | storeId: 'columnsStore',
77 | sorters: 'column_name',
78 | proxy: {
79 | type: 'carto',
80 | mode: 'columns'
81 | },
82 | filters: [
83 | function(data) {
84 | return columnsToIgnore.indexOf(data.get('column_name')) === -1;
85 | }
86 | ]
87 | },
88 | numberColumns: {
89 | source: '{columns}',
90 | filters: [
91 | function(data) {
92 | return numberTypes.indexOf(data.get('column_type')) > -1;
93 | }
94 | ]
95 | }
96 | },
97 | data: {
98 | username: null,
99 | table: null
100 | }
101 | },
102 | defaults: {
103 | xtype: 'combobox',
104 | valueField: 'column_name',
105 | displayField: 'column_name',
106 | labelWidth: 200,
107 | editable: false
108 | },
109 | items: [{
110 | xtype: 'textfield',
111 | reference: 'usernameField',
112 | fieldLabel: 'Username',
113 | editable: true,
114 | listeners: {
115 | blur: 'onSelectUsername'
116 | }
117 | }, {
118 | reference: 'tableBox',
119 | valueField: 'table_name',
120 | displayField: 'table_name',
121 | listeners: {
122 | select: 'onSelectTable'
123 | },
124 | bind: {
125 | fieldLabel: '{username}\'s tables',
126 | store: '{tables}'
127 | }
128 | }, {
129 | reference: 'fieldBox',
130 | bind: {
131 | fieldLabel: '{table}\'s fields',
132 | store: '{columns}',
133 | disabled: '{!table}'
134 | }
135 | }, {
136 | reference: 'numberFieldBox',
137 | queryMode: 'local',
138 | bind: {
139 | fieldLabel: '{table}\'s number fields',
140 | store: '{numberColumns}',
141 | disabled: '{!table}'
142 | }
143 | }]
144 | }]
145 | });
146 | });
--------------------------------------------------------------------------------
/examples/chartMap/chartMap-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ChartMap demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/examples/chartMap/chartMap-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Carto.CartoStore'
7 | ]);
8 |
9 |
10 | Ext.onReady(function () {
11 | Ext.QuickTips.init();
12 |
13 | Ext.create('Ext.container.Viewport', {
14 | layout: 'fit',
15 | items: [{
16 | xtype: 'panel',
17 | layout: 'border',
18 | viewModel: {
19 | data: {
20 | filterCombo: {
21 | selection: {
22 | author_gender: null
23 | }
24 | },
25 | filterField: {
26 | value: ''
27 | }
28 | },
29 | stores: {
30 | layer: {
31 | type: 'carto',
32 | storeId: 'layer',
33 | autoLoad: true,
34 | filters: [{
35 | property: 'author_gender',
36 | value: '{filterCombo.selection.author_gender}',
37 | disableOnEmpty: true
38 | }, {
39 | property: 'text',
40 | value: '{filterField.value}',
41 | operator: 'regex',
42 | disableOnEmpty: true
43 | }],
44 | proxy: {
45 | username: 'extjscarto',
46 | table: 'starwars'
47 | }
48 | },
49 | chart: {
50 | type: 'carto',
51 | storeId: 'chart',
52 | autoLoad: true,
53 | filters: [{
54 | property: 'author_gender',
55 | value: '{filterCombo.selection.author_gender}',
56 | disableOnEmpty: true
57 | }, {
58 | property: 'text',
59 | value: '{filterField.value}',
60 | operator: 'regex',
61 | disableOnEmpty: true
62 | }],
63 | proxy: {
64 | groupBy: 'sentiment',
65 | username: 'extjscarto',
66 | table: 'starwars'
67 | }
68 | },
69 | combo: {
70 | type: 'carto',
71 | storeId: 'combo',
72 | autoLoad: true,
73 | proxy: {
74 | groupBy: 'author_gender',
75 | username: 'extjscarto',
76 | table: 'starwars'
77 | }
78 | }
79 | }
80 | },
81 | tbar: [{
82 | xtype: 'combo',
83 | reference: 'filterCombo',
84 | fieldLabel: 'Author Gender',
85 | forceSelection: true,
86 | bind: {
87 | store: '{combo}'
88 | },
89 | displayField: 'author_gender',
90 | valueField: 'author_gender'
91 | }, {
92 | xtype: 'textfield',
93 | reference: 'filterField',
94 | publishes: ['value'],
95 | fieldLabel: 'Keyword'
96 | }],
97 | items: [{
98 | xtype: "cartomap",
99 | region: 'center',
100 | center: 'us',
101 | layers: [{
102 | subLayers: [{
103 | bind: '{layer}',
104 | interactivity: {
105 | enable: true,
106 | tooltip: {
107 | enable: true
108 | },
109 | fields: ['text']
110 | },
111 | css: [
112 | "#layer {",
113 | " marker-line-width: 1;",
114 | " marker-line-color: #FFF;",
115 | " marker-line-opacity: 1;",
116 | " marker-width: 7;",
117 | " marker-fill: gray;",
118 | " marker-fill-opacity: 0.9;",
119 | " marker-allow-overlap: true;",
120 | "}",
121 | "#layer [sentiment = 'pos'] {",
122 | " marker-fill: blue;",
123 | "}",
124 | "#layer [sentiment = 'neg'] {",
125 | " marker-fill: red;",
126 | "}"
127 | ]
128 | }]
129 | }]
130 | }, {
131 | xtype: 'cartesian',
132 | region: 'west',
133 | split: true,
134 | width: '30%',
135 | bind: '{chart}',
136 | axes: [{
137 | type: 'numeric',
138 | position: 'left',
139 | title: {
140 | text: 'Number',
141 | fontSize: 15
142 | },
143 | fields: 'cnt'
144 | }, {
145 | type: 'category',
146 | position: 'bottom',
147 | title: {
148 | text: 'Sentiment',
149 | fontSize: 15
150 | },
151 | fields: 'sentiment'
152 | }],
153 | series: {
154 | type: 'bar',
155 | renderer: function(sprite, config, rendererData, index) {
156 | return {
157 | fillStyle: (index === 0) ? 'gray' : (index === 1) ? 'blue' : 'red'
158 | };
159 | },
160 | subStyle: {
161 | stroke: '#1F6D91'
162 | },
163 | xField: 'sentiment',
164 | yField: 'cnt'
165 | }
166 | }]
167 | }]
168 | });
169 | });
--------------------------------------------------------------------------------
/examples/fireMap/fireMap-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FireMap demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/examples/fireMap/fireMap-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 | var dataTextStore = Ext.create('Ext.data.Store',{
10 | data: [{
11 | title: 'Federal Fire Occurrence',
12 | total: '694,294',
13 | natural: '287,674 natural',
14 | human: '380,984 human',
15 | fromYear: '1980',
16 | toYear: '2013'
17 | }]
18 | });
19 |
20 | var txtTpl = new Ext.XTemplate(
21 | '',
22 | '{title} ',
23 | 'Explore {total} ({natural} , {human} ) fire records collected by Federal land management agencies for fires that occurred from {fromYear} through {toYear} in the United States.
',
24 | ' '
25 | );
26 |
27 | var flag = false
28 |
29 | var dataStore = Ext.create('Ext.data.Store',{
30 | data: [{
31 | name: 'Fire Map',
32 | value: 0,
33 | mapLayer: {
34 | layerId: 'fireLayer',
35 | subLayers: [{
36 | store: {
37 | autoLoad: true,
38 | proxy: {
39 | username: 'crestonedigital',
40 | table: 'wildfire'
41 | }
42 | },
43 | css: [
44 | '#wildfire{',
45 | 'marker-fill-opacity: 0.05;',
46 | 'marker-line-color: #FFF;',
47 | 'marker-line-width: 0.0;',
48 | 'marker-line-opacity: 1;',
49 | 'marker-placement: point;',
50 | 'marker-type: ellipse;',
51 | 'marker-width: 6;',
52 | 'marker-fill: #FF5C00;',
53 | 'marker-allow-overlap: true;',
54 | '}',
55 | '#wildfire [zoom <18]{',
56 | 'marker-fill-opacity: 0.7;',
57 | '}',
58 | '#wildfire [zoom <9]{',
59 | 'marker-fill-opacity: 0.4;',
60 | 'marker-width: 5;',
61 | '}',
62 | '#wildfire [zoom <8]{',
63 | 'marker-fill-opacity: 0.2;',
64 | 'marker-width: 4;',
65 | '}',
66 | '#wildfire [zoom <7]{',
67 | 'marker-fill-opacity: 0.08;',
68 | 'marker-width: 3;',
69 | '}',
70 | '#wildfire [zoom <6]{',
71 | 'marker-fill-opacity: 0.07;',
72 | 'marker-width: 2;',
73 | '}',
74 | '#wildfire [zoom <5]{',
75 | 'marker-width: 1;',
76 | '}'
77 | ].join(' ')
78 | }]
79 | }
80 | },{
81 | name: 'Causes Map',
82 | value: 1,
83 | mapLayer: {
84 | layerId: 'causesLayer',
85 | subLayers: [{
86 | store: {
87 | autoLoad: true,
88 | proxy: {
89 | username: 'crestonedigital',
90 | table: 'wildfire'
91 | }
92 | },
93 | css: [
94 | '#wildfire {'+
95 | 'marker-fill-opacity: 0.9;'+
96 | 'marker-line-color: #000;'+
97 | 'marker-line-width: 0;'+
98 | 'marker-line-opacity: 0;'+
99 | 'marker-placement: point;'+
100 | 'marker-type: ellipse;'+
101 | 'marker-width: 6;'+
102 | 'marker-allow-overlap: true;'+
103 | '}'+
104 | '#wildfire[cause="Human"] {'+
105 | 'marker-fill: #1F78B4;'+
106 | '}'+
107 | '#wildfire[cause="Natural"] {'+
108 | 'marker-fill: #B2DF8A;'+
109 | '}'+
110 | '#wildfire [zoom <18]{'+
111 | 'marker-fill-opacity: 0.7;'+
112 | '}'+
113 | '#wildfire [zoom <9]{'+
114 | 'marker-fill-opacity: 0.4;'+
115 | 'marker-width: 5;'+
116 | '}'+
117 | '#wildfire [zoom <8]{'+
118 | 'marker-fill-opacity: 0.2;'+
119 | 'marker-width: 4;'+
120 | '}'+
121 | '#wildfire [zoom <7]{'+
122 | 'marker-fill-opacity: 0.08;'+
123 | 'marker-width: 3;'+
124 | '}'+
125 | '#wildfire [zoom <6]{'+
126 | 'marker-fill-opacity: 0.07;'+
127 | 'marker-width: 2;'+
128 | '}'+
129 | '#wildfire [zoom <5]{'+
130 | 'marker-width: 1;'+
131 | '}'
132 | ].join(' ')
133 | }]
134 | }
135 | }]
136 | });
137 |
138 |
139 | var mapController = Ext.create('Ext.app.ViewController',{
140 | onLayerAdd: function(tag, newRecord, oldRecord){
141 | var idx;
142 | if (newRecord.length > oldRecord.length) {
143 | idx = this.getDiff(newRecord, oldRecord);
144 | this.lookup('map').addLayer(dataStore.data.items[newRecord[idx]].get('mapLayer'));
145 | } else {
146 | idx = this.getDiff(oldRecord, newRecord);
147 | this.lookup('map').removeLayer(dataStore.data.items[oldRecord[idx]].get('mapLayer').layerId, true);
148 | }
149 | },
150 |
151 | getDiff: function(arr1, arr2) {
152 | for (var i = 0; i < arr1.length; i++) {
153 | if (arr2.indexOf(arr1[i]) === -1) {
154 | return i;
155 | }
156 | }
157 | return null;
158 | }
159 | });
160 |
161 | /**
162 | *
163 | * Basic map w/toolbar Centered on US.
164 | */
165 | Ext.onReady(function () {
166 | Ext.QuickTips.init();
167 |
168 | Ext.create('Ext.container.Viewport', {
169 | layout: 'fit',
170 | items: [{
171 | xtype: 'panel',
172 | layout: 'fit',
173 | controller: mapController,
174 | items: [{
175 | xtype: "cartomap",
176 | center: 'us',
177 | reference: 'map',
178 | basemap: 'darkMatterLite'
179 | }],
180 | tbar: [{
181 | xtype: 'tagfield',
182 | reference: 'layers',
183 | fieldLabel: 'Select Layer',
184 | displayField: 'name',
185 | valueField: 'value',
186 | store: dataStore,
187 | listeners: {
188 | change: 'onLayerAdd'
189 | },
190 | width: 350,
191 | editable: false
192 | }]
193 | }]
194 | });
195 | });
--------------------------------------------------------------------------------
/examples/fireMap/fireMap-example2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FireMap demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/examples/fireMap/fireMap-example3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FireMap demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/examples/fireMap/fireMap-example3.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 | var mapController = Ext.create('Ext.app.ViewController',{
11 | onLayerChange: function(segButton, value, oldValue){
12 | var map = this.lookup('map');
13 | if (oldValue) {
14 | map.removeLayer(map.getLayers().first(), true);
15 | }
16 | map.addLayer(value);
17 | map.getLayer('layer').setStore(this.getStore('fireLayer'));
18 |
19 | // var map = this.lookup('map');
20 | // if (oldValue.length) {
21 | // map.removeLayer(map.getLayers().first(), true);
22 | // }
23 | // map.addLayer(value[0]);
24 | // map.getLayer('layer').setStore(this.getStore('fireLayer'));
25 | }
26 | });
27 |
28 | /**
29 | *
30 | * Basic map w/toolbar Centered on US.
31 | */
32 | Ext.onReady(function () {
33 | Ext.QuickTips.init();
34 |
35 | Ext.create('Ext.container.Viewport', {
36 | layout: 'fit',
37 | items: [{
38 | xtype: 'panel',
39 | layout: 'fit',
40 | controller: mapController,
41 | viewModel: {
42 | stores: {
43 | fireLayer: {
44 | type: 'carto',
45 | autoLoad: true,
46 | onlyTiles: true,
47 | proxy: {
48 | username: 'crestonedigital',
49 | table: 'wildfire'
50 | }
51 | }
52 | }
53 | },
54 | items: [{
55 | xtype: "cartomap",
56 | center: 'us',
57 | reference: 'map',
58 | basemap: 'darkMatterLite'
59 | }],
60 | tbar: [{
61 | xtype: 'segmentedbutton',
62 | reference: 'cssButton',
63 | listeners: {
64 | change: 'onLayerChange'
65 | },
66 | items: [{
67 | text: 'Intensity',
68 | value: {
69 | subLayers: {
70 | layerId: 'layer',
71 | css: {
72 | type: 'intensity',
73 | value: {
74 | markerFillOpacity: 0.05,
75 | markerLineWidth: 0.0,
76 | markerWidth: 6,
77 | markerFill: '#FF5C00',
78 | case: [{
79 | condition: 'zoom<18',
80 | markerFillOpacity: 0.7
81 | }, {
82 | condition: 'zoom<9',
83 | markerFillOpacity: 0.4,
84 | markerWidth: 5
85 | }, {
86 | condition: 'zoom<8',
87 | markerFillOpacity: 0.2,
88 | markerWidth: 4
89 | }, {
90 | condition: 'zoom<7',
91 | markerFillOpacity: 0.08,
92 | markerWidth: 3
93 | }, {
94 | condition: 'zoom<6',
95 | markerFillOpacity: 0.07,
96 | markerWidth: 2
97 | }, {
98 | condition: 'zoom<5',
99 | markerWidth: 1
100 | }]
101 | }
102 | }
103 | }
104 | },
105 | pressed: true
106 | }, {
107 | text: 'Heatmap',
108 | value: {
109 | type: 'torque',
110 | layerId: 'layer',
111 | css: {
112 | type: 'heatmap'
113 | }
114 | }
115 | }]
116 | }]
117 | }]
118 | });
119 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Carto.CartoStore'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | onSelect: function(rowmodel, record) {
13 | this.lookup('southGrid').ensureVisible(record);
14 | }
15 | });
16 |
17 | /**
18 | *
19 | * Basic map w/toolbar Centered on US.
20 | */
21 | Ext.onReady(function () {
22 | Ext.QuickTips.init();
23 |
24 | Ext.create('Ext.container.Viewport', {
25 | layout: 'fit',
26 | items: [{
27 | xtype: 'panel',
28 | layout: 'border',
29 | viewModel: {
30 | stores: {
31 | layer: {
32 | type: 'carto',
33 | autoLoad: true,
34 | proxy: {
35 | username: 'extjscarto',
36 | table: 'petroleum_refineries'
37 | }
38 | }
39 | }
40 | },
41 | controller: mapController,
42 | items: [{
43 | xtype: "cartomap",
44 | region: 'center',
45 | center: 'us',
46 | reference: 'map',
47 | bind: {
48 | selection: '{selectedValue}'
49 | },
50 | basemap: 'darkMatterLite',
51 | layers: [{
52 | subLayers: [{
53 | css: {
54 | type: 'intensity',
55 | },
56 | bind: '{layer}',
57 | interactivity: {
58 | enable: true,
59 | fields: [
60 | 'site_name', 'company', 'state', 'total_oper'
61 | ],
62 | tooltip: {
63 | enable: true
64 | }
65 | }
66 | }]
67 |
68 | }]
69 | },{
70 | xtype: 'grid',
71 | region: 'south',
72 | reference: 'southGrid',
73 | split: true,
74 | idProperty: 'cartodb_id',
75 | bind: {
76 | selection: '{selectedValue}',
77 | store: '{layer}'
78 | },
79 | listeners: {
80 | select: 'onSelect'
81 | },
82 | height: 350,
83 | columns: [{
84 | text: 'Site Name',
85 | dataIndex: 'site_name',
86 | flex: 1
87 | },{
88 | text: 'Company',
89 | dataIndex: 'company',
90 | flex: 1
91 | },{
92 | text: 'State',
93 | dataIndex: 'state',
94 | flex: 1
95 | },{
96 | text: 'Total Operation',
97 | dataIndex: 'total_oper',
98 | flex: 1
99 | }]
100 | }]
101 | }]
102 | });
103 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example2.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 | Ext.onReady(function () {
10 | Ext.QuickTips.init();
11 |
12 | Ext.create('Ext.container.Viewport', {
13 | layout: 'fit',
14 | items: [{
15 | xtype: 'panel',
16 | layout: 'border',
17 | viewModel: {
18 | stores: {
19 | layer: {
20 | type: 'carto',
21 | autoLoad: true,
22 | proxy: {
23 | enableLatLng: true,
24 | username: 'extjscarto',
25 | table: 'petroleum_refineries'
26 | }
27 | }
28 | }
29 | },
30 | items: [{
31 | xtype: "cartomap",
32 | region: 'center',
33 | center: 'us',
34 | reference: 'map',
35 | bind: {
36 | selection: '{selectedValue}'
37 | },
38 | selectedAction: ['panTo','placeMarker'],
39 | basemap: 'darkMatterLite',
40 | layers: [{
41 | hidden: true,
42 | subLayers: [{
43 | bind: '{layer}',
44 | interactivity: {
45 | enable: true,
46 | fields: [
47 | 'site_name', 'company', 'state', 'total_oper'
48 | ]
49 | }
50 | }]
51 |
52 | }]
53 | },{
54 | xtype: 'grid',
55 | region: 'south',
56 | reference: 'southGrid',
57 | split: true,
58 | idProperty: 'cartodb_id',
59 | bind: {
60 | selection: '{selectedValue}',
61 | store: '{layer}'
62 | },
63 | height: 350,
64 | columns: [{
65 | text: 'Site Name',
66 | dataIndex: 'site_name',
67 | flex: 1
68 | },{
69 | text: 'Company',
70 | dataIndex: 'company',
71 | flex: 1
72 | },{
73 | text: 'State',
74 | dataIndex: 'state',
75 | flex: 1
76 | },{
77 | text: 'Total Operation',
78 | dataIndex: 'total_oper',
79 | flex: 1
80 | }]
81 | }, {
82 | xtype: 'container',
83 | reference: 'detailsPanel',
84 | padding: 10,
85 | width: '15%',
86 | region: 'east',
87 | split: true,
88 | tpl: ['Site Name ',
89 | '{site_name}
',
90 | 'Company ',
91 | '{company}
',
92 | 'State ',
93 | '{state}
',
94 | 'Number of Operations ',
95 | '{total_oper}
'],
96 | bind: {
97 | data: '{selectedValue}'
98 | }
99 | }]
100 | }]
101 | });
102 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example3.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | onSelect: function(rowmodel, record) {
13 | this.lookup('southGrid').ensureVisible(record);
14 | }
15 | });
16 |
17 |
18 | Ext.onReady(function () {
19 | Ext.QuickTips.init();
20 |
21 | Ext.create('Ext.container.Viewport', {
22 | layout: 'fit',
23 | items: [{
24 | xtype: 'panel',
25 | layout: 'border',
26 | viewModel: {
27 | stores: {
28 | layer: {
29 | storeId: 'layer1',
30 | type: 'carto',
31 | autoLoad: true,
32 | proxy: {
33 | enableLatLng: true,
34 | username: 'extjscarto',
35 | table: 'petroleum_refineries'
36 | }
37 | }
38 | }
39 | },
40 | controller: mapController,
41 | tbar: {
42 | items: {
43 | xtype: 'checkboxfield',
44 | reference: 'lockToMapBox',
45 | boxLabel: 'Lock to Map'
46 | }
47 | },
48 | items: [{
49 | xtype: "cartomap",
50 | region: 'center',
51 | center: 'us',
52 | reference: 'map',
53 | bind: {
54 | selection: '{selectedValue}',
55 | mapLock: '{lockToMapBox.checked}'
56 | },
57 | storesToLock: ['layer1'],
58 | basemap: 'darkMatterLite',
59 | layers: [{
60 | subLayers: [{
61 | bind: '{layer}',
62 | interactivity: {
63 | enable: true,
64 | fields: [
65 | 'site_name', 'company', 'state', 'total_oper'
66 | ],
67 | tooltip: {
68 | enable: true
69 | }
70 | }
71 | }]
72 | }]
73 | },{
74 | xtype: 'grid',
75 | region: 'south',
76 | reference: 'southGrid',
77 | split: true,
78 | idProperty: 'cartodb_id',
79 | bind: {
80 | selection: '{selectedValue}',
81 | store: '{layer}'
82 | },
83 | listeners: {
84 | select: 'onSelect'
85 | },
86 | height: 350,
87 | columns: [{
88 | text: 'Site Name',
89 | dataIndex: 'site_name',
90 | flex: 1
91 | },{
92 | text: 'Company',
93 | dataIndex: 'company',
94 | flex: 1
95 | },{
96 | text: 'State',
97 | dataIndex: 'state',
98 | flex: 1
99 | },{
100 | text: 'Total Operation',
101 | dataIndex: 'total_oper',
102 | flex: 1
103 | }]
104 | }]
105 | }]
106 | });
107 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example4.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | filterStore: function(combo, record){
13 | this.getStore('layer').filter('city', record.get('city'));
14 | },
15 | clearFilter: function(){
16 | this.lookup('comboFilter').reset();
17 | this.getStore('layer').clearFilter();
18 | }
19 | });
20 |
21 | Ext.onReady(function () {
22 | Ext.QuickTips.init();
23 |
24 | Ext.create('Ext.container.Viewport', {
25 | layout: 'fit',
26 | items: [{
27 | xtype: 'panel',
28 | layout: 'border',
29 | viewModel: {
30 | stores: {
31 | layer: {
32 | storeId: 'layer1',
33 | type: 'carto',
34 | autoLoad: true,
35 | proxy: {
36 | username: 'extjscarto',
37 | table: 'us_metro_stations'
38 | }
39 | },
40 | combo: {
41 | type: 'carto',
42 | sorters: 'city',
43 | proxy: {
44 | username: 'extjscarto',
45 | table: 'us_metro_stations',
46 | groupBy: 'city'
47 | }
48 | }
49 | }
50 | },
51 | controller: mapController,
52 | dockedItems: [{
53 | xtype: 'toolbar',
54 | dock: 'top',
55 | items: [{
56 | text: 'View Code',
57 | },{
58 | xtype: 'combo',
59 | fieldLabel: "City Filters",
60 | reference: 'comboFilter',
61 | displayField: 'city',
62 | valueField: 'city',
63 | bind: {
64 | store: '{combo}'
65 | },
66 | listeners: {
67 | select: 'filterStore'
68 | }
69 | },{
70 | xtype: 'button',
71 | text: 'Clear Filter',
72 | handler: 'clearFilter'
73 | }]
74 | }],
75 | items: [{
76 | xtype: "cartomap",
77 | region: 'center',
78 | center: 'us',
79 | reference: 'map',
80 | basemap: 'darkMatterLite',
81 | layers: [{
82 | subLayers: [{
83 | bind: '{layer}'
84 | }]
85 | }]
86 | },{
87 | xtype: 'grid',
88 | region: 'south',
89 | reference: 'southGrid',
90 | split: true,
91 | height: 350,
92 | plugins: 'gridfilters',
93 | bind: {
94 | store: '{layer}'
95 | },
96 | columns: [
97 | { text: 'City', dataIndex: 'city', flex: 1, filter: {
98 | type: 'string',
99 | itemDefaults: {
100 | emptyText: 'Search for...'
101 | }
102 | } },
103 | { text: 'Name', dataIndex: 'name', flex: 2 }
104 | ],
105 | }]
106 | }]
107 | });
108 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example5.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | filterStore: function(combo, record){
13 | if (record) {
14 | this.getStore('layer').filter([{
15 | property: 'city',
16 | value: record,
17 | operator: 'like'
18 | }]);
19 | } else {
20 | this.clearFilter();
21 | }
22 | },
23 | clearFilter: function(){
24 | this.lookup('comboFilter').reset();
25 | this.getStore('layer').clearFilter();
26 | }
27 | });
28 |
29 | Ext.onReady(function () {
30 | Ext.QuickTips.init();
31 |
32 | Ext.create('Ext.container.Viewport', {
33 | layout: 'fit',
34 | items: [{
35 | xtype: 'panel',
36 | layout: 'border',
37 | viewModel: {
38 | stores: {
39 | layer: {
40 | storeId: 'layer1',
41 | type: 'carto',
42 | autoLoad: true,
43 | proxy: {
44 | username: 'extjscarto',
45 | table: 'us_metro_stations'
46 | }
47 | },
48 | combo: {
49 | type: 'carto',
50 | sorters: 'city',
51 | proxy: {
52 | username: 'extjscarto',
53 | table: 'us_metro_stations',
54 | groupBy: 'city'
55 | }
56 | }
57 | }
58 | },
59 | controller: mapController,
60 | dockedItems: [{
61 | xtype: 'toolbar',
62 | dock: 'top',
63 | items: [{
64 | text: 'View Code',
65 | },{
66 | xtype: 'combo',
67 | fieldLabel: "City Filters",
68 | reference: 'comboFilter',
69 | displayField: 'city',
70 | valueField: 'city',
71 | bind: {
72 | store: '{combo}'
73 | },
74 | listeners: {
75 | change: 'filterStore'
76 | }
77 | },{
78 | xtype: 'button',
79 | text: 'Clear Filter',
80 | handler: 'clearFilter'
81 | }]
82 | }],
83 | items: [{
84 | xtype: "cartomap",
85 | region: 'center',
86 | center: 'us',
87 | reference: 'map',
88 | basemap: 'darkMatterLite',
89 | layers: [{
90 | subLayers: [{
91 | bind: '{layer}'
92 | }]
93 | }]
94 | },{
95 | xtype: 'grid',
96 | region: 'south',
97 | reference: 'southGrid',
98 | split: true,
99 | height: 350,
100 | plugins: 'gridfilters',
101 | bind: {
102 | store: '{layer}'
103 | },
104 | columns: [
105 | { text: 'City', dataIndex: 'city', flex: 1, filter: {
106 | type: 'string',
107 | itemDefaults: {
108 | emptyText: 'Search for...'
109 | }
110 | } },
111 | { text: 'Name', dataIndex: 'name', flex: 2 }
112 | ],
113 | }]
114 | }]
115 | });
116 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example6.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | filterStore: function(combo, record){
13 | Ext.getStore('layer1').filter([{
14 | property: 'sentiment',
15 | value: record.get('value')
16 | }]);
17 | },
18 | clearFilter: function(){
19 | this.lookup('comboFilter').reset();
20 | Ext.getStore('layer1').clearFilter();
21 | }
22 | });
23 |
24 | Ext.onReady(function () {
25 | Ext.QuickTips.init();
26 |
27 | Ext.create('Ext.container.Viewport', {
28 | layout: 'fit',
29 | items: [{
30 | xtype: 'panel',
31 | layout: 'border',
32 | viewModel: {
33 | stores: {
34 | layer: {
35 | storeId: 'layer1',
36 | type: 'carto',
37 | autoLoad: true,
38 | pageSize: 20,
39 | proxy: {
40 | username: 'extjscarto',
41 | table: 'starwars',
42 | reader: {
43 | transform: {
44 | fn: function(data) {
45 | data.rows.forEach(function(item){
46 | item.timestamp = new Date(item.timestamp/1000000);
47 | }.bind(this));
48 | return data;
49 | }
50 | }
51 | }
52 | }
53 | },
54 | combo: {
55 | data: [{
56 | name: 'Negative',
57 | value: 'neg'
58 | },{
59 | name: 'Postive',
60 | value: 'pos'
61 | }]
62 | }
63 | }
64 | },
65 | controller: mapController,
66 | dockedItems: [{
67 | xtype: 'toolbar',
68 | dock: 'top',
69 | items: [{
70 | text: 'View Code',
71 | },{
72 | xtype: 'combo',
73 | fieldLabel: "Sentiment Filter",
74 | reference: 'comboFilter',
75 | displayField: 'name',
76 | valueField: 'value',
77 | bind: {
78 | store: '{combo}'
79 | },
80 | listeners: {
81 | select: 'filterStore'
82 | }
83 | },{
84 | xtype: 'button',
85 | text: 'Clear Filter',
86 | handler: 'clearFilter'
87 | }]
88 | }],
89 | items: [{
90 | xtype: "cartomap",
91 | region: 'center',
92 | center: 'us',
93 | reference: 'map',
94 | basemap: 'darkMatterLite',
95 | layers: [{
96 | subLayers: [{
97 | bind: '{layer}',
98 | css: {
99 | type: 'intensity'
100 | }
101 | }]
102 | }]
103 | },{
104 | xtype: 'grid',
105 | region: 'south',
106 | reference: 'southGrid',
107 | split: true,
108 | height: 350,
109 | plugins: 'gridfilters',
110 | bind: {
111 | store: '{layer}'
112 | },
113 | dockedItems: [{
114 | xtype: 'pagingtoolbar',
115 | dock: 'bottom',
116 | bind: {
117 | store: '{layer}'
118 | },
119 | displayInfo: true
120 | }],
121 | columns: [{
122 | text: 'Author Handle',
123 | dataIndex: 'author_handle',
124 | flex: 2,
125 | filter: {
126 | type: 'string',
127 | itemDefaults: {
128 | emptyText: 'Search for...'
129 | }
130 | }
131 | },{
132 | text: 'Author Gender',
133 | dataIndex: 'author_gender',
134 | flex: 1,
135 | filter: {
136 | type: 'string',
137 | itemDefaults: {
138 | emptyText: 'Search for...'
139 | }
140 | }
141 | },{
142 | text: 'Followers',
143 | dataIndex: 'followers',
144 | flex: 1,
145 | filter: {
146 | type: 'number',
147 | itemDefaults: {
148 | emptyText: 'Search for...'
149 | }
150 | }
151 | },{
152 | text: 'Sentiment',
153 | dataIndex: 'sentiment',
154 | flex: 1/2,
155 | filter: {
156 | type: 'string',
157 | itemDefaults: {
158 | emptyText: 'Search for...'
159 | }
160 | }
161 | },{
162 | text: 'Text',
163 | dataIndex: 'text',
164 | flex: 3,
165 | filter: {
166 | type: 'string',
167 | itemDefaults: {
168 | emptyText: 'Search for...'
169 | }
170 | }
171 | }]
172 | }]
173 | }]
174 | });
175 | });
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example7.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Grid Map demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridMap/gridMap-example7.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | filterStore: function(combo, record){
13 | Ext.getStore('layer1').filter([{
14 | property: 'case_status',
15 | value: record.get('value'),
16 | operator: 'like'
17 | }]);
18 | },
19 | clearFilter: function(){
20 | this.lookup('comboFilter').reset();
21 | Ext.getStore('layer1').clearFilter();
22 | }
23 | });
24 |
25 | Ext.onReady(function () {
26 | Ext.QuickTips.init();
27 |
28 | Ext.create('Ext.container.Viewport', {
29 | layout: 'fit',
30 | items: [{
31 | xtype: 'panel',
32 | layout: 'border',
33 | viewModel: {
34 | stores: {
35 | layer: {
36 | storeId: 'layer1',
37 | type: 'carto',
38 | autoLoad: true,
39 | proxy: {
40 | username: 'extjscarto',
41 | table: 'denver_service_requests',
42 | reader: {
43 | transform: {
44 | fn: function(data) {
45 | data.rows.forEach(function(item){
46 | item.timestamp = new Date(item.timestamp/1000000);
47 | }.bind(this));
48 | return data;
49 | }
50 | }
51 | }
52 | }
53 | },
54 | combo: {
55 | data: [{
56 | name: 'Open',
57 | value: 'Open'
58 | },{
59 | name: 'Closed',
60 | value: 'Closed'
61 | }]
62 | }
63 | }
64 | },
65 | controller: mapController,
66 | dockedItems: [{
67 | xtype: 'toolbar',
68 | dock: 'top',
69 | items: [{
70 | text: 'View Code',
71 | },{
72 | xtype: 'combo',
73 | fieldLabel: "Case Filter",
74 | reference: 'comboFilter',
75 | displayField: 'name',
76 | valueField: 'value',
77 | bind: {
78 | store: '{combo}'
79 | },
80 | listeners: {
81 | select: 'filterStore'
82 | }
83 | },{
84 | xtype: 'button',
85 | text: 'Clear Filter',
86 | handler: 'clearFilter'
87 | }]
88 | }],
89 | items: [{
90 | xtype: "cartomap",
91 | region: 'center',
92 | center: 'us',
93 | reference: 'map',
94 | basemap: 'darkMatterLite',
95 | maskWhileLoading: true,
96 | layers: [{
97 | subLayers: [{
98 | bind: '{layer}',
99 | css: {
100 | type: 'intensity'
101 | }
102 | }]
103 | }]
104 | },{
105 | xtype: 'grid',
106 | region: 'south',
107 | reference: 'southGrid',
108 | split: true,
109 | height: 350,
110 | plugins: 'gridfilters',
111 | bind: {
112 | store: '{layer}'
113 | },
114 | columns: [{
115 | text: 'Agency',
116 | dataIndex: 'agency',
117 | flex: 2,
118 | filter: {
119 | type: 'string',
120 | itemDefaults: {
121 | emptyText: 'Search for...'
122 | }
123 | }
124 | },{
125 | text: 'Case Summary',
126 | dataIndex: 'case_summa',
127 | flex: 1,
128 | filter: {
129 | type: 'string',
130 | itemDefaults: {
131 | emptyText: 'Search for...'
132 | }
133 | }
134 | },{
135 | text: 'Case Status',
136 | dataIndex: 'case_status',
137 | flex: 1,
138 | filter: {
139 | type: 'string',
140 | itemDefaults: {
141 | emptyText: 'Search for...'
142 | }
143 | }
144 | },{
145 | xtype:'datecolumn',
146 | format:'m-d-Y',
147 | text: 'Date Created',
148 | dataIndex: 'case_cre_1',
149 | flex: 1,
150 | filter: {
151 | type: 'date',
152 | itemDefaults: {
153 | emptyText: 'Search for...'
154 | }
155 | }
156 | }],
157 | }]
158 | }]
159 | });
160 | });
--------------------------------------------------------------------------------
/examples/gridpanel/gridPanel-example3.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoProxy',
6 | 'Carto.CartoStore'
7 | ]);
8 |
9 | Ext.onReady(function () {
10 | Ext.QuickTips.init();
11 |
12 | Ext.create('Carto.CartoStore', {
13 | storeId: 'metrostopsStore',
14 | proxy: {
15 | username: 'extjscarto',
16 | table: 'us_metro_stations'
17 | },
18 | autoLoad: true
19 | });
20 |
21 | Ext.create('Ext.container.Viewport', {
22 | layout: 'fit',
23 | items: [{
24 | xtype: 'grid',
25 | title: 'United States - Metro Stops',
26 | store: Ext.data.StoreManager.lookup('metrostopsStore'),
27 | columns: [
28 | { text: 'City', dataIndex: 'city', flex: 1 },
29 | { text: 'Name', dataIndex: 'name', flex: 2 }
30 | ],
31 | /* Generic footer for reviewing example */
32 | dockedItems: [{
33 | xtype: 'toolbar',
34 | dock: 'top',
35 | items: [{
36 | text: 'View Code',
37 | },{
38 | xtype: 'combo',
39 | fieldLabel: "City Filters",
40 | displayField: 'name',
41 | valueField: 'value',
42 | store: Ext.create('Ext.data.Store', {
43 | data: [{
44 | name: 'Atlanta',
45 | value: 'atlanta'
46 | },{
47 | name: 'Boston',
48 | value: 'boston'
49 | }]
50 | }),
51 | listeners: {
52 | select: function(combo, record) {
53 | this.up('grid').store.filter('city', record.data.value);
54 | }
55 | }
56 | }]
57 | }]
58 | }]
59 | });
60 |
61 | });
--------------------------------------------------------------------------------
/examples/gridpanel/gridpanel-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GridPanel demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridpanel/gridpanel-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoProxy'
6 | ]);
7 |
8 | Ext.onReady(function () {
9 | Ext.QuickTips.init();
10 |
11 | Ext.create('Ext.data.Store', {
12 | storeId: 'metrostopsStore',
13 | remoteFilter: true,
14 | remoteSort: true,
15 | // sorters: 'city',
16 | sorters: [{
17 | property: 'city',
18 | direction: 'ASC'
19 | }, 'name'],
20 | proxy: {
21 | type: 'carto',
22 | username: 'extjscarto',
23 | table: 'us_metro_stations'
24 | },
25 | autoLoad: true
26 | });
27 |
28 | Ext.create('Ext.container.Viewport', {
29 | layout: 'fit',
30 | items: [{
31 | xtype: 'grid',
32 | title: 'United States - Metro Stops',
33 | store: Ext.data.StoreManager.lookup('metrostopsStore'),
34 | multiColumnSort: true,
35 | plugins: 'gridfilters',
36 | columns: [
37 | { text: 'City', dataIndex: 'city', flex: 1, filter: 'number' },
38 | {
39 | text: 'Name',
40 | dataIndex: 'name',
41 | flex: 2,
42 | filter: {
43 | type: 'string',
44 | itemDefaults: {
45 | emptyText: 'Search for...'
46 | }
47 | }
48 | }
49 | ],
50 |
51 | bbar: [{
52 | xtype: 'pagingtoolbar',
53 | store: Ext.data.StoreManager.lookup('metrostopsStore'),
54 | displayInfo: true
55 | }],
56 |
57 | /* Generic footer for reviewing example */
58 | dockedItems: [{
59 | xtype: 'toolbar',
60 | dock: 'bottom',
61 | ui: 'dark',
62 | padding: 10,
63 | items: [{
64 | text: 'View Code'
65 | }]
66 | }]
67 | }]
68 | });
69 |
70 | });
--------------------------------------------------------------------------------
/examples/gridpanel/gridpanel-example2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GridPanel demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/gridpanel/gridpanel-example2.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoProxy'
6 | ]);
7 |
8 | Ext.onReady(function () {
9 | Ext.QuickTips.init();
10 |
11 | Ext.create('Ext.data.Store', {
12 | storeId: 'metrostopsStore',
13 | proxy: {
14 | type: 'carto',
15 | username: 'extjscarto',
16 | table: 'us_metro_stations'
17 | },
18 | autoLoad: true
19 | });
20 |
21 | Ext.create('Ext.container.Viewport', {
22 | layout: 'fit',
23 | items: [{
24 | xtype: 'grid',
25 | title: 'United States - Metro Stops',
26 | store: Ext.data.StoreManager.lookup('metrostopsStore'),
27 | columns: [
28 | { text: 'City', dataIndex: 'city', flex: 1 },
29 | { text: 'Name', dataIndex: 'name', flex: 2 }
30 | ],
31 |
32 | /* Generic footer for reviewing example */
33 | dockedItems: [{
34 | xtype: 'toolbar',
35 | dock: 'bottom',
36 | items: [{
37 | text: 'View Code'
38 | }]
39 | }]
40 | }]
41 | });
42 |
43 | });
--------------------------------------------------------------------------------
/examples/gridpanel/gridpanel-example3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GridPanel demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/layerDemo/layerDemo-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Layer demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/layerDemo/layerDemo-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 | /**
10 | *
11 | * Layer Demo for different kinds of layers.
12 | */
13 | Ext.onReady(function () {
14 | Ext.QuickTips.init();
15 |
16 | Ext.create('Ext.container.Viewport', {
17 | layout: 'fit',
18 | items: [{
19 | xtype: 'panel',
20 | layout: 'fit',
21 | controller: Ext.create('Ext.app.ViewController'),
22 | viewModel: {
23 | stores: {
24 | tweets: {
25 | type: 'carto',
26 | autoLoad: true,
27 | onlyTiles: true,
28 | filters: {
29 | property: 'longitude',
30 | value: -90,
31 | operator: '>'
32 | },
33 | proxy: {
34 | username: 'crestonedigital',
35 | table: 'starwars'
36 | }
37 | },
38 | coloradoZipCodes: {
39 | type: 'carto',
40 | autoLoad: true,
41 | onlyTiles: true,
42 | proxy: {
43 | username: 'crestonedigital',
44 | table: 'colorado_zipcodes'
45 | }
46 | },
47 | oregonFires: {
48 | type: 'carto',
49 | autoLoad: true,
50 | onlyTiles: true,
51 | filters: {
52 | property: 'state',
53 | value: 'Oregon'
54 | },
55 | proxy: {
56 | username: 'crestonedigital',
57 | table: 'wildfire'
58 | }
59 | }
60 | }
61 | },
62 | items: [{
63 | xtype: "cartomap",
64 | center: 'us',
65 | reference: 'map',
66 | basemap: 'darkMatterLite',
67 | layers: [{
68 | type: 'torque',
69 | table: 'lac_hospitals_2011',
70 | username: 'crestonedigital',
71 | sql: 'SELECT * FROM lac_hospitals_2011',
72 | css: {
73 | type: 'torque'
74 | }
75 | }, {
76 | subLayers: [{
77 | bind: '{tweets}'
78 | }, {
79 | bind: '{coloradoZipCodes}',
80 | css: {
81 | type: 'polygon'
82 | }
83 | }]
84 | }, {
85 | type: 'torque',
86 | bind: '{oregonFires}',
87 | css: {
88 | type: 'heatmap',
89 | value: {
90 | markerFillOpacity: .4,
91 | markerWidth: 25,
92 | case: null
93 | }
94 | }
95 | }]
96 | }]
97 | }]
98 | });
99 | });
--------------------------------------------------------------------------------
/examples/playMap/playMap-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Map Play Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/examples/storeBinding/storeBinding-example1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Store Binding Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/examples/storeBinding/storeBinding-example1.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | 'Carto.CartoMap',
6 | 'Ext.data.Store'
7 | ]);
8 |
9 |
10 |
11 | var mapController = Ext.create('Ext.app.ViewController',{
12 | onSelect: function(rowmodel, record) {
13 | this.lookup('southGrid').ensureVisible(record);
14 | }
15 | });
16 |
17 | /**
18 | *
19 | * Basic map w/toolbar Centered on US.
20 | */
21 | Ext.onReady(function () {
22 | Ext.QuickTips.init();
23 |
24 | Ext.create('Ext.container.Viewport', {
25 | layout: 'fit',
26 | items: [{
27 | xtype: 'panel',
28 | layout: 'border',
29 | viewModel: {
30 | stores: {
31 | refineries: {
32 | type: 'carto',
33 | storeId: 'refineriesStore',
34 | autoLoad: true,
35 | proxy: {
36 | username: 'extjscarto',
37 | table: 'petroleum_refineries',
38 | enableLatLng: true
39 | }
40 | }
41 | }
42 | },
43 | controller: mapController,
44 | items: [{
45 | xtype: "cartomap",
46 | region: 'center',
47 | center: 'us',
48 | reference: 'map',
49 | bind: {
50 | selection: '{selectedValue}'
51 | },
52 | selectedAction: 'panTo',
53 | basemap: 'darkMatterLite',
54 | layers: [{
55 | subLayers: [{
56 | subLayerId: 'intenseLayer',
57 | bind: {
58 | store: '{refineries}'
59 | },
60 | css: {
61 | type: 'intensity'
62 | },
63 | interactivity: {
64 | enable: true,
65 | fields: [
66 | 'site_name', 'company', 'state', 'total_oper'
67 | ],
68 | tooltip: {
69 | enable: true
70 | }
71 | }
72 | }]
73 |
74 | }]
75 | }, {
76 | xtype: 'cartomap',
77 | region: 'east',
78 | width: '50%',
79 | bind: {
80 | selection: '{selectedValue}'
81 | },
82 | layers: [{
83 | subLayers: [{
84 | subLayerId: 'normalLayer',
85 | bind: {
86 | store: '{refineries}'
87 | },
88 | interactivity: {
89 | enable: true
90 | }
91 | }]
92 | }]
93 | }, {
94 | xtype: 'grid',
95 | region: 'south',
96 | reference: 'southGrid',
97 | split: true,
98 | idProperty: 'cartodb_id',
99 | bind: {
100 | store: '{refineries}',
101 | selection: '{selectedValue}'
102 | },
103 | listeners: {
104 | select: 'onSelect'
105 | },
106 | height: 350,
107 | columns: [{
108 | text: 'Site Name',
109 | dataIndex: 'site_name',
110 | flex: 1
111 | },{
112 | text: 'Company',
113 | dataIndex: 'company',
114 | flex: 1
115 | },{
116 | text: 'State',
117 | dataIndex: 'state',
118 | flex: 1
119 | },{
120 | text: 'Total Operation',
121 | dataIndex: 'total_oper',
122 | flex: 1
123 | }]
124 | }]
125 | }]
126 | });
127 | });
--------------------------------------------------------------------------------
/examples/tornados/tornado-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Tornado demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/examples/tornados/tornado-example.js:
--------------------------------------------------------------------------------
1 | Ext.Loader.setConfig({enabled: true, disableCaching: true});
2 | //Ext.Loader.setPath('Carto', '../../src/');
3 |
4 | Ext.require([
5 | // 'BarChart'
6 | ]);
7 |
8 | Ext.onReady(function () {
9 | // Ext.QuickTips.init();
10 |
11 | Ext.create('Ext.data.Store', {
12 | storeId: 'tornadosStore',
13 | remoteFilter: true,
14 | remoteSort: true,
15 | // sorters: 'city',
16 | sorters: [{
17 | property: 'st',
18 | direction: 'ASC'
19 | }],
20 | proxy: {
21 | type: 'carto',
22 | username: 'extjscarto',
23 | table: 'tornados'
24 | },
25 | autoLoad: true
26 | });
27 |
28 |
29 | // Ext.define('RoadExplorer.store.RoadData', {
30 | // extend: 'Ext.data.Store',
31 | //
32 | // alias: 'store.roadData',
33 | //
34 | // fields: ['name', 'value'],
35 | // data: [{
36 | // name: 'Mon',
37 | // value: 39
38 | // }, {
39 | // name: 'Tues',
40 | // value: 22
41 | // }, {
42 | // name: 'Weds',
43 | // value: 14
44 | // }, {
45 | // name: 'Thurs',
46 | // value: 10
47 | // }, {
48 | // name: 'Fri',
49 | // value: 30
50 | // }, {
51 | // name: 'Sat',
52 | // value: 6
53 | // }, {
54 | // name: 'Sun',
55 | // value: 2
56 | // }],
57 | //
58 | // proxy: {
59 | // type: 'memory',
60 | // reader: {
61 | // type: 'json'
62 | // }
63 | // }
64 | // });
65 |
66 | Ext.define('RoadExplorer.view.graph.BarChart', {
67 | extend: 'Ext.chart.CartesianChart',
68 | xtype: 'barChart',
69 | label: {
70 | display: 'insideStart',
71 | orientation: 'vertical'
72 | },
73 | axes: [{
74 | type: 'numeric',
75 | position: 'top',
76 | fields: 'mag'
77 | // fields: 'value'
78 | }, {
79 | type: 'category',
80 | position: 'left',
81 | fields: 'st'
82 | // fields: 'name'
83 | }],
84 | series: {
85 | type: 'bar',
86 | subStyle: {
87 | fill: ['#C8DCF1'],
88 | stroke: '#5CA6DB'
89 | },
90 | xField: 'st',
91 | yField: 'mag',
92 | // xField: 'name',
93 | // yField: 'value',
94 | tooltip: {
95 | trackMouse: true,
96 | renderer: function (tooltip, record, item) {
97 | // tooltip.setHtml(item.record.get('name') + ': ' + item.record.get('value'));
98 | }
99 | }
100 | }
101 | });
102 |
103 | Ext.create('Ext.container.Viewport', {
104 | layout: 'border',
105 | frame: true,
106 | bodyBorder: true,
107 | defaults: {
108 | collapsible: false,
109 | split: true,
110 | // bodyPadding: 10
111 | },
112 | items: [{
113 | title: 'United States - Tornados',
114 | region: 'center',
115 | // html: 'This is CenterPanel',
116 | headerPosition: 'top',
117 | xtype: 'barChart',
118 | // title: 'Crashes by Day of Week',
119 | flipXY: true,
120 | // store: {
121 | // type: 'roadData'
122 | // }
123 | store: Ext.data.StoreManager.lookup('tornadosStore')
124 | },{
125 | title: 'East Panel',
126 | region: 'east',
127 | html: 'This is EastPanel',
128 | headerPosition: 'left',
129 | width: 400
130 | }]
131 | });
132 |
133 | });
--------------------------------------------------------------------------------
/licenses/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/licenses
2 |
3 | This folder contains the supported licenses for third-party use.
4 |
--------------------------------------------------------------------------------
/modern/Readme.md:
--------------------------------------------------------------------------------
1 | This modern-specific directory can include any (if not all) of the following directories:
2 |
3 | * overrides: Any classes in this directory will be automatically required and included in the modern build.
4 | In case any of these classes define an Ext JS override (using Ext.define with an "override" property),
5 | that override will in fact only be included in the build if the target class specified
6 | in the "override" property is also included.
7 |
8 | - sass: Any modern-specific style rules should reside in this package, following the same structure
9 | as the directory in the package root (see package.json for more information).
10 |
11 | - src: The modern-specific classes of this package should reside in this directory.
--------------------------------------------------------------------------------
/overrides/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/overrides
2 |
3 | This folder contains overrides which will automatically be required by package users.
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | * The name of the package.
4 | */
5 | "name": "carto",
6 |
7 | /**
8 | * Alternate names for this package.
9 | *
10 | * "alternateName": [],
11 | */
12 |
13 | /**
14 | * The namespace of this package.
15 | *
16 | * As a general rule, all classes that belong to this package should be under this namespace
17 | * if multiple namespaces are part of this package, set this to "".
18 | */
19 | "namespace": "carto",
20 |
21 | /**
22 | * The package type.
23 | *
24 | * Sencha Cmd understands the following types of packages:
25 | * - code : An arbitrary package of code for use by applications or other packages.
26 | * - theme : A package to be used as an application’s theme.
27 | * - locale : A package containing localization strings or locale-specific code.
28 | * - template : A package containing one or more templates.
29 | */
30 | "type": "code",
31 |
32 | /**
33 | * The toolkit used by this theme (only for "theme" package type).
34 | *
35 | * Themes can specify the toolkit they apply to ("classic" or "modern").
36 | *
37 | * "toolkit": "classic",
38 | */
39 | "toolkit": "classic",
40 |
41 | /**
42 | * The author of the package.
43 | *
44 | * Required only if you are distributing this package through a Sencha Cmd repository,
45 | * in which case it should match the name you assign to your local package repository.
46 | */
47 | "creator": "anonymous",
48 |
49 | /**
50 | * A summarized description of this package.
51 | */
52 | "summary": "Short summary",
53 |
54 | /**
55 | * A detailed description of this package.
56 | */
57 | "detailedDescription": "Long description of package",
58 |
59 | /**
60 | * The package version.
61 | *
62 | * Typically, changes to the package should come along with changes to the version.
63 | * This number should be in this format: d+(.d+)*
64 | */
65 | "version": "1.0.0",
66 |
67 | /**
68 | * The version that users can transparently update from without requiring code changes.
69 | *
70 | * In addition the version property, packages can also indicate the degree to which
71 | * they are backward compatible using the compatVersion property.
72 | */
73 | "compatVersion": "1.0.0",
74 |
75 | /**
76 | * Spec. version of this package.json file.
77 | * This is set automatically by Sencha Cmd when first generating this file
78 | */
79 | "format": "1",
80 |
81 | /**
82 | * Additional resources used during theme slicing operations
83 | */
84 | "slicer": {
85 | "js": [
86 | {
87 | "path": "${package.dir}/sass/example/custom.js",
88 | "isWidgetManifest": true
89 | }
90 | ]
91 | },
92 |
93 | /**
94 | * Controls the output directory.
95 | */
96 | "output": "${package.dir}/build",
97 |
98 | /**
99 | * Indicates whether this is a locally developed package or downloaded form a repository.
100 | * Defaults to true on newly generated packages, should not be changed.
101 | */
102 | "local": true,
103 |
104 | /**
105 | * The theme (package) this package will use (e.g., "ext-theme-neptune", etc.).
106 | * This is only needed if the built package will be used by a non-Cmd application.
107 | *
108 | * "theme": "ext-theme-classic",
109 | */
110 |
111 | /**
112 | * Sass configuration properties.
113 | */
114 | "sass" : {
115 | /**
116 | * The namespace to which this package's SASS corresponds. The default value of
117 | * "carto" means that the files in ./sass/src (and ./sass/var) match classes in
118 | * the carto" root namespace. In other words, "carto.panel.Panel" maps to
119 | * ./sass/src/panel/Panel.scss.
120 | *
121 | * To style classes from any namespace, set this to blank. If this is blank,
122 | * then to style "carto.panel.Panel" you would put SASS in
123 | * ./sass/src/carto/panel/Panel.scss.
124 | */
125 | "namespace": "carto",
126 |
127 | /**
128 | * Comma-separated list of files or folders containing extra Sass. These
129 | * files are automatically included in the Sass compilation. By default this
130 | * is just "etc/all.scss" to allow import directives to control the order
131 | * other files are included.
132 | *
133 | * All "etc" files are included at the top of the Sass compilation in their
134 | * dependency order:
135 | *
136 | * +-------+---------+
137 | * | | base |
138 | * | theme +---------+
139 | * | | derived |
140 | * +-------+---------+
141 | * | packages | (in package dependency order)
142 | * +-----------------+
143 | * | application |
144 | * +-----------------+
145 | */
146 | "etc": [
147 | "${package.dir}/sass/etc/all.scss"
148 | ],
149 |
150 | /**
151 | * Comma-separated list of folders containing Sass variable definitions
152 | * files. These file can also define Sass mixins for use by components.
153 | *
154 | * All "var" files are included after "etc" files in the Sass compilation in
155 | * dependency order:
156 | *
157 | * +-------+---------+
158 | * | | base |
159 | * | theme +---------+
160 | * | | derived |
161 | * +-------+---------+
162 | * | packages | (in package dependency order)
163 | * +-----------------+
164 | * | application |
165 | * +-----------------+
166 | *
167 | * The "sass/var/all.scss" file is always included at the start of the var
168 | * block before any files associated with JavaScript classes.
169 | */
170 | "var": [
171 | "${package.dir}/sass/var"
172 | ],
173 |
174 | /**
175 | * Comma-separated list of folders containing Sass rule files.
176 | *
177 | * All "src" files are included after "var" files in the Sass compilation in
178 | * dependency order (the same order as "etc"):
179 | *
180 | * +-------+---------+
181 | * | | base |
182 | * | theme +---------+
183 | * | | derived |
184 | * +-------+---------+
185 | * | packages | (in package dependency order)
186 | * +-----------------+
187 | * | application |
188 | * +-----------------+
189 | */
190 | "src": [
191 | "${package.dir}/sass/src"
192 | ]
193 | },
194 |
195 | /**
196 | * This is the comma-separated list of folders where classes reside. These
197 | * classes must be explicitly required to be included in the build.
198 | */
199 | "classpath": [
200 | "${package.dir}/src"
201 | ],
202 |
203 | /**
204 | * Comma-separated string with the paths of directories or files to search. Any classes
205 | * declared in these locations will be automatically required and included in the build.
206 | * If any file defines an Ext JS override (using Ext.define with an "override" property),
207 | * that override will in fact only be included in the build if the target class specified
208 | * in the "override" property is also included.
209 | */
210 | "overrides": [
211 | "${package.dir}/overrides"
212 | ],
213 |
214 | "example": {
215 | /**
216 | * One or more folders that contain example applications for this package.
217 | */
218 | "path": [
219 | "${package.dir}/examples"
220 | ]
221 |
222 | /**
223 | * You can list apps specifically.
224 | *
225 | * "apps": [
226 | * "demo1",
227 | * "demo2"
228 | * ]
229 | *
230 | * By default, all subfolders in the path are considered example applications.
231 | */
232 | },
233 |
234 | /**
235 | * The framework this package will use (i.e., "ext" or "touch").
236 | * This is only needed if the built package will be used by a non-Cmd application.
237 | *
238 | * "framework": "ext",
239 | */
240 |
241 | /**
242 | * Packages can require other packages in the same way that applications can require
243 | * packages.
244 | *
245 | * Can be specified as an array of package names or configuration objects.
246 | *
247 | * "requires": [
248 | * "foo",
249 | * "bar@1.1-2.0",
250 | * {
251 | * "name": "baz"
252 | * "version": "1.5"
253 | * }
254 | * ]
255 | *
256 | * Can also be specified as an object:
257 | *
258 | * "requires": {
259 | * "foo": "2.2",
260 | * "bar": {
261 | * "minVersion": "1.1",
262 | * "version": "2.0"
263 | * }
264 | * }
265 | */
266 | "requires": []
267 | }
268 |
--------------------------------------------------------------------------------
/resources/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/resources
2 |
3 | This folder contains static resources (typically an `"images"` folder as well).
4 |
--------------------------------------------------------------------------------
/sass/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/sass
2 |
3 | This folder contains SASS files of various kinds, organized in sub-folders:
4 |
5 | carto/sass/etc
6 | carto/sass/src
7 | carto/sass/var
8 |
--------------------------------------------------------------------------------
/sass/config.rb:
--------------------------------------------------------------------------------
1 | cur_dir = File.dirname(__FILE__)
2 | output_style = :nested
3 |
--------------------------------------------------------------------------------
/sass/etc/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/sass/etc
2 |
3 | This folder contains miscellaneous SASS files. Unlike `"carto/sass/etc"`, these files
4 | need to be used explicitly.
5 |
--------------------------------------------------------------------------------
/sass/example/custom.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is generated as a starting point by Sencha Cmd - it will not be replaced or
3 | * updated by "sencha package upgrade".
4 | *
5 | * This file can be removed and the script tag in theme.html removed if this theme does
6 | * not need custom additional manifest or shortcut entries. These are documented in
7 | * ./packages/ext-theme-base/sass/example/render.js.
8 | */
9 |
10 | //Ext.theme.addManifest();
11 |
12 | //Ext.theme.addShortcuts();
13 |
--------------------------------------------------------------------------------
/sass/example/fashion.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Ext JS Theme Harness
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/sass/example/theme.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Ext JS Theme Harness
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/sass/src/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/sass/src
2 |
3 | This folder contains SASS sources that mimic the component-class hierarchy. These files
4 | are gathered in to a build of the CSS based on classes that are used by the build.
5 |
--------------------------------------------------------------------------------
/sass/var/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/sass/var
2 |
3 | This folder contains variable declaration files named by their component class.
4 |
--------------------------------------------------------------------------------
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CrestoneDigital/extjs-carto/a67036b54c48717290eb6cfc996cd37644cdc46f/src/.DS_Store
--------------------------------------------------------------------------------
/src/AbstractLayer.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.AbstractLayer', {
2 |
3 | mixins: [
4 | 'Ext.mixin.Inheritable',
5 | 'Ext.mixin.Observable',
6 | 'Ext.mixin.Bindable'
7 | ],
8 |
9 | config: {
10 | cartoLayer: null,
11 | hidden: false,
12 | table: '',
13 | username: '',
14 | mapZIndex: null
15 | },
16 |
17 | isAbstractLayer: true,
18 |
19 | constructor: function(config) {
20 | config = config || {};
21 |
22 | if (config.initialConfig) {
23 | config = config.initialConfig;
24 | }
25 |
26 | this.initialConfig = config;
27 |
28 | if (config.layerId) {
29 | this.setId(config.layerId);
30 | }
31 |
32 | this.getId();
33 | this.initConfig(config);
34 |
35 | this.initBindable();
36 |
37 | delete this.layerId;
38 | return this;
39 | },
40 |
41 | beforeInitConfig: function() {
42 | this.mixins.observable.constructor.call(this);
43 | },
44 |
45 | createCartoLayer: Ext.emptyFn,
46 |
47 | buildCartoLayer: Ext.emptyFn,
48 |
49 | updateCartoLayer: function(cartoLayer) {
50 | if (this.getHidden()) {
51 | cartoLayer.hide();
52 | }
53 | },
54 |
55 | updateHidden: function(hidden) {
56 | var cartoLayer = this.getCartoLayer();
57 | if (cartoLayer) {
58 | if (hide) {
59 | cartoLayer.hide();
60 | } else {
61 | cartoLayer.show();
62 | }
63 | }
64 | },
65 |
66 | getType: function() {
67 | var alias = this.alias;
68 | return alias ? alias[0].split('.')[1] : null;
69 | },
70 |
71 | remove: function(destroy) {
72 | var cartoLayer = this.getCartoLayer();
73 | if (cartoLayer) {
74 | cartoLayer.remove();
75 | }
76 | if (destroy) {
77 | this.destroy();
78 | }
79 | },
80 |
81 | initInheritedState: function(inheritedState) {
82 | this.mixins.bindable.initInheritedState.call(this, inheritedState);
83 | },
84 |
85 | doDestroy: Ext.emptyFn,
86 |
87 | destroy: function() {
88 | if (!this.hasListeners.beforedestroy || this.fireEvent('beforedestroy', this) !== false) {
89 | // isDestroying added for compat reasons
90 | this.isDestroying = this.destroying = true;
91 |
92 | this.doDestroy();
93 |
94 | this.removeBindings();
95 |
96 | this.destroyBindable();
97 |
98 | // We need to defer clearing listeners until after doDestroy() completes,
99 | // to let the interested parties fire events until the very end.
100 | this.clearListeners();
101 |
102 | // isDestroying added for compat reasons
103 | this.isDestroying = this.destroying = false;
104 |
105 | this.callParent(); // Ext.Base
106 | }
107 | }
108 | });
--------------------------------------------------------------------------------
/src/CartoBasemaps.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.CartoBasemaps',{
2 |
3 | basemaps: [{
4 | itemId: 'positronLite',
5 | name: 'Positron (lite)',
6 | url: 'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png',
7 | attribution: '© OpenStreetMap contributors, © CartoDB '
8 | },{
9 | itemId: 'positron',
10 | name: 'Positron',
11 | url: 'https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png',
12 | attribution: '© OpenStreetMap contributors, © CartoDB '
13 | },{
14 | itemId: 'positronLabelsBelow',
15 | name: 'Positron (labels below)',
16 | url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
17 | attribution: '© OpenStreetMap contributors, © CartoDB '
18 | }, {
19 | itemId: 'darkMatterLabelsBelow',
20 | name: 'Dark Matter (labels below)',
21 | url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
22 | attribution: '© OpenStreetMap contributors, © CartoDB '
23 | }, {
24 | itemId: 'darkMatter',
25 | name: 'Dark Matter',
26 | url: 'https://{s}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}.png',
27 | attribution: '© OpenStreetMap contributors, © CartoDB '
28 | }, {
29 | itemId: 'darkMatterLite',
30 | name: 'Dark Matter (lite)',
31 | url: 'https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png',
32 | attribution: '© OpenStreetMap contributors, © CartoDB '
33 | }, {
34 | itemId: 'cartoWorldEco',
35 | name: 'CARTO World Eco',
36 | url: 'https://cartocdn_{s}.global.ssl.fastly.net/base-eco/{z}/{x}/{y}.png',
37 | attribution: '© OpenStreetMap contributors, © CartoDB '
38 | }, {
39 | itemId: 'cartoWorldFlatBlue',
40 | name: 'CARTO World Flat Blue',
41 | url: 'https://cartocdn_{s}.global.ssl.fastly.net/base-flatblue/{z}/{x}/{y}.png',
42 | attribution: '© OpenStreetMap contributors, © CartoDB '
43 | }, {
44 | itemId: 'cartoWorldMidnightCommander',
45 | name: 'CARTO World Midnight Commander',
46 | url: 'https://cartocdn_{s}.global.ssl.fastly.net/base-midnight/{z}/{x}/{y}.png',
47 | attribution: '© OpenStreetMap contributors, © CartoDB '
48 | }, {
49 | itemId: 'cartoAntique',
50 | name: 'CARTO Antique',
51 | url: 'https://cartocdn_{s}.global.ssl.fastly.net/base-antique/{z}/{x}/{y}.png',
52 | attribution: '© OpenStreetMap contributors, © CartoDB '
53 | /* New basemaps */
54 | },{
55 | itemId: 'toner',
56 | name: 'Toner',
57 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-labels/{z}/{x}/{y}.png',
58 | attribution: '© OpenStreetMap contributors, © CartoDB '
59 | }, {
60 | itemId: 'tonerLabelsBelow',
61 | name: 'Toner (labels below)',
62 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png',
63 | attribution: '© OpenStreetMap contributors, © CartoDB '
64 | }, {
65 | itemId: 'tonerBackground',
66 | name: 'Toner Background',
67 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-background/{z}/{x}/{y}.png',
68 | attribution: '© OpenStreetMap contributors, © CartoDB '
69 | }, {
70 | itemId: 'tonerLite',
71 | name: 'Toner Lite',
72 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png',
73 | attribution: '© OpenStreetMap contributors, © CartoDB '
74 | }, {
75 | itemId: 'tonerLines',
76 | name: 'Toner Lines',
77 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lines/{z}/{x}/{y}.png',
78 | attribution: '© OpenStreetMap contributors, © CartoDB '
79 | }, {
80 | itemId: 'tonerHybrid',
81 | name: 'Toner Hybrid',
82 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-hybrid/{z}/{x}/{y}.png',
83 | attribution: '© OpenStreetMap contributors, © CartoDB '
84 | }, {
85 | itemId: 'watercolor',
86 | name: 'Watercolor',
87 | url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png',
88 | attribution: '© OpenStreetMap contributors, © CartoDB '
89 | }],
90 | getBasemapById: function(itemId){
91 | var basemap = null;
92 | this.basemaps.forEach(function(item){
93 | if(item.itemId === itemId){
94 | basemap = item;
95 | }
96 | }.bind(this));
97 | if (basemap) {
98 | return basemap;
99 | } else {
100 | console.error("Unknown basemap '" + itemId + "'.");
101 | }
102 | }
103 |
104 |
105 | });
--------------------------------------------------------------------------------
/src/CartoDataModel.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.CartoDataModel', {
2 | extend: 'Ext.data.Model',
3 | idProperty: 'cartodb_id',
4 | fields: [
5 | 'site_name', 'company', 'state', 'total_oper', 'cartodb_id'
6 | // 'corporatio', 'created_at',
7 | // 'dataperiod', 'source', 'the_geom', 'the_geom_webmercator', 'updated_at'
8 | ]
9 | });
--------------------------------------------------------------------------------
/src/CartoFilter.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.CartoFilter', {
2 | extend: 'Ext.util.Filter',
3 |
4 | config: {
5 | sql: '',
6 | negate: false
7 | },
8 |
9 | initConfig: function(config) {
10 | this.callParent(arguments);
11 | if (!this.getSql() && !this.getFilterFn()) {
12 | this.createSql();
13 | }
14 | },
15 |
16 | createSql: function() {
17 | var me = this,
18 | property = me.getProperty(),
19 | value = me.getValue(),
20 | operator = me.getOperator() || '=',
21 | negate = me.getNegate(),
22 | caseSensitive = me.caseSensitive;
23 |
24 | if (property && value) {
25 | if (value instanceof RegExp) {
26 | operator = '~';
27 | value = value.toString().slice(1);
28 | while (!value.endsWith('/')) {
29 | if (value.slice(-1) === 'i') {
30 | caseSensitive = false;
31 | }
32 | value = value.slice(0,-1);
33 | }
34 | if (!caseSensitive) {
35 | operator += '*';
36 | }
37 | value = value.slice(0,-1);
38 | } else {
39 | switch(operator) {
40 | case 'like':
41 | case '<':
42 | case '<=':
43 | case '>':
44 | case '>=':
45 | case '=':
46 | case '!=':
47 | break;
48 | case 'lt':
49 | operator = '<';
50 | break;
51 | case 'lte':
52 | operator = '<=';
53 | break;
54 | case 'gt':
55 | operator = '>';
56 | break;
57 | case 'gte':
58 | operator = '>=';
59 | break;
60 | case 'eq':
61 | operator = '='
62 | break;
63 | case 'in':
64 | if(Ext.isArray(value)) {
65 | var temp = value.slice();
66 | for (var i = 0; i < temp.length; i++) temp[i] = this.wrap(temp[i]);
67 | property = 'ARRAY[' + property + ']';
68 | operator = '<@';
69 | value = 'ARRAY[' + temp + ']';
70 | }
71 | break;
72 | case 'regex':
73 | var validRegExp = true;
74 | try {
75 | new RegExp(value);
76 | } catch (e) {
77 | validRegExp = false;
78 | }
79 | if (validRegExp) {
80 | operator = caseSensitive ? '~' : '~*';
81 | } else {
82 | console.error("Invalid Regular Expression '" + value + "'. Skipping.");
83 | return;
84 | }
85 | break;
86 | default:
87 | console.warn("Unknown operator '" + operator + "'.");
88 | }
89 | }
90 | return (negate ? 'NOT ' : '') + property + operator + me.wrap(value);
91 | }
92 | }
93 | });
--------------------------------------------------------------------------------
/src/CartoGroupBy.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.CartoGroupBy', {
2 | isGroupBy: true,
3 |
4 | config: {
5 | fields: null,
6 | countName: 'cnt'
7 | },
8 |
9 | constructor: function(config) {
10 | this.initConfig(config);
11 | },
12 |
13 | initConfig: function(config) {
14 | this.decodeGroupBy(config);
15 | this.callParent();
16 | },
17 |
18 | /**
19 | * Adds a field to the `fields` config.
20 | * @param {Object} field
21 | */
22 | addField: function(field) {
23 | var fields = this.getFields(),
24 | alreadyExists = false;
25 | field = this.decodeField(field);
26 | for (var i in fields) {
27 | if (fields[i].name === field.name) {
28 | alreadyExists = true;
29 | fields[i] = field;
30 | }
31 | }
32 | if (!alreadyExists) {
33 | fields.push(field);
34 | }
35 | this.setFields(fields);
36 | },
37 |
38 | /**
39 | * Returns the comma-separated field's sql to be inserted in the SELECT statement.
40 | */
41 | getSelectSql: function() {
42 | return Ext.pluck(this.getFields(), 'sql').join(',');;
43 | },
44 |
45 | /**
46 | * Returns the comma-separated field's sql to be inserted in the GROUP BY statement.'
47 | */
48 | getGroupBySql: function() {
49 | var sql = '',
50 | fields = this.getFields();
51 | for (var i in fields) {
52 | sql += fields[i].aggregateType ? '' : fields[i].name + ',';
53 | }
54 | return sql.slice(0,-1);
55 | },
56 |
57 | /**
58 | * Creates this from the given config.
59 | * @param {String/String[]/Object/Object[]} groupBy
60 | */
61 | decodeGroupBy: function(groupBy) {
62 | if (!groupBy.fields) {
63 | groupBy = {fields: groupBy};
64 | }
65 | var fields = Ext.isArray(groupBy.fields) ? groupBy.fields : [groupBy.fields],
66 | field;
67 | for (var i = 0; i < fields.length; i++) {
68 | fields[i] = this.decodeField(fields[i]);
69 | }
70 | this.setFields(fields);
71 | if (groupBy.countName) {
72 | this.setCountName(groupBy.countName);
73 | }
74 | },
75 |
76 | /**
77 | * Creates the {@link Ext.data.field.Field} from the given config.
78 | * @param {String/Object/Ext.data.field.Field} field
79 | */
80 | decodeField: function(field) {
81 | if (!field.isField) {
82 | field = new Ext.data.field.Field(field);
83 | }
84 | if (!field.sql) {
85 | field.sql = this.wrapAggregate(field) + (field.property ? ' AS ' + field.name : '');
86 | }
87 | return field;
88 | },
89 |
90 | wrapAggregate: function(field) {
91 | if (field.aggregateType) {
92 | field.aggregateType = field.aggregateType.toUpperCase();
93 | if (this.allowedAggregateTypes.indexOf(field.aggregateType) === -1) {
94 | console.warn("Unknown aggregate type '" + field.aggregateType + "'. Skipping.");
95 | field.aggregateType = null;
96 | } else {
97 | return field.aggregateType + '(' + (field.property || field.name) + ')';
98 | }
99 | }
100 | return field.property || field.name;
101 | },
102 |
103 | allowedAggregateTypes: ['AVG', 'SUM', 'COUNT', 'MIN', 'MAX', 'STDDEV']
104 | });
--------------------------------------------------------------------------------
/src/CartoProxy.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.CartoProxy', {
2 | extend: 'Ext.data.proxy.Ajax',
3 | alias: 'proxy.carto',
4 |
5 | requires: [
6 | 'Carto.sql.CartoField',
7 | 'Carto.sql.CartoFrom',
8 | 'Carto.sql.CartoSql',
9 | 'Carto.sql.CartoTable',
10 | // 'Carto.util.SubLayerCollection'
11 | ],
12 | mixins: [
13 | 'Carto.CartoSqlMixin'
14 | ],
15 | alternateClassName: ['Carto.CartoProxy.CartoAjax'],
16 |
17 | reader: {
18 | type: 'json',
19 | rootProperty: 'rows',
20 | totalProperty: 'total_rows'
21 | },
22 |
23 | config: {
24 | url: "https://{{account}}.carto.com/api/v2/sql",
25 | apiKey: null,
26 | table: '',
27 | select: '',
28 | join: [],
29 | where: {},
30 | groupBy: null,
31 | orderBy: '',
32 | username: '',
33 | mode: null,
34 | sqlCacheBuster: false,
35 | enableData: true,
36 | enableBounds: false,
37 | enableLatLng: false,
38 | limit: null,
39 | layers: null
40 | },
41 |
42 | /**
43 | * @private
44 | * Copy any sorters, filters etc into the params so they can be sent over the wire
45 | */
46 | getParams: function(operation) {
47 | if (!operation.isReadOperation) {
48 | return {};
49 | }
50 |
51 | var me = this,
52 | params = {},
53 | grouper = operation.getGrouper(),
54 | sorters = operation.getSorters(),
55 | filters = operation.getFilters(),
56 | page = operation.getPage(),
57 | start = operation.getStart(),
58 | limit = operation.getLimit(),
59 | simpleSortMode = me.getSimpleSortMode(),
60 | simpleGroupMode = me.getSimpleGroupMode(),
61 | pageParam = me.getPageParam(),
62 | startParam = me.getStartParam(),
63 | limitParam = me.getLimitParam(),
64 | groupParam = me.getGroupParam(),
65 | groupDirectionParam = me.getGroupDirectionParam(),
66 | sortParam = me.getSortParam(),
67 | filterParam = me.getFilterParam(),
68 | directionParam = me.getDirectionParam(),
69 | hasGroups, index;
70 |
71 | if (pageParam && page) {
72 | params[pageParam] = page;
73 | }
74 |
75 | if (startParam && (start || start === 0)) {
76 | params[startParam] = start;
77 | }
78 |
79 | if (limitParam && limit) {
80 | params[limitParam] = limit;
81 | }
82 |
83 | hasGroups = groupParam && grouper;
84 | if (hasGroups) {
85 | // Grouper is a subclass of sorter, so we can just use the sorter method
86 | if (simpleGroupMode) {
87 | params[groupParam] = grouper.getProperty();
88 | params[groupDirectionParam] = grouper.getDirection();
89 | } else {
90 | params[groupParam] = me.encodeSorters([grouper], true);
91 | }
92 | }
93 |
94 | if (sortParam && sorters && sorters.length > 0) {
95 | if (simpleSortMode) {
96 | index = 0;
97 | // Group will be included in sorters, so grab the next one
98 | if (sorters.length > 1 && hasGroups) {
99 | index = 1;
100 | }
101 | params[sortParam] = sorters[index].getProperty();
102 | params[directionParam] = sorters[index].getDirection();
103 | } else {
104 | params[sortParam] = me.encodeSorters(sorters);
105 | }
106 |
107 | }
108 |
109 | if (filterParam && filters && filters.length > 0) {
110 | // We do not want to send the filters as a parameter, as they will be added into the query
111 | params.filter = filters;
112 | }
113 |
114 | return params;
115 | },
116 |
117 | joinTable: function(joinTable) {
118 | if (!joinTable.table.isCartoTable) {
119 | joinTable.table = Ext.create('Carto.sql.CartoTable', joinTable.table);
120 | }
121 | this.getJoin().push(joinTable);
122 | },
123 |
124 | removeJoin: function(joinName) {
125 | var join = this.getJoin(),
126 | j;
127 | for (var i in join) {
128 | j = join[i];
129 | if (j.table.getId() === joinName) {
130 | delete join.splice(i, 1);
131 | }
132 | }
133 | },
134 |
135 | /**
136 | * Adds a field to the proxy's {@link Carto.CartoGroupBy}. This will create a groupBy object if one does not exist.
137 | * @param {Ext.data.field.Field/Object} field
138 | */
139 | addGroupByField: function(field) {
140 | var groupBy = this.getGroupBy();
141 | if (!groupBy) {
142 | groupBy = Ext.create('Carto.CartoGroupBy', field);
143 | } else {
144 | groupBy.addField(field);
145 | }
146 | this.setGroupBy(groupBy);
147 | },
148 |
149 | addLayer: function(layer, load) {
150 | var table = this.getTable(),
151 | layers = this.getLayers();
152 | if (table) {
153 | layer.setTable(table.getId());
154 | }
155 | layer.setUsername(this.getUsername());
156 | this.setLayers(layer);
157 | if (load && this._cachedSql) {
158 | layer.setSql(this._cachedSql);
159 | }
160 | },
161 |
162 | setSql: function(sql) {
163 | this.sql = sql;
164 | },
165 |
166 | /**
167 | * Generates a url based on a given Ext.data.Request object. By default, ServerProxy's buildUrl will add the
168 | * cache-buster param to the end of the url. Subclasses may need to perform additional modifications to the url.
169 | * @param {Ext.data.Request} request The request object
170 | * @return {String} The url
171 | */
172 | buildUrl: function(request) {
173 | var url = this.getUrl();
174 | if (this.useCartoDb) {
175 | url = "https://{{account}}.cartodb.com/api/v2/sql";
176 | }
177 | url = url.replace(/{{account}}/, this.getUsername());
178 | if (this.getNoCache()) {
179 | url = Ext.urlAppend(url, Ext.String.format("{0}={1}", this.getCacheString(), Ext.Date.now()));
180 | }
181 | return url;
182 | },
183 |
184 | /**
185 | * Creates an {@link Ext.data.Request Request} object from {@link Ext.data.operation.Operation Operation}.
186 | *
187 | * This gets called from doRequest methods in subclasses of Server proxy.
188 | *
189 | * @param {Ext.data.operation.Operation} operation The operation to execute
190 | * @return {Ext.data.Request} The request object
191 | */
192 | buildRequest: function(operation) {
193 | var me = this,
194 | layers = this.getLayers(),
195 | sqlParams = Ext.apply(me.getParams(operation), this.getCurrentConfig()),
196 | request, operationId, idParam, sql;
197 | switch (this.getMode()) {
198 | case 'tables': sql = this.getTablesSql; break;
199 | case 'columns': sql = this.getColumnsSql.replace(/{{table_name}}/g, this.getTable().getId()); break;
200 | default: sql = this.sql ? this.sqlFormatter(this.sql, sqlParams) : this.sqlBuilder(sqlParams);
201 | }
202 | var params = {
203 | q: sql
204 | };
205 | if (this.getApiKey()) {
206 | params.api_key = this.getApiKey();
207 | }
208 | if (layers) {
209 | sql = this.sql ? sql : this.sqlBuilder(sqlParams, {isMap: true});
210 | if (sql !== me._cachedSql) {
211 | layers.each(function(layer) {
212 | layer.setSql(sql);
213 | });
214 | }
215 | }
216 | me._cachedSql = sql;
217 |
218 | // Set up the entity id parameter according to the configured name.
219 | // This defaults to "id". But TreeStore has a "nodeParam" configuration which
220 | // specifies the id parameter name of the node being loaded.
221 | operationId = operation.getId();
222 | idParam = me.getIdParam();
223 | if (operationId !== undefined && params[idParam] === undefined) {
224 | params[idParam] = operationId;
225 | }
226 | request = new Ext.data.Request({
227 | params: params,
228 | action: operation.getAction(),
229 | records: operation.getRecords(),
230 | url: operation.getUrl(),
231 | operation: operation,
232 | // this is needed by JsonSimlet in order to properly construct responses for
233 | // requests from this proxy
234 | proxy: me
235 | });
236 | request.setUrl(me.buildUrl(request));
237 | /*
238 | * Save the request on the Operation. Operations don't usually care about Request and Response data, but in the
239 | * ServerProxy and any of its subclasses we add both request and response as they may be useful for further processing
240 | */
241 | operation.setRequest(request);
242 | return request;
243 | },
244 |
245 | doRequest: function(operation) {
246 | var me = this,
247 | writer = me.getWriter(),
248 | request = me.buildRequest(operation),
249 | method = me.getMethod(request),
250 | jsonData, params;
251 |
252 | // EDIT
253 | // If the onlyTiles flag is enabled, then buildRequest has done all the work we needed done.
254 | if (operation.onlyTiles) {
255 | return null;
256 | }
257 | // END EDIT
258 |
259 | if (writer && operation.allowWrite()) {
260 | request = writer.write(request);
261 | }
262 |
263 | request.setConfig({
264 | binary : me.getBinary(),
265 | headers : me.getHeaders(),
266 | timeout : me.getTimeout(),
267 | scope : me,
268 | callback : me.createRequestCallback(request, operation),
269 | method : method,
270 | useDefaultXhrHeader : me.getUseDefaultXhrHeader(),
271 | disableCaching : false // explicitly set it to false, ServerProxy handles caching
272 | });
273 |
274 | if (method.toUpperCase() !== 'GET' && me.getParamsAsJson()) {
275 | params = request.getParams();
276 |
277 | if (params) {
278 | jsonData = request.getJsonData();
279 | if (jsonData) {
280 | jsonData = Ext.Object.merge({}, jsonData, params);
281 | } else {
282 | jsonData = params;
283 | }
284 | request.setJsonData(jsonData);
285 | request.setParams(undefined);
286 | }
287 | }
288 |
289 | if (me.getWithCredentials()) {
290 | request.setWithCredentials(true);
291 | request.setUsername(me.getUsername());
292 | request.setPassword(me.getPassword());
293 | }
294 | return me.sendRequest(request);
295 | },
296 |
297 | applyLayers: function(layers, layerCollection) {
298 | if (!layerCollection) {
299 | layerCollection = Ext.create('Carto.util.LayerCollection');
300 | }
301 | layerCollection.add(layers);
302 | return layerCollection;
303 | },
304 |
305 | updateUsername: function(username) {
306 | var layers = this.getLayers();
307 | if (layers) {
308 | layers.each(function(layer) {
309 | layer.setUsername(username);
310 | }.bind(this));
311 | }
312 | },
313 |
314 | applyTable: function(table) {
315 | if (table && !table.isCartoTable) {
316 | table = Ext.create('Carto.sql.CartoTable', table);
317 | }
318 | return table;
319 | },
320 |
321 | updateTable: function(table) {
322 | var layers = this.getLayers();
323 | if (table && layers) {
324 | layers.each(function(layer) {
325 | layer.setTable(table.getId());
326 | });
327 | }
328 | }
329 |
330 | });
--------------------------------------------------------------------------------
/src/CartoStore.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.CartoStore',{
2 | extend: 'Ext.data.Store',
3 | alias: 'store.carto',
4 | requires: [
5 | 'Carto.CartoProxy'
6 | ],
7 |
8 | isCartoStore: true,
9 |
10 | // listeners: {
11 | // filterchange: function(store, filters) {
12 | // var storeConfig = this.getProxy().getCurrentConfig();
13 | // storeConfig.filter = [];
14 | // filters.forEach(function(item){
15 | // storeConfig.filter.push({
16 | // operator: (item._operator) ? item._operator : "like",
17 | // value: (item._convert) ? item._value.toLocaleDateString() :item._value,
18 | // property: item._property
19 | // });
20 | // }.bind(this));
21 | // // if(this._subLayer){
22 | // // this._subLayer.setSQL(this.sqlBuilder(storeConfig));
23 | // // }
24 | // if(this._layer){
25 | // this._layer.setSQL(this.sqlBuilder(storeConfig));
26 | // }
27 | // }
28 | // },
29 |
30 | constructor: function(config) {
31 | var table = config.table;
32 | if (table) {
33 | config.select = {
34 | tables: [table]
35 | };
36 | delete config.table;
37 | }
38 | this.callParent([config]);
39 | },
40 |
41 | applySelect: function(select) {
42 | if (select && !select.isCartoSelect) {
43 | select = Ext.create('Carto.sql.CartoSelect', select);
44 | }
45 | return select;
46 | },
47 |
48 | proxy: {
49 | type: 'carto'
50 | },
51 |
52 | remoteFilter: true,
53 | remoteSort: true,
54 |
55 | config: {
56 | groupBy: null,
57 | distinct: false,
58 | applyFilterToLayer: true,
59 | onlyTiles: false
60 | },
61 |
62 | // addSubLayerToProxy: function(subLayer) {
63 | // this.getProxy().addSubLayer(subLayer, this.autoLoad || this.isLoaded() || this.isLoading());
64 | // },
65 |
66 | addLayerToProxy: function(layer) {
67 | this.getProxy().addLayer(layer, this.autoLoad || this.isLoaded() || this.isLoading());
68 | },
69 |
70 | // getSubLayer: function() {
71 | // return this._subLayer;
72 | // },
73 |
74 | privates: {
75 | setLoadOptions: function(options) {
76 | var me = this,
77 | groupBy = me.getGroupBy(),
78 | onlyTiles = me.getOnlyTiles(),
79 | distinct = me.getDistinct();
80 | if (groupBy) {
81 | options.groupBy = groupBy;
82 | }
83 | if (onlyTiles) {
84 | options.onlyTiles = true;
85 | }
86 | me.callParent([options]);
87 | }
88 | }
89 | });
--------------------------------------------------------------------------------
/src/LayerManager.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.LayerManager', {
2 |
3 | // requires: [
4 | // 'Carto.CartoLayerBase',
5 | // 'Carto.CartoLayerContainer',
6 | // 'Carto.CartoSubLayer',
7 | // 'Carto.CartoLayer'
8 | // ],
9 |
10 | singleton: true,
11 |
12 | lookupLayer: function(layer, defaultType) {
13 | if (!layer.isLayer) {
14 | if (!layer.type && layer.hasOwnProperty('subLayers')) {
15 | layer.type = 'layergroup';
16 | }
17 | layer = Ext.Factory.layer(layer);
18 | }
19 | return layer;
20 | },
21 |
22 | lookupSubLayer: function(subLayer, defaultType) {
23 | if (!subLayer.isSubLayer) {
24 | if (!subLayer.type && defaultType) {
25 | subLayer.type = defaultType;
26 | }
27 | subLayer = Ext.Factory.sublayer(subLayer, defaultType);
28 | }
29 | return subLayer;
30 | },
31 |
32 | lookupCss: function(css) {
33 | if (!css) {
34 | return null;
35 | }
36 | if (Ext.isArray(css)) {
37 | css = css.join('');
38 | }
39 | if (typeof css !== 'string' && !css.isCartoCss) {
40 | if (!css.type) {
41 | css = {
42 | type: 'shell',
43 | value: css
44 | }
45 | }
46 | css = Ext.Factory.cartocss(css);
47 | }
48 | return css;
49 | }
50 | });
--------------------------------------------------------------------------------
/src/LeafletFunctionsMixin.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.LeafletFunctionsMixin', {
2 | /**
3 | * @param {integer} lat
4 | * @param {integer} lng
5 | * @param {integer} zoom
6 | */
7 | panTo: function(lat, lng, zoom) {
8 | this.getCartoMap().setView([lat,lng], zoom || 10);
9 | },
10 |
11 | /**
12 | * @param {} bounds
13 | * @param {} options
14 | */
15 | fitBounds: function(bounds, options) {
16 | this.getCartoMap().fitBounds(bounds, options);
17 | },
18 |
19 | setZoom: function(zoom, options) {
20 | this.getCartoMap().setZoom(zoom, options);
21 | },
22 |
23 | /**
24 | * @param {} num
25 | * @param {} options
26 | */
27 | zoomIn: function(num, options) {
28 | this.getCartoMap().zoomIn(num, options);
29 | },
30 |
31 | /**
32 | * @param {} num
33 | * @param {} options
34 | */
35 | zoomOut: function(num, options) {
36 | this.getCartoMap().zoomOut(num, options);
37 | },
38 |
39 | /**
40 | * @param {} latLngBounds
41 | */
42 | setMaxBounds: function(latLngBounds) {
43 | this.getCartoMap().setMaxBounds(latLngBounds);
44 | },
45 |
46 | /**
47 | */
48 | remove: function() {
49 | this.getCartoMap().remove();
50 | },
51 | /**
52 | */
53 | getCenter: function() {
54 | return this.getCartoMap().getCenter();
55 | },
56 | /**
57 | */
58 | getZoom: function() {
59 | return this.getCartoMap().getZoom();
60 | },
61 | /**
62 | */
63 | getMinZoom: function() {
64 | return this.getCartoMap().getMinZoom();
65 | },
66 | /**
67 | */
68 | getMaxZoom: function() {
69 | return this.getCartoMap().getMaxZoom();
70 | },
71 | /**
72 | */
73 | getBounds: function() {
74 | return this.getCartoMap().getBounds();
75 | },
76 | /**
77 | * @param {} latLngBounds
78 | * @param {} inside
79 | */
80 | getBoundsZoom: function(latLngBounds, inside) {
81 | return this.getCartoMap().getBoundsZoom(latLngBounds, inside);
82 | },
83 | /**
84 | */
85 | getSize: function() {
86 | return this.getCartoMap().getSize();
87 | },
88 | /**
89 | */
90 | getPixelBounds: function() {
91 | return this.getCartoMap().getPixelBounds();
92 | },
93 | /**
94 | */
95 | getPixelOrigin: function() {
96 | return this.getCartoMap().getPixelOrigin();
97 | }
98 |
99 |
100 | });
--------------------------------------------------------------------------------
/src/Readme.md:
--------------------------------------------------------------------------------
1 | # carto/src
2 |
3 | This folder contains source code that will automatically be added to the classpath when
4 | the package is used.
5 |
--------------------------------------------------------------------------------
/src/css/Css.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.Css', {
2 | alias: 'cartocss.shell',
3 |
4 | mixins: [
5 | 'Ext.mixin.Factoryable'
6 | ],
7 |
8 | factoryConfig: {
9 | type: 'cartocss',
10 | defaultType: 'shell'
11 | },
12 |
13 | config: {
14 | value: {}
15 | },
16 |
17 | isCartoCss: true,
18 |
19 | constructor: function(cfg) {
20 | this.initConfig(cfg);
21 | return this;
22 | },
23 |
24 | applyValue: function(newValue, oldValue) {
25 | if (oldValue) {
26 | newValue = Ext.apply(oldValue, newValue);
27 | }
28 | return newValue;
29 | },
30 |
31 | updateValue: function(value) {
32 | this.createCssString();
33 | },
34 |
35 | createCssString: function(obj) {
36 | var isCase = obj !== undefined,
37 | obj = isCase ? obj : this.getValue(),
38 | str = '',
39 | table, k, i;
40 |
41 | if (!obj) {
42 | return '';
43 | }
44 | if (obj.Map) {
45 | str += this.createTorqueString(obj.Map);
46 | }
47 | if (isCase) {
48 | str += '[' + obj.condition + ']{';
49 | } else {
50 | table = 'layer';
51 | str += '#' + table + '{';
52 | }
53 | for (k in obj) {
54 | if (k === 'case') {
55 | if (!Ext.isArray(obj[k])) {
56 | obj[k] = [obj[k]];
57 | }
58 | for (i in obj[k]) {
59 | str += this.createCssString(obj[k][i]);
60 | }
61 | } else if (k === 'condition' || k === 'Map') {
62 |
63 | } else {
64 | str += this.parseCss(k) + ':' + obj[k] + ';';
65 | }
66 | }
67 | str += '}';
68 | if (!isCase) {
69 | this.cssString = str;
70 | }
71 | return str;
72 | },
73 |
74 | createTorqueString: function(obj) {
75 | var str = '',
76 | k;
77 | if (obj) {
78 | str += 'Map{';
79 | for (k in obj) {
80 | str += this.parseCss(k, true) + ':' + obj[k] + ';';
81 | }
82 | str += '}';
83 | }
84 | return str;
85 | },
86 |
87 | set: function(attr, value, suppressed) {
88 | if (typeof attr === 'string') {
89 | if (value === undefined) {
90 | delete this.css[attr];
91 | } else {
92 | this.css[attr] = value;
93 | }
94 | } else {
95 | for (var k in attr) {
96 | this.set(k, attr[k], true);
97 | }
98 | suppressed = value;
99 | }
100 | if (!suppressed) {
101 | this.createCssString();
102 | }
103 | },
104 |
105 | addCase: function(caseObj) {
106 | var css = this.css;
107 | if (!css.case) {
108 | css.case = [];
109 | }
110 | css.case.push(caseObj);
111 | this.css = css;
112 | this.createCssString();
113 | },
114 |
115 | removeCase: function(condition) {
116 | var cssCase = this.css.case;
117 | if (cssCase) {
118 | for (var i = 0; i < cssCase.length; i++) {
119 | if (cssCase[i].condition === condition) {
120 | cssCase.splice(i, 1);
121 | this.createCssString();
122 | break;
123 | }
124 | }
125 | }
126 | },
127 |
128 | getCssString: function() {
129 | return this.cssString;
130 | },
131 |
132 | parseCss: function(str, prefix) {
133 | return (prefix ? '-' : '') + str.replace(this.cssRegex, this.replaceUppercase);
134 | },
135 |
136 | replaceUppercase: function(str) {
137 | return '-' + str.toLowerCase();
138 | },
139 |
140 | cssRegex: /[A-Z]/g
141 | });
--------------------------------------------------------------------------------
/src/css/HeatMap.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.HeatMap', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.heatmap',
4 |
5 | value: {
6 | Map: {
7 | torqueFrameCount: 1,
8 | torqueAnimationDuration: 10,
9 | torqueTimeAttribute: '"contrdated"',
10 | torqueAggregationFunction: '"count(cartodb_id)"',
11 | torqueResolution: 8,
12 | torqueDataAggregation: 'linear'
13 | },
14 |
15 | imageFilters: 'colorize-alpha(blue, cyan, lightgreen, yellow , orange, red)',
16 | markerFile: 'url(http://s3.amazonaws.com/com.cartodb.assets.static/alphamarker.png)',
17 | markerFillOpacity: '0.4*[value]',
18 | markerWidth: 35,
19 | case: [{
20 | condition: 'frame-offset=1',
21 | markerWidth: 37,
22 | markerFillOpacity: 0.2,
23 | }, {
24 | condition: 'frame-offset=2',
25 | markerWidth: 39,
26 | markerFillOpacity: 0.1
27 | }]
28 | }
29 | });
--------------------------------------------------------------------------------
/src/css/Intensity.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.Intensity', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.intensity',
4 |
5 | value: {
6 | markerFill: '#FFCC00',
7 | markerWidth: '10',
8 | markerLineColor: '#FFF',
9 | markerLineWidth: '1',
10 | markerLineOpacity: '1',
11 | markerFillOpacity: '0.9',
12 | markerCompOp: 'multiply',
13 | markerType: 'ellipse',
14 | markerPlacement: 'point',
15 | markerAllowOverlap: true,
16 | markerClip: false,
17 | markerMultiPolicy: 'largest'
18 | }
19 | });
--------------------------------------------------------------------------------
/src/css/Line.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.Line', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.line',
4 |
5 | value: {
6 | lineColor: '#FFF',
7 | lineWidth: '1',
8 | lineOpacity: '0.5',
9 | lineCompOp: 'soft-light'
10 | }
11 | });
--------------------------------------------------------------------------------
/src/css/Point.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.Point', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.point',
4 |
5 | value: {
6 | markerLineColor: '#FFF',
7 | markerLineWidth: '1.5',
8 | markerLineOpacity: '1',
9 | markerFillOpacity: '0.9',
10 | markerPlacement: 'point',
11 | markerType: 'ellipse',
12 | markerFill: '#FF6600',
13 | markerWidth: '10',
14 | markerAllowOverlap: true
15 | }
16 | });
--------------------------------------------------------------------------------
/src/css/Polygon.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.Polygon', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.polygon',
4 |
5 | value: {
6 | polygonFill: '#374C70',
7 | polygonOpacity: '0.9',
8 | polygonGamma: '0.5',
9 | lineColor: '#FFF',
10 | lineWidth: '1',
11 | lineOpacity: '0.5',
12 | lineCompOp: 'soft-light'
13 | }
14 | });
--------------------------------------------------------------------------------
/src/css/Torque.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.Torque', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.torque',
4 |
5 | value: {
6 | Map: {
7 | torqueFrameCount: 256,
8 | torqueAnimationDuration: 30,
9 | torqueTimeAttribute: '"cartodb_id"',
10 | torqueAggregationFunction: '"count(cartodb_id)"',
11 | torqueResolution: 2,
12 | torqueDataAggregation: 'linear'
13 | },
14 |
15 | compOp: 'lighter',
16 | markerFillOpacity: 0.9,
17 | markerLineColor: '#FFF',
18 | markerLineWidth: 0,
19 | markerLineOpacity: 1,
20 | markerType: 'ellipse',
21 | markerWidth: 6,
22 | markerFill: '#0F3B82',
23 | case: [{
24 | condition: 'frame-offset=1',
25 | markerWidth: 8,
26 | markerFillOpacity: 0.45
27 | }, {
28 | condition: 'frame-offset=2',
29 | markerWidth: 10,
30 | markerFillOpacity: 0.225
31 | }]
32 | }
33 | });
--------------------------------------------------------------------------------
/src/css/TorqueCat.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.css.TorqueCat', {
2 | extend: 'Carto.css.Css',
3 | alias: 'cartocss.torquecat',
4 |
5 | // Coming Soon...
6 | value: {
7 | markerLineColor: '#FFF',
8 | markerLineWidth: '1.5',
9 | markerLineOpacity: '1',
10 | markerFillOpacity: '0.9',
11 | markerPlacement: 'point',
12 | markerType: 'ellipse',
13 | markerFill: '#FF6600',
14 | markerWidth: '10',
15 | markerAllowOverlap: true
16 | }
17 | });
--------------------------------------------------------------------------------
/src/layer/LayerBase.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.layer.LayerBase', {
2 | extend: 'Carto.AbstractLayer',
3 |
4 | mixins: [
5 | 'Ext.mixin.Factoryable'
6 | ],
7 |
8 | isLayer: true,
9 |
10 | factoryConfig: {
11 | defaultType: 'cartodb',
12 | type: 'layer'
13 | },
14 |
15 | config: {
16 | map: null
17 | },
18 |
19 | getRefOwner: function() {
20 | return this.getMap();
21 | }
22 | });
--------------------------------------------------------------------------------
/src/layer/LayerGroup.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.layer.LayerGroup', {
2 | extend: 'Carto.layer.LayerBase',
3 | alias: 'layer.layergroup',
4 |
5 | requires: [
6 | 'Carto.util.SubLayerCollection'
7 | ],
8 |
9 | isLayerGroup: true,
10 |
11 | config: {
12 | subLayers: null
13 | },
14 |
15 | createCartoSubLayer: function(subLayer) {
16 | if (this.isCreating) {
17 | return;
18 | }
19 | this.isCreating = true;
20 | if (this.getCartoLayer()) {
21 | this.getCartoLayer().addLayer(subLayer.buildCartoLayer());
22 | } else if (this.allSubLayersReady()) {
23 | this.getMap().createCartoLayer(this);
24 | }
25 | delete this.isCreating;
26 | },
27 |
28 | allSubLayersReady: function() {
29 | var subLayers = this.getSubLayers(),
30 | allReady = true;
31 | if (subLayers) {
32 | subLayers.each(function(subLayer) {
33 | if (!subLayer.isReadyToBuild()) {
34 | allReady = false;
35 | return false;
36 | }
37 | });
38 | } else {
39 | allReady = false;
40 | }
41 | return allReady;
42 | },
43 |
44 | buildCartoLayer: function() {
45 | var subLayerArr = [],
46 | subLayers = this.getSubLayers(),
47 | ret = {
48 | ext_id: this.getId(),
49 | user_name: this.getUsername(),
50 | tiler_domain: this.useCartoDb ? 'cartodb.com' : 'carto.com',
51 | type: this.getType(),
52 | sublayers: subLayerArr
53 | };
54 | if (subLayers) {
55 | subLayers.each(function(subLayer) {
56 | subLayerArr.push(subLayer.buildCartoSubLayer());
57 | });
58 | }
59 | return ret;
60 | },
61 |
62 | updateMap: function(map, oldMap) {
63 | var subLayers = this.getSubLayers();
64 | if (subLayers && map) {
65 | map.addSubLayer(subLayers.getRange());
66 | }
67 | },
68 |
69 | updateCartoLayer: function(cartoLayer) {
70 | this.callParent(arguments);
71 | var subLayers = this.getSubLayers();
72 | if (subLayers) {
73 | subLayers.each(function(subLayer, index) {
74 | subLayer.setCartoLayer(cartoLayer.getSubLayer(index));
75 | });
76 | }
77 | },
78 |
79 | applySubLayers: function(subLayers, subLayerCollection) {
80 | var map = this.getMap();
81 | if (!subLayerCollection) {
82 | subLayerCollection = Ext.create('Carto.util.SubLayerCollection', {
83 | owner: this
84 | });
85 | }
86 | subLayers = subLayerCollection.add(subLayers);
87 | if (subLayers && map) {
88 | map.addLayer(subLayers);
89 | }
90 | return subLayerCollection;
91 | },
92 |
93 | doDestroy: function() {
94 | var subLayers = this.getSubLayers();
95 | if (subLayers) {
96 | subLayers.each(function(subLayer) {
97 | subLayer.destroy();
98 | });
99 | }
100 | }
101 | });
--------------------------------------------------------------------------------
/src/layer/Torque.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.layer.Torque', {
2 | extend: 'Carto.layer.LayerBase',
3 | alias: 'layer.torque',
4 |
5 | mixins: [
6 | 'Carto.mixin.DataContainingLayer'
7 | ],
8 |
9 | defaultBindProperty: 'store',
10 |
11 | twoWayBindable: [
12 | 'selection'
13 | ],
14 |
15 | create: function() {
16 | if (this.isReadyToBuild()) {
17 | this.getMap().createCartoLayer(this);
18 | }
19 | },
20 |
21 | buildCartoLayer: function() {
22 | return {
23 | type: this.getType(),
24 | user_name: this.getUsername(),
25 | options: {
26 | ext_id: this.getId(),
27 | query: this.getSql(),
28 | cartocss: this.getCss(),
29 | table_name: this.getTable()
30 | }
31 | };
32 | },
33 |
34 | updateCartoLayer: function(cartoLayer) {
35 | this.callParent(arguments);
36 | this.mixins.dataContainingLayer.updateCartoLayer.call(this, cartoLayer);
37 | }
38 | });
--------------------------------------------------------------------------------
/src/mixin/DataContainingLayer.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.mixin.DataContainingLayer', {
2 | mixinId: 'dataContainingLayer',
3 |
4 | requires: [
5 | 'Carto.css.Css',
6 | 'Carto.css.Point',
7 | 'Carto.css.Line',
8 | 'Carto.css.Polygon',
9 | 'Carto.css.Intensity',
10 | 'Carto.css.HeatMap',
11 | 'Carto.css.Torque',
12 | 'Carto.css.TorqueCat',
13 | 'Carto.LayerManager'
14 | ],
15 |
16 | isDataContainingLayer: true,
17 |
18 | config: {
19 | store: null,
20 | sql: '',
21 | css: {
22 | type: 'point'
23 | },
24 | selection: null,
25 | interactivity: null
26 | },
27 |
28 | isReadyToBuild: function() {
29 | return !!(this.getSql() && this.getCss());
30 | },
31 |
32 | updateSql: function(sql) {
33 | if (sql) {
34 | var cartoLayer = this.getCartoLayer();
35 | if (cartoLayer) {
36 | cartoLayer.setSQL(sql);
37 | } else {
38 | this.create();
39 | }
40 | }
41 | },
42 |
43 | updateCartoLayer: function(cartoLayer) {
44 | var interactivity = this.getInteractivity(),
45 | tooltip;
46 | if (interactivity && interactivity.enable) {
47 | cartoLayer.setInteraction(true);
48 | cartoLayer.set({
49 | interactivity: 'cartodb_id' + ((interactivity.fields) ? ',' + interactivity.fields.join(',') : '')
50 | });
51 | tooltip = interactivity.tooltip;
52 | if(tooltip && tooltip.enable){
53 | this.getMap().getCartoMap().viz.addOverlay({
54 | type: 'tooltip',
55 | layer: cartoLayer,
56 | template: tooltip.html || this.createDefaultTooltip(tooltip.fields || interactivity.fields, tooltip.mood),
57 | position: tooltip.position || 'bottom|right',
58 | fields: [this.createFields(interactivity.fields)]
59 | });
60 | }
61 | cartoLayer.on('featureClick', this.featureClick.bind(this));
62 | cartoLayer.on('featureOver', this.featureOver.bind(this));
63 | cartoLayer.on('featureOut', this.featureOut.bind(this));
64 | }
65 | },
66 |
67 | featureClick: function(e, latLng, point, record){
68 | var selection = this.getRecord(record.cartodb_id);
69 | this.setSelection(selection);
70 | this.getLayer().getMap().setSelection(selection);
71 | if (this.hasListeners.itemclick) {
72 | this.fireEvent('itemclick', this, selection);
73 | }
74 | if (this.hasListeners.select) {
75 | this.fireEvent('select', this, selection);
76 | }
77 | },
78 |
79 | featureOver: function() {
80 | if (!this._cursor && $('.leaflet-container').css('cursor') != 'pointer' ) {
81 | this._cursor = $('.leaflet-container').css('cursor');
82 | }
83 | $('.leaflet-container').css('cursor','pointer');
84 | },
85 |
86 | featureOut: function() {
87 | $('.leaflet-container').css('cursor',this._cursor);
88 | },
89 |
90 | createDefaultTooltip: function(fields, mood) {
91 | var html = '';
92 | for(var i = 0; i < fields.length; i++){
93 | html += '
' + fields[i] + ' {{' + fields[i] + '}}
';
94 | }
95 | return html + '
';
96 | },
97 |
98 | createFields: function(fields) {
99 | var obj = {};
100 | for(var i = 0; i < fields.length; i++){
101 | obj[fields[i]] = fields[i];
102 | }
103 | return obj;
104 | },
105 |
106 | getRecord: function(cartodb_id) {
107 | return this.getStore().findRecord('cartodb_id', cartodb_id);
108 | },
109 |
110 | applyStore: function(store) {
111 | if (store) {
112 | store = Ext.StoreManager.lookup(store, 'carto');
113 | //
114 | if (!store.isCartoStore) {
115 | Ext.raise('Carto Layers cannot have non-carto stores.');
116 | }
117 | //
118 | }
119 | return store;
120 | },
121 |
122 | updateStore: function(store) {
123 | if (store) {
124 | store.addLayerToProxy(this);
125 | }
126 | },
127 |
128 | updateSelection: function(selection) {
129 | if (this.hasListeners.select) {
130 | this.fireEvent('select', this, selection);
131 | }
132 | },
133 |
134 | setCssAttribute: function(attr, value, suppressed) {
135 | if (typeof attr !== 'string') {
136 | suppressed = value;
137 | }
138 | this.css.set(attr, value);
139 | if (!suppressed) {
140 | this.updateCss(this.css);
141 | }
142 | },
143 |
144 | addCssCase: function(caseObj, suppressed) {
145 | this.css.addCase(caseObj);
146 | if (!suppressed) {
147 | this.updateCss(this.css);
148 | }
149 | },
150 |
151 | removeCssCase: function(condition, suppressed) {
152 | this.css.removeCase(condition);
153 | if (!suppressed) {
154 | this.updateCss(this.css);
155 | }
156 | },
157 |
158 | getCss: function() {
159 | var css = this.callParent();
160 | if (css && typeof css !== 'string') {
161 | css = css.getCssString();
162 | }
163 | return css;
164 | },
165 |
166 | applyCss: function(css) {
167 | return Carto.LayerManager.lookupCss(css);
168 | },
169 |
170 | updateCss: function(css) {
171 | if (css) {
172 | var cartoLayer = this.getCartoLayer();
173 | if (cartoLayer) {
174 | cartoLayer.setCartoCSS(typeof css === 'string' ? css : css.getCssString());
175 | } else {
176 | this.create();
177 | }
178 | }
179 | }
180 |
181 | });
--------------------------------------------------------------------------------
/src/sql/CartoField.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.sql.CartoField', {
2 | extend: 'Carto.sql.CartoSql',
3 |
4 | isCartoField: true,
5 |
6 | // In honor of the original intent for these fields, keep it light
7 |
8 | property: null,
9 | sql: '',
10 |
11 | constructor: function(config) {
12 | this.callParent([config]);
13 | if (!this.sql) {
14 | this.createSql();
15 | }
16 | },
17 |
18 | createSql: function() {
19 | var name = this.getName(),
20 | property = this.getProperty();
21 | this.sql = property ? property + ' AS ' + name : name;
22 | },
23 |
24 | parseSql: function(sql) {
25 | var parseSql = this.stripEnds(sql).split(/\s/),
26 | len = parseSql.length;
27 | if (len > 1) {
28 | this.setAlias(parseSql[len-1]);
29 | } else {
30 | this.setName(parseSql[0]);
31 | }
32 | },
33 |
34 | getProperty: function() {
35 | return this.property;
36 | },
37 |
38 | getId: function() {
39 | return this.getAlias() || this.getName();
40 | },
41 |
42 | singleRegex: /^\w+$/,
43 |
44 | stripEnds: function(str) {
45 | return str.replace(/^\s+/, '').replace(/\s+$/, '');
46 | }
47 | });
--------------------------------------------------------------------------------
/src/sql/CartoFrom.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.sql.CartoFrom', {
2 | extend: 'Carto.sql.CartoSql',
3 |
4 | requires: [
5 | 'Carto.util.TableCollection'
6 | ],
7 |
8 | isCartoFrom: true,
9 |
10 | config: {
11 | tables: null
12 | },
13 |
14 | decode: function(config) {
15 | if (!config.tables) {
16 | config = {tables: config};
17 | }
18 | if (!Ext.isArray(config.tables)) {
19 | config.tables = [config.tables];
20 | }
21 | return config;
22 | },
23 |
24 | isMulti: function() {
25 | return this.getTables().length > 1;
26 | },
27 |
28 | applyTables: function(tables, tableCollection) {
29 | if (!tableCollection) {
30 | tableCollection = Ext.create('Carto.util.TableCollection');
31 | }
32 | tableCollection.add(tables);
33 | return tableCollection;
34 | },
35 |
36 | createSql: function(sql) {
37 | this.setSql(this.getTables().getSql());
38 | }
39 | });
--------------------------------------------------------------------------------
/src/sql/CartoSql.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.sql.CartoSql', {
2 | isCartoSql: true,
3 |
4 | config: {
5 | sql: '',
6 | hardcoded: false
7 | },
8 |
9 | constructor: function(config) {
10 | this.initConfig(config);
11 | var sql = this.getSql();
12 | if (sql) {
13 | this.setHardcoded(true);
14 | this.parseSql(sql);
15 | } else {
16 | this.createSql();
17 | }
18 | return this;
19 | },
20 |
21 | initConfig: function(config) {
22 | config = this.decode(config);
23 | return this.callParent([config]);
24 | },
25 |
26 | parseSql: Ext.emptyFn,
27 | createSql: Ext.emptyFn,
28 |
29 | decode: function(config) {
30 | return config;
31 | },
32 |
33 | stripEnds: function(str) {
34 | return str.replace(/^\s+/, '').replace(/\s+$/, '');
35 | }
36 | });
--------------------------------------------------------------------------------
/src/sql/CartoTable.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.sql.CartoTable', {
2 | extend: 'Carto.sql.CartoSql',
3 |
4 | isCartoTable: true,
5 |
6 | config: {
7 | name: '',
8 | alias: ''
9 | },
10 |
11 | decode: function(config) {
12 | if (typeof config === 'string') {
13 | if (/\s/.test(this.stripEnds(config))) {
14 | config = {sql: config};
15 | } else {
16 | config = {name: config};
17 | }
18 | }
19 | return config;
20 | },
21 |
22 | createSql: function() {
23 | var name = this.getName(),
24 | alias = this.getAlias();
25 | this.setSql(name + (alias ? ' AS ' + alias : ''));
26 | },
27 |
28 | parseSql: function(sql) {
29 | var parseSql = this.stripEnds(sql).split(/\s/),
30 | len = parseSql.length;
31 | if (len > 1) {
32 | this.setAlias(parseSql[len-1]);
33 | } else {
34 | this.setName(parseSql[0]);
35 | }
36 | },
37 |
38 | getId: function() {
39 | return this.getAlias() || this.getName();
40 | }
41 | });
--------------------------------------------------------------------------------
/src/sublayer/CartoDb.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.sublayer.CartoDb', {
2 | extend: 'Carto.sublayer.SubLayerBase',
3 | alias: 'sublayer.cartodb',
4 |
5 | buildCartoSubLayer: function() {
6 | return {
7 | type: this.getType(),
8 | sql: this.getSql(),
9 | cartocss: this.getCss()
10 | };
11 | }
12 | });
--------------------------------------------------------------------------------
/src/sublayer/SubLayerBase.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.sublayer.SubLayerBase', {
2 | extend: 'Carto.AbstractLayer',
3 |
4 | mixins: [
5 | 'Carto.mixin.DataContainingLayer',
6 | 'Ext.mixin.Factoryable'
7 | ],
8 |
9 | isSubLayer: true,
10 |
11 | defaultBindProperty: 'store',
12 |
13 | twoWayBindable: [
14 | 'selection'
15 | ],
16 |
17 | factoryConfig: {
18 | defaultType: 'cartodb',
19 | type: 'sublayer'
20 | },
21 |
22 | config: {
23 | layer: null
24 | },
25 |
26 | create: function() {
27 | if (this.isReadyToBuild()) {
28 | this.getLayer().createCartoSubLayer(this);
29 | }
30 | },
31 |
32 | updateUsername: function(username, oldUsername) {
33 | var layer = this.getLayer();
34 | if (username && layer) {
35 | layer.setUsername(username);
36 | }
37 | },
38 |
39 | updateLayer: function(layer, oldLayer) {
40 | if (layer) {
41 | var username = this.getUsername();
42 | if (username) {
43 | layer.setUsername(username);
44 | }
45 | }
46 | },
47 |
48 | updateCartoLayer: function(cartoLayer) {
49 | this.callParent(arguments);
50 | this.mixins.dataContainingLayer.updateCartoLayer.call(this, cartoLayer);
51 | },
52 |
53 | getRefOwner: function() {
54 | return this.getLayer();
55 | },
56 |
57 | getMap: function() {
58 | return this.getLayer().getMap();
59 | }
60 | });
--------------------------------------------------------------------------------
/src/util/LayerCollection.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.util.LayerCollection', {
2 | extend: 'Ext.util.Collection',
3 |
4 | requires: [
5 | 'Carto.LayerManager',
6 | 'Carto.layer.LayerGroup',
7 | 'Carto.layer.Torque'
8 | ],
9 |
10 | isLayerCollection: true,
11 |
12 | constructor: function(config) {
13 | this.callParent([config]);
14 | this.setDecoder(this.decodeLayer);
15 | },
16 |
17 | decodeLayer: function(layer) {
18 | var owner = this.getOwner();
19 | if (!layer.isLayer && owner && owner.isMap) {
20 | layer.map = owner;
21 | }
22 | return Carto.LayerManager.lookupLayer(layer);
23 | },
24 |
25 | getOwner: function() {
26 | return this.owner;
27 | }
28 | });
--------------------------------------------------------------------------------
/src/util/SubLayerCollection.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.util.SubLayerCollection', {
2 | extend: 'Ext.util.Collection',
3 |
4 | requires: [
5 | 'Carto.LayerManager',
6 | 'Carto.sublayer.CartoDb'
7 | ],
8 |
9 | isSubLayerCollection: true,
10 |
11 | constructor: function(config) {
12 | this.callParent([config]);
13 | this.setDecoder(this.decodeSubLayer);
14 | },
15 |
16 | decodeSubLayer: function(subLayer) {
17 | var owner = this.getOwner();
18 | if (!subLayer.isSubLayer && owner && owner.isLayer) {
19 | subLayer.layer = owner;
20 | }
21 | return Carto.LayerManager.lookupSubLayer(subLayer, 'cartodb');
22 | },
23 |
24 | getOwner: function() {
25 | return this.owner;
26 | }
27 | });
--------------------------------------------------------------------------------
/src/util/TableCollection.js:
--------------------------------------------------------------------------------
1 | Ext.define('Carto.util.TableCollection', {
2 | extend: 'Ext.util.Collection',
3 |
4 | requires: [
5 | 'Carto.sql.CartoTable'
6 | ],
7 |
8 | isTableCollection: true,
9 |
10 | constructor: function(config) {
11 | this.callParent([config]);
12 | this.setDecoder(this.decodeTable);
13 | },
14 |
15 | decodeTable: function(table) {
16 | if (!table.isCartoTable) {
17 | table = new Carto.sql.CartoTable(table);
18 | }
19 | return table;
20 | },
21 |
22 | getSql: function() {
23 | var sql = '';
24 | this.items.forEach(function(item) {
25 | sql += item.getSql() + ',';
26 | });
27 | return sql.slice(0,-1);
28 | }
29 | });
--------------------------------------------------------------------------------