├── .gitignore ├── src ├── index.js ├── classify.js ├── string-to-dom.js ├── colors.js └── malette.js ├── .jshintrc ├── index.html ├── karma.conf.js ├── README.md ├── spec ├── colors.spec.js ├── classify.spec.js └── malette.spec.js ├── package.json └── dist ├── malette.css ├── polyfilled-malette.js └── malette.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | _tmp 3 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './malette.js'; 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "jasmine": true, 4 | "globals": { 5 | "describe": true, 6 | "it": true, 7 | "expect": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Malette es6 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/classify.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Classify returns classification breaks for a field based on stats 3 | * @param {string} fieldName field to classify on 4 | * @param {array} fields array of possible fields 5 | * 6 | */ 7 | export function classify (fieldName, fields){ 8 | 9 | var breaks = 8; 10 | var values = []; 11 | 12 | fields.forEach(function(f) { 13 | if ( f.name === fieldName ) { 14 | var step = ( f.statistics.max - f.statistics.min ) / breaks; 15 | for (var i = 0; i<=breaks; i++ ) { 16 | values.push( f.statistics.min + (step * i) ); 17 | } 18 | } 19 | }); 20 | 21 | return values; 22 | } -------------------------------------------------------------------------------- /src/string-to-dom.js: -------------------------------------------------------------------------------- 1 | export function stringToDom(tagString) { 2 | var dom; 3 | 4 | // standards land (IE 11+, FF, Chrome, Safari) 5 | if (document.createRange) { 6 | var range = document.createRange(); 7 | range.selectNode(document.body); 8 | dom = range.createContextualFragment(tagString); 9 | } else { 10 | try { 11 | // non standard IE behavior will throw a DOM error in non IE 12 | dom = document.createElement(tagString); 13 | } catch (e){ 14 | // this is what most libraries do (jquery ect...) 15 | var div = document.createElement('div'); 16 | div.innerHTML = tagString; 17 | dom = div.childNodes; 18 | } 19 | } 20 | 21 | return dom; 22 | } -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | 2 | /* global module */ 3 | module.exports = function (config) { 4 | 'use strict'; 5 | config.set({ 6 | 7 | autoWatch: true, 8 | 9 | singleRun: false, 10 | 11 | frameworks: [ 'browserify', 'jasmine' ], 12 | 13 | preprocessors: { 14 | 'src/**/*.js': [ 'browserify' ], 15 | 'spec/**/*.js': [ 'browserify' ] 16 | }, 17 | 18 | browserify: { 19 | debug: true, 20 | transform: [ 'babelify' ] 21 | }, 22 | 23 | files: [ 24 | 'spec/**/*.js' 25 | ], 26 | 27 | // proxies: { 28 | // '/base': '/base/src' 29 | // }, 30 | 31 | browsers: [ 'PhantomJS' ], 32 | 33 | reporters: [ 'progress' ], 34 | 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Malette.js 2 | A lightweight style editor for maps 3 | 4 | **** 5 | 6 | Malette UI: [http://benheb.github.io/malette-ui/](http://benheb.github.io/malette-ui/) 7 | 8 | 9 | ## TODO: 10 | - [X] es6ify it 11 | - [X] build 12 | - [ ] ~~make it a custom element~~ maybe not - you need to manipulate it programatically after the map is instantiated anyway 13 | - [ ] ~~use templates~~ (can only really use html templates with html imports which firefox has said they will not support) 14 | - [ ] ~~package css into it~~ (i think we would need html imports for this too) 15 | - [ ] break it into several files/modules? [ in progress ] 16 | - [ ] use more es6 features [ in progress ] 17 | - [X] tests 18 | - [ ] sourcemaps 19 | - [ ] code coverage 20 | -------------------------------------------------------------------------------- /spec/colors.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { dojoColorToRgba, rgbaToDojoColor } from '../src/colors'; 4 | 5 | describe('colors', () => { 6 | 7 | describe('dojoColorToRgba', () => { 8 | 9 | it('should return rgba', function () { 10 | var result = dojoColorToRgba([ 1, 2, 3, 0.4 ]); 11 | expect(result).toEqual('rgba(1,2,3,0.4)'); 12 | }); 13 | 14 | }); 15 | 16 | describe('rgbaToDojoColor', () => { 17 | 18 | it('should return color array when passed an array', function () { 19 | var result = rgbaToDojoColor([ 1, 2, 3 ], 0.4); 20 | expect(result).toEqual([ 1, 2, 3, 0.4 ]); 21 | }); 22 | 23 | it('should return color array when passed a string', function () { 24 | var result = rgbaToDojoColor('1, 2, 3', 0.4); 25 | expect(result).toEqual([ 1, 2, 3, 0.4 ]); 26 | }); 27 | 28 | }); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /spec/classify.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { classify } from '../src/classify'; 4 | 5 | describe('classify', () => { 6 | 7 | var fields = [ 8 | { 9 | name: 'foo', 10 | statistics: { 11 | min: 1, 12 | max: 10 13 | } 14 | }, 15 | { 16 | name: 'bar', 17 | statistics: { 18 | min: 1, 19 | max: 100 20 | } 21 | }, 22 | { 23 | name: 'baz', 24 | statistics: { 25 | min: 0, 26 | max: 4 27 | } 28 | } 29 | ]; 30 | 31 | it('should return class breaks (1 - 10)', function () { 32 | var result = classify('foo', fields); 33 | expect(result).toEqual([ 1, 2.125, 3.25, 4.375, 5.5, 6.625, 7.75, 8.875, 10 ]); 34 | }); 35 | 36 | it('should return class breaks (1 - 100)', function () { 37 | var result = classify('bar', fields); 38 | expect(result).toEqual([ 1, 13.375, 25.75, 38.125, 50.5, 62.875, 75.25, 87.625, 100 ]); 39 | }); 40 | 41 | it('should return class breaks (0 - 4)', function () { 42 | var result = classify('baz', fields); 43 | expect(result).toEqual([ 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4 ]); 44 | }); 45 | 46 | }); 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "malette", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "npm run build && npm run server", 8 | "test": "karma start", 9 | "build": "npm run compile && npm run bundle && npm run combine", 10 | "compile": "babel src -d _tmp --blacklist es6.modules -e 0", 11 | "bundle": "rollup _tmp/index.js -o dist/malette.js", 12 | "combine": "uglifyjs node_modules/document-register-element/build/document-register-element.js dist/malette.js -o dist/polyfilled-malette.js", 13 | "server": "http-server -p 8081", 14 | "open": "opener http://localhost:8081", 15 | "watch": "watch 'npm run build' src" 16 | }, 17 | "author": "", 18 | "license": "ISC", 19 | "devDependencies": { 20 | "babel": "^5.8.21", 21 | "babelify": "^6.1.3", 22 | "http-server": "^0.8.0", 23 | "jasmine": "^2.3.2", 24 | "jasmine-core": "^2.3.4", 25 | "karma": "^0.13.9", 26 | "karma-browserify": "^4.3.0", 27 | "karma-jasmine": "^0.3.6", 28 | "karma-phantomjs-launcher": "^0.2.1", 29 | "phantomjs": "^1.9.18", 30 | "rollup": "^0.12.1", 31 | "uglify-js": "^2.4.24" 32 | }, 33 | "dependencies": { 34 | "document-register-element": "^0.4.5" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/colors.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Converts dojo color to rgba 4 | * @param {array} c dojo color to be converted 5 | * returns rgba color 6 | * 7 | */ 8 | export function dojoColorToRgba(c) { 9 | var color = 'rgba('+c[0]+','+c[1]+','+c[2]+','+c[3]+')'; 10 | return color; 11 | } 12 | 13 | 14 | /* 15 | * Converts rgba back to dojo color 16 | * @param {string} c rgba string 17 | * @param {number} opacity the a in rgba 18 | * 19 | */ 20 | export function rgbaToDojoColor(c, opacity) { 21 | var color; 22 | if ( !opacity ) opacity = 255; 23 | 24 | if ( Array.isArray(c) ) { 25 | color = c; 26 | color[3] = opacity; 27 | return color; 28 | } else { 29 | color = c.split(','); 30 | return [ parseInt(color[0].replace(/[^0-9]/g, '')), parseInt(color[1]), parseInt(color[2]), opacity ]; 31 | } 32 | } 33 | 34 | 35 | /* 36 | * Theme colors for use in Malette 37 | * 38 | * 39 | */ 40 | export var themeColors = [ 41 | ['rgb(255,255,255)','rgb(240,240,240)','rgb(217,217,217)','rgb(189,189,189)','rgb(150,150,150)','rgb(115,115,115)','rgb(82,82,82)','rgb(37,37,37)'], 42 | ['rgb(255,255,217)','rgb(237,248,177)','rgb(199,233,180)','rgb(127,205,187)','rgb(65,182,196)','rgb(29,145,192)','rgb(34,94,168)','rgb(12,44,132)'], 43 | ['rgb(255,255,229)','rgb(247,252,185)','rgb(217,240,163)','rgb(173,221,142)','rgb(120,198,121)','rgb(65,171,93)','rgb(35,132,67)','rgb(0,90,50)'], 44 | ['rgb(255,247,251)','rgb(236,226,240)','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(54,144,192)','rgb(2,129,138)','rgb(1,100,80)'], 45 | ['rgb(247,252,253)','rgb(224,236,244)','rgb(191,211,230)','rgb(158,188,218)','rgb(140,150,198)','rgb(140,107,177)','rgb(136,65,157)','rgb(110,1,107)'], 46 | ['rgb(255,255,204)','rgb(255,237,160)','rgb(254,217,118)','rgb(254,178,76)','rgb(253,141,60)','rgb(252,78,42)','rgb(227,26,28)','rgb(177,0,38)'], 47 | ['rgb(255,245,235)','rgb(254,230,206)','rgb(253,208,162)','rgb(253,174,107)','rgb(253,141,60)','rgb(241,105,19)','rgb(217,72,1)','rgb(140,45,4)'] 48 | ] 49 | 50 | 51 | 52 | /* 53 | * Single colors used to construct Malette color picker 54 | * 55 | * 56 | */ 57 | export var colorSwatches = [ 58 | 'rgb(255,255,255)','rgb(240,240,240)','rgb(217,217,217)','rgb(189,189,189)','rgb(150,150,150)','rgb(115,115,115)','rgb(82,82,82)','rgb(37,37,37)', 59 | 'rgb(247,252,253)','rgb(224,236,244)','rgb(191,211,230)','rgb(158,188,218)','rgb(140,150,198)','rgb(140,107,177)','rgb(136,65,157)','rgb(110,1,107)', 60 | 'rgb(255,247,243)','rgb(253,224,221)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(221,52,151)','rgb(174,1,126)','rgb(122,1,119)', 61 | 'rgb(255,255,204)','rgb(255,237,160)','rgb(254,217,118)','rgb(254,178,76)','rgb(253,141,60)','rgb(252,78,42)','rgb(227,26,28)','rgb(177,0,38)', 62 | 'rgb(255,255,217)','rgb(237,248,177)','rgb(199,233,180)','rgb(127,205,187)','rgb(65,182,196)','rgb(29,145,192)','rgb(34,94,168)','rgb(12,44,132)', 63 | 'rgb(247,252,240)','rgb(224,243,219)','rgb(204,235,197)','rgb(168,221,181)','rgb(123,204,196)','rgb(78,179,211)','rgb(43,140,190)','rgb(8,88,158)', 64 | 'rgb(247,252,253)','rgb(229,245,249)','rgb(204,236,230)','rgb(153,216,201)','rgb(102,194,164)','rgb(65,174,118)','rgb(35,139,69)','rgb(0,88,36)' 65 | ]; -------------------------------------------------------------------------------- /spec/malette.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Malette } from '../src/malette'; 4 | 5 | describe('Malette... ', function(){ 6 | var malette, url = null, options = null, json, fields; 7 | 8 | beforeEach(function () { 9 | // inject the HTML fixture for the tests 10 | var fixture = '
'; 11 | document.body.insertAdjacentHTML('afterbegin', fixture); 12 | 13 | spyOn(Malette.prototype, '_buildUI').and.callFake(function(){}); 14 | spyOn(Malette.prototype, '_addExporter').and.callFake(function(){}); 15 | 16 | json = { 17 | "type": "simple", 18 | "label": "", 19 | "description": "", 20 | "symbol": { 21 | "color": [ 22 | 158, 23 | 188, 24 | 218, 25 | 191 26 | ], 27 | "size": 3, 28 | "angle": 0, 29 | "xoffset": 0, 30 | "yoffset": 0, 31 | "type": "esriSMS", 32 | "style": "esriSMSCircle", 33 | "outline": { 34 | "color": [ 35 | 255, 36 | 255, 37 | 255, 38 | 255 39 | ], 40 | "width": 0.2, 41 | "type": "esriSLS", 42 | "style": "esriSLSSolid" 43 | } 44 | } 45 | }; 46 | 47 | fields = [ 48 | { 49 | alias: 'testField', 50 | name: 'testField', 51 | statistics: { 52 | avg: 100, 53 | min: 10, 54 | max: 500, 55 | stddev: 1.2 56 | }, 57 | type: 'esriFieldTypeDouble' 58 | } 59 | ]; 60 | 61 | options = { 62 | style: json, 63 | formatIn: 'esri-json', 64 | formatOut: 'esri-json', 65 | fields: fields, 66 | type: 'point', 67 | exportStyle: true 68 | }; 69 | 70 | malette = new Malette('container-element', options); 71 | 72 | }); 73 | 74 | // remove the html fixture from the DOM 75 | afterEach(function() { 76 | document.body.removeChild(document.getElementById('container-element')); 77 | }); 78 | 79 | it('container to equal', function(){ 80 | expect(malette.container).toBe('container-element'); 81 | }); 82 | 83 | it('build UI should be called', function() { 84 | expect(malette._buildUI).toHaveBeenCalled(); 85 | }); 86 | 87 | it('build exporter should be called', function() { 88 | expect(malette._addExporter).toHaveBeenCalled(); 89 | }); 90 | 91 | it('state graduated to be false', function(){ 92 | expect(malette.state._isGraduated).toBe(false); 93 | }); 94 | 95 | it('state theme to be false', function(){ 96 | expect(malette.state._isTheme).toBe(false); 97 | }); 98 | 99 | it('state type to be point', function(){ 100 | expect(malette.state.type).toBe('point'); 101 | }); 102 | 103 | it('set opacity', function() { 104 | spyOn(Malette.prototype, 'updateStyle').and.callFake(function(){}); 105 | spyOn(Malette.prototype, '_setInnerHTML').and.callFake(function(){}); 106 | 107 | malette.setOpacity(0.5); 108 | expect(malette.state.fillOpacity).toEqual( 127.5 ); 109 | }); 110 | 111 | it('set stroke width', function() { 112 | spyOn(Malette.prototype, 'updateStyle').and.callFake(function(){}); 113 | spyOn(Malette.prototype, '_setInnerHTML').and.callFake(function(){}); 114 | 115 | malette.setStrokeWidth( 5 ); 116 | expect(malette.style.symbol.outline.width).toEqual( 5 ); 117 | }); 118 | 119 | it('set size', function() { 120 | spyOn(Malette.prototype, 'updateStyle').and.callFake(function(){}); 121 | spyOn(Malette.prototype, '_setInnerHTML').and.callFake(function(){}); 122 | 123 | malette.setSelectedSize( 5 ); 124 | expect(malette.style.symbol.size).toEqual( 5 ); 125 | }); 126 | 127 | it('clear graduated symbol', function() { 128 | spyOn(Malette.prototype, 'updateStyle').and.callFake(function(){}); 129 | spyOn(Malette.prototype, '_setInnerHTML').and.callFake(function(){}); 130 | 131 | malette.clearGraduated(); 132 | expect(malette.style.classBreakInfos).toEqual( null ); 133 | expect(malette.updateStyle).toHaveBeenCalled(); 134 | }); 135 | 136 | it('clear themes', function() { 137 | spyOn(Malette.prototype, 'updateStyle').and.callFake(function(){}); 138 | spyOn(Malette.prototype, '_setInnerHTML').and.callFake(function(){}); 139 | 140 | malette.clearTheme(); 141 | expect(malette.style.visualVariables).toEqual( null ); 142 | expect(malette.updateStyle).toHaveBeenCalled(); 143 | }); 144 | 145 | }); 146 | -------------------------------------------------------------------------------- /dist/malette.css: -------------------------------------------------------------------------------- 1 | #malette { 2 | position: absolute; 3 | z-index: 1000; 4 | pointer-events: none; 5 | right: 10px; 6 | top: 10px; 7 | background: #FFF; 8 | min-height: 110px; 9 | width:300px; 10 | box-shadow: 0 1px 5px rgba(0,0,0,0.11); 11 | border-radius: 4px; 12 | } 13 | 14 | #malette-header { 15 | padding: 5px; 16 | background: #EEE; 17 | text-transform: uppercase; 18 | font-family: Helvetica, Arial, sans-serif; 19 | font-weight: 700; 20 | font-size: 1em; 21 | line-height: 1em; 22 | pointer-events:auto; 23 | border-top-left-radius: 4px; 24 | border-top-right-radius: 4px; 25 | color: rgba(172, 172, 172, 0.7); 26 | text-shadow: 1px 1px 1px #EEE, 0 0 0 #EEE, 1px 2px 4px #EEE; 27 | } 28 | 29 | #malette-title { 30 | width: 100%; 31 | overflow: hidden; 32 | position: relative; 33 | padding-left: 4px; 34 | padding-right: 10px; 35 | border-bottom: 1px solid #eee; 36 | white-space: nowrap; 37 | overflow: hidden; 38 | text-overflow: ellipsis; 39 | } 40 | 41 | /* Don't show shadows when selecting text */ 42 | ::-moz-selection { background: #5af; color: #fff; text-shadow: none; } 43 | ::selection { background: #5af; color: #fff; text-shadow: none; } 44 | 45 | #malette-content { 46 | width: 250px; 47 | margin-left: 50px; 48 | height: 220px; 49 | position: absolute; 50 | padding:10px; 51 | padding-left:12px; 52 | pointer-events:auto; 53 | } 54 | 55 | #malette-tab-region { 56 | width: 50px; 57 | border-right: 1px solid #EEE; 58 | min-height: 220px; 59 | position: relative; 60 | pointer-events:auto; 61 | } 62 | 63 | .malette-tab { 64 | padding:4px; 65 | border-bottom: 1px solid #EEE; 66 | text-align: center; 67 | padding-top: 8px; 68 | padding-bottom: 8px; 69 | cursor: pointer; 70 | font-size: 1.1rem; 71 | } 72 | 73 | .malette-tab.disabled { 74 | color: #EEE; 75 | } 76 | 77 | .malette-tab.disabled:hover { 78 | cursor: default; 79 | background: #FFF; 80 | } 81 | 82 | .malette-tab:hover { 83 | background:#F9F9F9; 84 | } 85 | 86 | .malette-tab-selected { 87 | width: 51px; 88 | background: #FFF; 89 | } 90 | 91 | .malette-option-toggle { 92 | float: left; 93 | border: 1px solid #EEE; 94 | background: #EEE; 95 | border-radius: 1px; 96 | padding:5px; 97 | font-size: 0.8em; 98 | margin-right: 5px; 99 | padding-top:2px; 100 | padding-bottom: 2px; 101 | border-bottom: 1px solid #FFF; 102 | } 103 | 104 | .malette-option-toggle:hover { 105 | cursor: pointer; 106 | } 107 | 108 | .malette-option-toggle.disabled { 109 | color:#DDD; 110 | border:1px solid #EEE; 111 | } 112 | 113 | .malette-option-toggle-selected { 114 | background: #FFF; 115 | } 116 | 117 | #malette-color-palette, #malette-theme-palette { 118 | width:100%; 119 | margin:auto; 120 | margin-top: 5px; 121 | margin-top: 24px; 122 | overflow: hidden; 123 | } 124 | 125 | .malette-color-swatch { 126 | width: 26px; 127 | height: 17.5px; 128 | border: 1px solid #EEE; 129 | float: left; 130 | margin: 1px; 131 | } 132 | 133 | #malette-selected-color { 134 | font-size: 0.8em; 135 | margin-top: 2px; 136 | margin-bottom: 4px; 137 | width: 98%; 138 | background: #F8F8F8; 139 | padding: 5px; 140 | position: relative; 141 | padding-top: 4px; 142 | padding-bottom: 4px; 143 | } 144 | 145 | .malette-color-swatch-selected { 146 | width: 26px; 147 | height: 17px; 148 | border: 1px solid #EEE; 149 | margin: 1px; 150 | position: absolute; 151 | right: 3px; 152 | top: 2px; 153 | } 154 | 155 | .malette-color-swatch:hover { 156 | cursor: pointer; 157 | border:1px solid #CCC; 158 | } 159 | 160 | #malette-theme-palette { 161 | display: none; 162 | } 163 | 164 | .malette-theme-swatch { 165 | width: 28.2px; 166 | height: 17px; 167 | border: none; 168 | float: left; 169 | margin: 0px; 170 | pointer-events:none; 171 | } 172 | 173 | .malette-theme-row { 174 | overflow: hidden; 175 | border:1px solid #FFF; 176 | margin-bottom: 1px; 177 | } 178 | 179 | .malette-theme-row:hover { 180 | border:1px solid #999; 181 | cursor: pointer; 182 | } 183 | 184 | #malette-attr-select { 185 | margin-bottom: 5px; 186 | right: 0px; 187 | } 188 | 189 | #malette-stroke-slider { 190 | width:175px; 191 | float: left; 192 | margin-top:10px; 193 | margin-bottom: 1px; 194 | } 195 | 196 | #malette-stroke-width { 197 | width: 45px; 198 | float: right; 199 | font-size: 1.6rem; 200 | text-align: right; 201 | margin-right: 8px; 202 | } 203 | 204 | #malette-export-toggle-text { 205 | color:#888; 206 | } 207 | 208 | #malette-export-toggle-container { 209 | font-size: 0.8em; 210 | text-transform: none; 211 | display: inline-block; 212 | font-weight: 400; 213 | margin-top: 0px; 214 | position: absolute; 215 | right: 13px; 216 | bottom: 1px; 217 | } 218 | 219 | #malette-export-toggle-container input { 220 | margin-left:4px; 221 | cursor: pointer; 222 | } 223 | 224 | #malette-export-container { 225 | height: 200px; 226 | background-color: #FFF; 227 | position: absolute; 228 | margin-top: -3px; 229 | z-index: 1000; 230 | border-top: 1px solid #EEE; 231 | width: 300px; 232 | border-bottom-left-radius: 4px; 233 | border-bottom-right-radius: 4px; 234 | visibility: hidden; 235 | } 236 | 237 | #malette-export-header { 238 | border: 1px solid #EEE; 239 | width:100%; 240 | font-size: 0.8em; 241 | overflow: hidden; 242 | padding:5px; 243 | pointer-events:auto; 244 | } 245 | 246 | #malette-export-header input { 247 | margin-right: 3px; 248 | } 249 | 250 | #malette-export-header span { 251 | margin-right: 10px; 252 | } 253 | 254 | #export-code-block { 255 | width:95%; 256 | margin:auto; 257 | height: 148px; 258 | position: relative; 259 | display: block; 260 | margin-top: 10px; 261 | overflow: hidden; 262 | overflow-y:auto; 263 | pointer-events:auto; 264 | } 265 | 266 | 267 | /* size */ 268 | #malette-size-slider { 269 | margin-top: 45px; 270 | } 271 | 272 | #malette-graduated-palette { 273 | overflow: hidden; 274 | width:100%; 275 | margin-top:25px; 276 | } 277 | 278 | #malette-graduated-palette { 279 | display: none; 280 | } 281 | 282 | input[type=range] { 283 | -webkit-appearance: none; 284 | margin: 18px 0; 285 | width: 100%; 286 | } 287 | input[type=range]:focus { 288 | outline: none; 289 | } 290 | input[type=range]::-webkit-slider-runnable-track { 291 | width: 100%; 292 | height: 4px; 293 | cursor: pointer; 294 | animate: 0.2s; 295 | box-shadow: none; 296 | background: #3071a9; 297 | border-radius: 1.3px; 298 | border: 0.2px solid #010101; 299 | } 300 | input[type=range]::-webkit-slider-thumb { 301 | box-shadow:none; 302 | border: 1px solid #999; 303 | height: 13px; 304 | width: 13px; 305 | border-radius: 15px; 306 | background: #ffffff; 307 | cursor: pointer; 308 | -webkit-appearance: none; 309 | margin-top: -5px; 310 | } 311 | input[type=range]:focus::-webkit-slider-runnable-track { 312 | background: #367ebd; 313 | } 314 | input[type=range]::-moz-range-track { 315 | width: 100%; 316 | height: 4px; 317 | cursor: pointer; 318 | animate: 0.2s; 319 | box-shadow: none; 320 | background: #3071a9; 321 | border-radius: 1.3px; 322 | border: 0.2px solid #010101; 323 | } 324 | input[type=range]::-moz-range-thumb { 325 | box-shadow:none; 326 | border: 1px solid #999; 327 | height: 15px; 328 | width: 15px; 329 | border-radius: 15px; 330 | background: #ffffff; 331 | cursor: pointer; 332 | } 333 | input[type=range]::-ms-track { 334 | width: 100%; 335 | height: 4px; 336 | cursor: pointer; 337 | animate: 0.2s; 338 | box-shadow: none; 339 | background: #3071a9; 340 | border-radius: 1.3px; 341 | border: 0.2px solid #010101; 342 | color: transparent; 343 | } 344 | -------------------------------------------------------------------------------- /dist/polyfilled-malette.js: -------------------------------------------------------------------------------- 1 | (function(e,t,n,r){"use strict";function rt(e,t){for(var n=0,r=e.length;n>0),s="attached",o="detached",u="extends",a="ADDITION",f="MODIFICATION",l="REMOVAL",c="DOMAttrModified",h="DOMContentLoaded",p="DOMSubtreeModified",d="<",v="=",m=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,g=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],y=[],b=[],w="",E=t.documentElement,S=y.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},x=n.prototype,T=x.hasOwnProperty,N=x.isPrototypeOf,C=n.defineProperty,k=n.getOwnPropertyDescriptor,L=n.getOwnPropertyNames,A=n.getPrototypeOf,O=n.setPrototypeOf,M=!!n.__proto__,_=n.create||function vt(e){return e?(vt.prototype=e,new vt):this},D=O||(M?function(e,t){return e.__proto__=t,e}:L&&k?function(){function e(e,t){for(var n,r=L(t),i=0,s=r.length;iMalette\n
\n \n ";var container=document.getElementById(this.container);container.appendChild(stringToDom(template));var innerContainer=document.getElementById("malette");var content=document.getElementById("malette-content");if(this.options.title){header=document.createElement("div");innerContainer.appendChild(header).id="malette-title";header.innerHTML=this.options.title;document.getElementById("malette-content").style["margin-top"]="17px"}this._addTabs(innerContainer);this._constructColorRegion(content)}},{key:"_addTabs",value:function _addTabs(el){var self=this;var disabled=this.state.type==="point"?"":"disabled";var stroke=this.state.type!=="line"?"stroke":"line";var template="\n
\n
color
\n
size
\n
"+stroke+"
\n
opacity
\n
\n ";el.appendChild(stringToDom(template));this._classEventBuilder("click","malette-tab","_onTabClick")}},{key:"_addExporter",value:function _addExporter(){var self=this;var container=document.getElementById("malette-content");var checked=this._isShowJson?"checked":"";var template="\n
\n Show JSON\n \n
\n ";container.appendChild(stringToDom(template));var content=document.getElementById("malette");var cssChecked=this.exportFormat==="css"?"checked":"";var esriChecked=this.exportFormat==="esri-json"?"checked":"";var template="\n
\n
\n \n CSS\n \n Esri Renderer\n
\n \n
\n ";content.appendChild(stringToDom(template));this.selectedExportType=this.exportFormat;this._generateExportStyle(this.exportFormat);this._idEventBuilder("click","malette-export-toggle","_onToggleExportUI");this._classEventBuilder("click","export-type-toggle","_onExportTypeChange")}},{key:"_addColors",value:function _addColors(el,selectedColor){var swatch;var colors=colorSwatches;var colorPalette=this._createElement("div",el,"malette-color-palette","","");var selectedEl=this._createElement("div",colorPalette,"malette-selected-color","Selected color","");swatch=this._createElement("span",selectedEl,"malette-selected-swatch","","malette-color-swatch-selected");swatch.style.backgroundColor=selectedColor;colors.forEach(function(color,i){swatch=document.createElement("div");swatch.style.backgroundColor=color;colorPalette.appendChild(swatch).className="malette-color-swatch"})}},{key:"_addThemes",value:function _addThemes(el){var self=this;var swatch;var select=this._createAttributeSelect("malette-attr-select");this.themeColors=themeColors;var template="\n
\n
\n
\n ";el.appendChild(stringToDom(template));var palette=document.getElementById("malette-theme-palette");var colorPalette=document.getElementById("malette-theme-palette-inner");palette.insertBefore(select,colorPalette);this.themeColors.forEach(function(colors,i){var row=self._createElement("div",colorPalette,"malette-theme-row-"+i,"","malette-theme-row");colorPalette.appendChild(row);colors.forEach(function(color){swatch=document.createElement("div");swatch.style.backgroundColor=color;row.appendChild(swatch).className="malette-theme-swatch"})})}},{key:"_constructColorRegion",value:function _constructColorRegion(el){var self=this;el.innerHTML="";this._createElement("div",el,"malette-single-color-option","Single","malette-option-toggle malette-option-toggle-selected");if(this._hasApplicableFields===true){this._createElement("div",el,"malette-theme-color-option","Theme","malette-option-toggle")}else{this._createElement("div",el,"malette-theme-color-option","Theme","malette-option-toggle disabled")}var colorContainer=this._createElement("div",el,"malatte-color-container","","");this._addColors(colorContainer,this.style.symbol.color);this._classEventBuilder("click","malette-color-swatch","_onColorClick");this._idEventBuilder("click","malette-single-color-option","showSingleColorUI");if(this._hasApplicableFields===true){this._addThemes(colorContainer);this._idEventBuilder("click","malette-theme-color-option","showThemeUI");this._idEventBuilder("change","malette-attr-select","_onAttributeChange");this._classEventBuilder("click","malette-theme-row","_onThemeRowClick")}this._selectOption("malette-attr-select","selectedField");if(this.state._isTheme||this.style.visualVariables){if(this.style.visualVariables){this.state.selectedField=this.style.visualVariables[0].field;this._selectOption("malette-attr-select","selectedField")}self.showThemeUI()}}},{key:"_addGraduated",value:function _addGraduated(el){var select=this._createAttributeSelect();var graduatedPaletteContainer=this._createElement("div",el,"malette-graduated-palette","","");graduatedPaletteContainer.appendChild(select).id="malette-grad-attr-select"}},{key:"_constructSizePalette",value:function _constructSizePalette(el){var self=this;el.innerHTML="";this._createElement("div",el,"malette-single-size-option","Single","malette-option-toggle malette-option-toggle-selected");if(this._hasApplicableFields===true){this._createElement("div",el,"malette-graduated-size-option","Graduated","malette-option-toggle")}else{this._createElement("div",el,"malette-graduated-size-option","Graduated","malette-option-toggle disabled")}var size=this.style.symbol.size||8;var template='\n
\n \n
Radius: '+size+"px
\n
\n ";el.appendChild(stringToDom(template));this._idEventBuilder("input","malette-size-slider","_onSizeChanged");this._idEventBuilder("click","malette-single-size-option","showSingleSizeUI");if(this._hasApplicableFields===true){this._addGraduated(el);this._idEventBuilder("click","malette-graduated-size-option","showGraduatedUI");this._idEventBuilder("change","malette-grad-attr-select","_onGradAttributeChange")}this._selectOption("malette-grad-attr-select","selectedField");if(this.state._isGraduated||this.style.classBreakInfos){if(this.style.classBreakInfos){this.state.selectedField=this.style.field;this._selectOption("malette-grad-attr-select","selectedField")}self.showGraduatedUI()}}},{key:"_constructStrokePalette",value:function _constructStrokePalette(el){var self=this;el.innerHTML="";var width=this.state.type!=="line"?this.style.symbol.outline.width:this.style.symbol.width;width=width.toFixed(1);var template='\n \n
'+width+"px
\n ";el.appendChild(stringToDom(template));if(this.state.type!=="line"){this._addColors(el,this.style.symbol.outline.color)}this._idEventBuilder("input","malette-stroke-slider","_onStrokeWidthChanged");this._classEventBuilder("click","malette-color-swatch","_onStrokeColorClick")}},{key:"_constructOpacityPalette",value:function _constructOpacityPalette(el){var self=this;el.innerHTML="";var opacity=this.state.fillOpacity/255||.7;var slider=document.createElement("input");slider.type="range";slider.min=.1;slider.max=1;slider.step=.1;slider.value=opacity;el.appendChild(slider).id="malette-opacity-slider";var sizeNumber=this._createElement("div",el,"malette-opacity-number","Opacity: "+opacity*100+"%","");el.appendChild(sizeNumber);this._idEventBuilder("input","malette-opacity-slider","_onOpacityChanged")}},{key:"_createElement",value:function _createElement(type,parent,id,html,className){var el=document.createElement(type);parent.appendChild(el).id=id;el.innerHTML=html;document.getElementById(id).className=className;return el}},{key:"_createAttributeSelect",value:function _createAttributeSelect(id){var select=document.createElement("select");if(id)select.id=id;for(var i=0;i "+values[0]+" to "+values[1],classMaxValue:values[1]},{symbol:{color:rgbaToDojoColor(this.style.symbol.color),size:16,xoffset:0,yoffset:0,type:"esriSMS",style:"esriSMSCircle",outline:{color:rgbaToDojoColor(this.style.symbol.outline.color),width:this.style.symbol.outline.width,type:"esriSLS",style:"esriSLSSolid"}},label:"> "+values[1]+" to "+values[2],classMaxValue:values[2]},{symbol:{color:rgbaToDojoColor(this.style.symbol.color),size:22,xoffset:0,yoffset:0,type:"esriSMS",style:"esriSMSCircle",outline:{color:rgbaToDojoColor(this.style.symbol.outline.color),width:this.style.symbol.outline.width,type:"esriSLS",style:"esriSLSSolid"}},label:"> "+values[2]+" to "+values[3],classMaxValue:values[3]},{symbol:{color:rgbaToDojoColor(this.style.symbol.color),size:30,xoffset:0,yoffset:0,type:"esriSMS",style:"esriSMSCircle",outline:{color:rgbaToDojoColor(this.style.symbol.outline.color),width:this.style.symbol.outline.width,type:"esriSLS",style:"esriSLSSolid"}},label:"> "+values[3]+" to "+values[4],classMaxValue:values[4]}];this.updateStyle()}},{key:"clearTheme",value:function clearTheme(){this.style.visualVariables=null;this.updateStyle()}},{key:"clearGraduated",value:function clearGraduated(){this.style.type="simple";this.style.field=null;this.style.minValue=1;this.style.classBreakInfos=null;this.updateStyle()}},{key:"showThemeUI",value:function showThemeUI(){document.getElementById("malette-theme-palette").style.display="block";document.getElementById("malette-color-palette").style.display="none";document.getElementById("malette-single-color-option").className="malette-option-toggle";document.getElementById("malette-theme-color-option").className="malette-option-toggle malette-option-toggle-selected";this.state._isTheme=true;var index=document.getElementById("malette-attr-select").selectedIndex;var field=document.getElementById("malette-attr-select")[index].innerHTML;this.setTheme(null,field)}},{key:"showSingleColorUI",value:function showSingleColorUI(){document.getElementById("malette-theme-palette").style.display="none";document.getElementById("malette-color-palette").style.display="block";document.getElementById("malette-single-color-option").className="malette-option-toggle malette-option-toggle-selected";document.getElementById("malette-theme-color-option").className="malette-option-toggle";this.state._isTheme=false;this.clearTheme()}},{key:"showGraduatedUI",value:function showGraduatedUI(){document.getElementById("malette-graduated-palette").style.display="block";document.getElementById("malette-size-palette").style.display="none";document.getElementById("malette-single-size-option").className="malette-option-toggle";document.getElementById("malette-graduated-size-option").className="malette-option-toggle malette-option-toggle-selected";this.state._isGraduated=true;var index=document.getElementById("malette-grad-attr-select").selectedIndex;var field=document.getElementById("malette-grad-attr-select")[index].innerHTML;this.setGraduated(field)}},{key:"showSingleSizeUI",value:function showSingleSizeUI(){document.getElementById("malette-graduated-palette").style.display="none";document.getElementById("malette-size-palette").style.display="block";document.getElementById("malette-single-size-option").className="malette-option-toggle malette-option-toggle-selected";document.getElementById("malette-graduated-size-option").className="malette-option-toggle";this.state._isGraduated=false;this.clearGraduated()}},{key:"toggleExportUI",value:function toggleExportUI(e){if(e.target.checked===true){document.getElementById("malette-export-container").style.visibility="visible";document.getElementById("malette-export-toggle-text").innerHTML="Hide JSON";this._isShowJson=true}else{document.getElementById("malette-export-container").style.visibility="hidden";document.getElementById("malette-export-toggle-text").innerHTML="Show JSON";this._isShowJson=false}}},{key:"changeExportType",value:function changeExportType(e){var checkbox=document.getElementsByClassName("export-type-toggle");for(var i=0;i>>",this.style);this.emit("style-change",this.style)}else{if(this.exportFormat==="css"){this._toCss(function(css){css.layerId=self.state.layerId;css.defaultSymbol=css.symbol;self.emit("style-change",css)})}}this._generateExportStyle()}},{key:"_generateExportStyle",value:function _generateExportStyle(type){type=type||this.selectedExportType;if(type==="esri-json"){this.style.symbol.color=rgbaToDojoColor(this.style.symbol.color,this.state.fillOpacity);if(this.state.type!=="line"){this.style.symbol.outline.color=rgbaToDojoColor(this.style.symbol.outline.color)}document.getElementById("export-code-block").innerHTML=JSON.stringify(this.style,null,2)}else{if(type==="css"){this._toCss(function(css){document.getElementById("export-code-block").innerHTML=JSON.stringify(css,null,2)})}}}},{key:"on",value:function on(eventName,handler){this._handlers[eventName]=handler}},{key:"emit",value:function emit(eventName,val){if(this._handlers[eventName]){this._handlers[eventName](val)}}},{key:"_onColorClick",value:function _onColorClick(e){if(e.which===1&&!(e.metaKey||e.ctrlKey)){e.preventDefault();this.setSelectedColor(e.target.style.backgroundColor)}}},{key:"_onThemeRowClick",value:function _onThemeRowClick(e){e.preventDefault();this.setSelectedThemeRow(e)}},{key:"_onAttributeChange",value:function _onAttributeChange(e){var index=document.getElementById("malette-attr-select").selectedIndex;var field=document.getElementById("malette-attr-select")[index].innerHTML;this.state.selectedField=field;this.setTheme(null,field);if(this.state._isGraduated){this.setGraduated(field)}}},{key:"_onGradAttributeChange",value:function _onGradAttributeChange(e){var index=document.getElementById("malette-grad-attr-select").selectedIndex;var field=document.getElementById("malette-grad-attr-select")[index].innerHTML;this.state.selectedField=field;this.setGraduated(field);if(this.state._isTheme){this.setTheme(null,field)}}},{key:"_onStrokeColorClick",value:function _onStrokeColorClick(e){if(e.which===1&&!(e.metaKey||e.ctrlKey)){e.preventDefault();this.setSelectedStrokeColor(e.target.style.backgroundColor)}}},{key:"_onSizeChanged",value:function _onSizeChanged(e){e.preventDefault();this.setSelectedSize(e.target.value)}},{key:"_onStrokeWidthChanged",value:function _onStrokeWidthChanged(e){e.preventDefault();this.setStrokeWidth(e.target.value)}},{key:"_onOpacityChanged",value:function _onOpacityChanged(e){e.preventDefault();this.setOpacity(e.target.value)}},{key:"_onToggleExportUI",value:function _onToggleExportUI(e){this.toggleExportUI(e)}},{key:"_onExportTypeChange",value:function _onExportTypeChange(e){this.changeExportType(e)}},{key:"_onTabClick",value:function _onTabClick(e){if(e.target.classList.contains("disabled")){return}if(e.which===1&&!(e.metaKey||e.ctrlKey)){e.preventDefault();var els=document.getElementsByClassName("malette-tab");for(var i=0;i 80 |
Malette
81 |
82 | 83 | `; 84 | 85 | var container = document.getElementById( this.container ); 86 | 87 | container.appendChild(stringToDom(template)); 88 | 89 | var innerContainer = document.getElementById( 'malette' ); 90 | var content = document.getElementById( 'malette-content' ); 91 | 92 | if ( this.options.title ) { 93 | header = document.createElement( 'div' ); 94 | innerContainer.appendChild( header ).id = 'malette-title'; 95 | header.innerHTML = this.options.title; 96 | document.getElementById('malette-content').style['margin-top'] = '17px'; 97 | } 98 | 99 | this._addTabs(innerContainer); 100 | this._constructColorRegion(content); 101 | } 102 | 103 | /* 104 | * Builds the navigation tabs 105 | * Default: Color, Size 106 | * @param {String} el Builds UI for navigation tabs 107 | */ 108 | _addTabs (el) { 109 | var self = this; 110 | 111 | var disabled = ( this.state.type === 'point' ) ? '' : 'disabled'; 112 | var stroke = ( this.state.type !== 'line' ) ? 'stroke' : 'line'; 113 | 114 | var template = ` 115 |
116 |
color
117 |
size
118 |
${stroke}
119 |
opacity
120 |
121 | `; 122 | el.appendChild(stringToDom(template)); 123 | 124 | //toggle the tabs!! 125 | this._classEventBuilder('click', 'malette-tab', '_onTabClick' ); 126 | } 127 | 128 | /* 129 | * Exporter UI 130 | * 131 | * 132 | */ 133 | _addExporter () { 134 | var self = this; 135 | 136 | var container = document.getElementById('malette-content'); 137 | var checked = ( this._isShowJson ) ? 'checked' : ''; 138 | 139 | var template = ` 140 |
141 | Show JSON 142 | 143 |
144 | `; 145 | 146 | container.appendChild(stringToDom(template)); 147 | 148 | var content = document.getElementById('malette'); 149 | var cssChecked = ( this.exportFormat === 'css' ) ? 'checked' : ''; 150 | var esriChecked = ( this.exportFormat === 'esri-json' ) ? 'checked' : ''; 151 | var template = ` 152 |
153 |
154 | 155 | CSS 156 | 157 | Esri Renderer 158 |
159 | 160 |
161 | ` 162 | 163 | content.appendChild(stringToDom(template)); 164 | 165 | this.selectedExportType = this.exportFormat; 166 | this._generateExportStyle( this.exportFormat ); 167 | 168 | //toggle export UI event handler 169 | this._idEventBuilder('click', 'malette-export-toggle', '_onToggleExportUI' ); 170 | 171 | //export type toggle 172 | this._classEventBuilder('click', 'export-type-toggle', '_onExportTypeChange' ); 173 | } 174 | 175 | /* 176 | * Color swatch UI generator 177 | * Used both in fill and stroke color UI 178 | * @param {String} el parenet element 179 | * @param {String} selectedColor currently selected color rgba 180 | */ 181 | _addColors (el, selectedColor) { 182 | var swatch; 183 | var colors = colorSwatches; 184 | 185 | var colorPalette = this._createElement('div', el, 'malette-color-palette', '', ''); 186 | 187 | var selectedEl = this._createElement('div', colorPalette, 'malette-selected-color', 'Selected color', ''); 188 | swatch = this._createElement('span', selectedEl, 'malette-selected-swatch', '', 'malette-color-swatch-selected'); 189 | swatch.style.backgroundColor = selectedColor; 190 | 191 | colors.forEach(function(color, i) { 192 | swatch = document.createElement( 'div' ); 193 | swatch.style.backgroundColor = color; 194 | colorPalette.appendChild( swatch ).className = 'malette-color-swatch'; 195 | }); 196 | } 197 | 198 | /* 199 | * Color theme UI generator 200 | * creates color ramps 201 | * @param {String} el parenet element 202 | * @param {String} 203 | */ 204 | _addThemes (el) { 205 | var self = this; 206 | var swatch; 207 | 208 | var select = this._createAttributeSelect('malette-attr-select'); 209 | 210 | this.themeColors = themeColors; 211 | 212 | var template = ` 213 |
214 |
215 |
216 | `; 217 | el.appendChild(stringToDom(template)); 218 | 219 | var palette = document.getElementById( 'malette-theme-palette'); 220 | var colorPalette = document.getElementById( 'malette-theme-palette-inner' ); 221 | 222 | palette.insertBefore(select, colorPalette); 223 | 224 | this.themeColors.forEach(function(colors, i) { 225 | var row = self._createElement('div', colorPalette, 'malette-theme-row-'+i, '', 'malette-theme-row'); 226 | colorPalette.appendChild(row); 227 | 228 | colors.forEach(function(color) { 229 | swatch = document.createElement( 'div' ); 230 | swatch.style.backgroundColor = color; 231 | row.appendChild( swatch ).className = 'malette-theme-swatch'; 232 | }); 233 | 234 | }); 235 | } 236 | 237 | /* 238 | * Creates the color tab UI 239 | * @param {String} el Parent element to append the color UI 240 | * 241 | */ 242 | _constructColorRegion (el) { 243 | var self = this; 244 | 245 | el.innerHTML = ''; 246 | 247 | this._createElement('div', el, 'malette-single-color-option', 'Single', 'malette-option-toggle malette-option-toggle-selected'); 248 | 249 | if ( this._hasApplicableFields === true ) { 250 | this._createElement('div', el, 'malette-theme-color-option', 'Theme', 'malette-option-toggle'); 251 | } else { 252 | this._createElement('div', el, 'malette-theme-color-option', 'Theme', 'malette-option-toggle disabled'); 253 | } 254 | 255 | var colorContainer = this._createElement('div', el, 'malatte-color-container', '', ''); 256 | 257 | this._addColors(colorContainer, this.style.symbol.color); 258 | 259 | //Color swatch events 260 | this._classEventBuilder('click', 'malette-color-swatch', '_onColorClick' ); 261 | 262 | //show single colors event 263 | this._idEventBuilder('click', 'malette-single-color-option', 'showSingleColorUI' ); 264 | 265 | if ( this._hasApplicableFields === true ) { 266 | this._addThemes(colorContainer); 267 | 268 | //show ui theme event 269 | this._idEventBuilder('click', 'malette-theme-color-option', 'showThemeUI' ); 270 | 271 | //theme color change event 272 | this._idEventBuilder('change', 'malette-attr-select', '_onAttributeChange' ); 273 | 274 | //on theme click handler 275 | this._classEventBuilder('click', 'malette-theme-row', '_onThemeRowClick' ); 276 | } 277 | 278 | this._selectOption('malette-attr-select', 'selectedField'); 279 | 280 | if ( this.state._isTheme || this.style.visualVariables ) { 281 | if ( this.style.visualVariables ) { 282 | this.state.selectedField = this.style.visualVariables[ 0 ].field; 283 | this._selectOption('malette-attr-select', 'selectedField'); 284 | } 285 | self.showThemeUI(); 286 | } 287 | } 288 | 289 | /* 290 | * Creates UI for graduated symbols; only called if fields exist 291 | * @param {String} el Parent element to append the graduated ui to 292 | * 293 | */ 294 | _addGraduated (el) { 295 | var select = this._createAttributeSelect(); 296 | var graduatedPaletteContainer = this._createElement('div', el, 'malette-graduated-palette', '', ''); 297 | 298 | graduatedPaletteContainer.appendChild( select ).id = 'malette-grad-attr-select'; 299 | } 300 | 301 | /* 302 | * Creates the size tab UI 303 | * @param {String} el Parent element to append the size UI 304 | * 305 | */ 306 | _constructSizePalette (el) { 307 | var self = this; 308 | 309 | el.innerHTML = ''; 310 | 311 | this._createElement('div', el, 'malette-single-size-option', 'Single', 'malette-option-toggle malette-option-toggle-selected'); 312 | if ( this._hasApplicableFields === true ) { 313 | this._createElement('div', el, 'malette-graduated-size-option', 'Graduated', 'malette-option-toggle'); 314 | } else { 315 | this._createElement('div', el, 'malette-graduated-size-option', 'Graduated', 'malette-option-toggle disabled'); 316 | } 317 | 318 | var size = this.style.symbol.size || 8; 319 | 320 | var template = ` 321 |
322 | 323 |
Radius: ${size}px
324 |
325 | `; 326 | 327 | el.appendChild(stringToDom(template)); 328 | 329 | 330 | //size slide event handler 331 | this._idEventBuilder('input', 'malette-size-slider', '_onSizeChanged' ); 332 | 333 | //show single size event 334 | this._idEventBuilder('click', 'malette-single-size-option', 'showSingleSizeUI' ); 335 | 336 | if ( this._hasApplicableFields === true ) { 337 | this._addGraduated(el); 338 | 339 | //change to graduated size event 340 | this._idEventBuilder('click', 'malette-graduated-size-option', 'showGraduatedUI' ); 341 | 342 | //change grad attr 343 | this._idEventBuilder('change', 'malette-grad-attr-select', '_onGradAttributeChange' ); 344 | } 345 | 346 | this._selectOption('malette-grad-attr-select', 'selectedField'); 347 | 348 | if ( this.state._isGraduated || this.style.classBreakInfos ) { 349 | if ( this.style.classBreakInfos ) { 350 | this.state.selectedField = this.style.field; 351 | this._selectOption('malette-grad-attr-select', 'selectedField'); 352 | } 353 | self.showGraduatedUI(); 354 | } 355 | } 356 | 357 | /* 358 | * Creates the stroke tab UI 359 | * @param {String} el Parent element to append the stroke UI 360 | * 361 | */ 362 | _constructStrokePalette (el) { 363 | var self = this; 364 | el.innerHTML = ''; 365 | 366 | var width = ( this.state.type !== 'line' ) ? this.style.symbol.outline.width : this.style.symbol.width; 367 | width = width.toFixed(1); 368 | 369 | var template = ` 370 | 371 |
${width}px
372 | `; 373 | 374 | el.appendChild(stringToDom(template)); 375 | 376 | 377 | if ( this.state.type !== 'line' ) { 378 | this._addColors( el, this.style.symbol.outline.color ); 379 | } 380 | 381 | //stroke width change event 382 | this._idEventBuilder('input', 'malette-stroke-slider', '_onStrokeWidthChanged' ); 383 | 384 | //Color events 385 | this._classEventBuilder('click', 'malette-color-swatch', '_onStrokeColorClick' ); 386 | } 387 | 388 | /* 389 | * Creates the opacity tab UI 390 | * @param {String} el Parent element to append the opacity UI 391 | * 392 | */ 393 | _constructOpacityPalette (el) { 394 | var self = this; 395 | 396 | el.innerHTML = ''; 397 | 398 | var opacity = (this.state.fillOpacity / 255) || 0.7; 399 | 400 | var slider = document.createElement( 'input' ); 401 | slider.type = 'range'; 402 | slider.min = 0.1; 403 | slider.max = 1; 404 | slider.step = 0.1; 405 | slider.value = opacity; 406 | el.appendChild( slider ).id = 'malette-opacity-slider'; 407 | 408 | var sizeNumber = this._createElement('div', el, 'malette-opacity-number', 'Opacity: '+(opacity * 100)+'%', ''); 409 | el.appendChild( sizeNumber ); 410 | 411 | //opacity change event 412 | this._idEventBuilder('input', 'malette-opacity-slider', '_onOpacityChanged' ); 413 | } 414 | 415 | /* 416 | * creates a generic element, and appends to 'parent' div 417 | * @param {String} type of HTML element to create 418 | * @param {String} parent element to append created element to 419 | * @param {String} id of newly created element 420 | * @param {String} any text one wishes to append to new element 421 | * @param {String} optional classname for new element 422 | */ 423 | _createElement (type, parent, id, html, className ) { 424 | var el = document.createElement( type ); 425 | parent.appendChild( el ).id = id; 426 | el.innerHTML = html; 427 | document.getElementById( id ).className = className; 428 | 429 | return el; 430 | } 431 | 432 | /* 433 | * Builds a generic attribute select drop down 434 | * Requires this.options.fields be defined; 435 | * 436 | */ 437 | _createAttributeSelect (id) { 438 | var select = document.createElement('select'); 439 | if ( id ) select.id = id; 440 | 441 | for (var i = 0; i < this.options.fields.length; i++) { 442 | if ( this.options.fields[i].type === 'esriFieldTypeDouble' || this.options.fields[i].type === 'esriFieldTypeInteger' || this.options.fields[i].type === 'esriFieldTypeSingle' || this.options.fields[i].type === 'esriFieldTypeSmallInteger' ) { 443 | if ( this.options.fields[i].statistics && this.options.fields[i].statistics.max ) { 444 | var option = document.createElement('option'); 445 | option.setAttribute('value', this.options.fields[i].type); 446 | option.setAttribute('id', this.options.fields[i].name.replace(/ /g, '')); 447 | option.appendChild(document.createTextNode(this.options.fields[i].name)); 448 | select.appendChild(option); 449 | } 450 | } 451 | } 452 | 453 | return select; 454 | } 455 | 456 | /* 457 | * Programatically select an option in dropdown 458 | * @param {String} id - id of select element 459 | * @param {String} field - value of select option 460 | * 461 | */ 462 | _selectOption (id, field) { 463 | if ( this.state[ field ] ) { 464 | var index = 0; 465 | var x = document.getElementById( id ); 466 | for (var i = 0; i < x.length; i++) { 467 | if ( x.options[i].text === this.state[ field ].replace(/ /g, '') ) { 468 | index = x.options[i].index; 469 | } 470 | } 471 | document.getElementById( id ).getElementsByTagName('option')[index].selected = 'selected'; 472 | } 473 | } 474 | 475 | /* 476 | * Checks if we can use any of the fields passed in as options 477 | * 478 | * 479 | */ 480 | _getApplicableFields () { 481 | var isApplicable = false; 482 | 483 | if ( this.options.fields ) { 484 | for (var i = 0; i < this.options.fields.length; i++) { 485 | if ( this.options.fields[i].type === 'esriFieldTypeDouble' || this.options.fields[i].type === 'esriFieldTypeInteger' || this.options.fields[i].type === 'esriFieldTypeSingle' || this.options.fields[i].type === 'esriFieldTypeSmallInteger' ) { 486 | if ( this.options.fields[i].statistics && this.options.fields[i].statistics.max ) { 487 | isApplicable = true; 488 | } 489 | } 490 | } 491 | } 492 | 493 | return isApplicable; 494 | } 495 | 496 | /* 497 | * Event builder for classes 498 | * @param {String} eventName, type of event 499 | * @param {String} className, what element class are we binding to 500 | * @param {String} fnName, what action (function to call) when event fires 501 | * 502 | */ 503 | _classEventBuilder (eventName, className, fnName ) { 504 | var self = this; 505 | 506 | var linkEl = document.getElementsByClassName( className ); 507 | for(var i=0;i "+values[0]+" to "+values[1], 709 | "classMaxValue": values[1] 710 | }, 711 | { 712 | "symbol": { 713 | "color": rgbaToDojoColor(this.style.symbol.color), 714 | "size": 16, 715 | "xoffset": 0, 716 | "yoffset": 0, 717 | "type": "esriSMS", 718 | "style": "esriSMSCircle", 719 | "outline": { 720 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 721 | "width": this.style.symbol.outline.width, 722 | "type": "esriSLS", 723 | "style": "esriSLSSolid" 724 | } 725 | }, 726 | "label": "> "+values[1]+" to "+values[2], 727 | "classMaxValue": values[2] 728 | }, 729 | { 730 | "symbol": { 731 | "color": rgbaToDojoColor(this.style.symbol.color), 732 | "size": 22, 733 | "xoffset": 0, 734 | "yoffset": 0, 735 | "type": "esriSMS", 736 | "style": "esriSMSCircle", 737 | "outline": { 738 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 739 | "width": this.style.symbol.outline.width, 740 | "type": "esriSLS", 741 | "style": "esriSLSSolid" 742 | } 743 | }, 744 | "label": "> "+values[2]+" to "+values[3], 745 | "classMaxValue": values[3] 746 | }, 747 | { 748 | "symbol": { 749 | "color": rgbaToDojoColor(this.style.symbol.color), 750 | "size": 30, 751 | "xoffset": 0, 752 | "yoffset": 0, 753 | "type": "esriSMS", 754 | "style": "esriSMSCircle", 755 | "outline": { 756 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 757 | "width": this.style.symbol.outline.width, 758 | "type": "esriSLS", 759 | "style": "esriSLSSolid" 760 | } 761 | }, 762 | "label": "> "+values[3]+" to "+values[4], 763 | "classMaxValue": values[4] 764 | } 765 | ]; 766 | 767 | this.updateStyle(); 768 | } 769 | 770 | /* 771 | * Set to single, remove and destroy theme 772 | * 773 | * 774 | */ 775 | clearTheme () { 776 | this.style.visualVariables = null; 777 | this.updateStyle(); 778 | } 779 | 780 | /* 781 | * 782 | * Clear graduated styles 783 | * 784 | */ 785 | clearGraduated () { 786 | this.style.type = "simple"; 787 | this.style.field = null; 788 | this.style.minValue = 1; 789 | this.style.classBreakInfos = null; 790 | this.updateStyle(); 791 | } 792 | 793 | /* 794 | * Crazy UI handlers 795 | * 796 | */ 797 | showThemeUI () { 798 | document.getElementById('malette-theme-palette').style.display = 'block'; 799 | document.getElementById('malette-color-palette').style.display = 'none'; 800 | document.getElementById('malette-single-color-option').className = 'malette-option-toggle'; 801 | document.getElementById('malette-theme-color-option').className = 'malette-option-toggle malette-option-toggle-selected'; 802 | this.state._isTheme = true; 803 | 804 | var index = document.getElementById('malette-attr-select').selectedIndex; 805 | var field = document.getElementById('malette-attr-select')[index].innerHTML; 806 | 807 | this.setTheme(null, field); 808 | } 809 | 810 | showSingleColorUI () { 811 | document.getElementById('malette-theme-palette').style.display = 'none'; 812 | document.getElementById('malette-color-palette').style.display = 'block'; 813 | document.getElementById('malette-single-color-option').className = 'malette-option-toggle malette-option-toggle-selected'; 814 | document.getElementById('malette-theme-color-option').className = 'malette-option-toggle'; 815 | this.state._isTheme = false; 816 | this.clearTheme(); 817 | } 818 | 819 | showGraduatedUI () { 820 | document.getElementById('malette-graduated-palette').style.display = 'block'; 821 | document.getElementById('malette-size-palette').style.display = 'none'; 822 | document.getElementById('malette-single-size-option').className = 'malette-option-toggle'; 823 | document.getElementById('malette-graduated-size-option').className = 'malette-option-toggle malette-option-toggle-selected'; 824 | this.state._isGraduated = true; 825 | 826 | var index = document.getElementById('malette-grad-attr-select').selectedIndex; 827 | var field = document.getElementById('malette-grad-attr-select')[index].innerHTML; 828 | 829 | this.setGraduated(field); 830 | } 831 | 832 | showSingleSizeUI () { 833 | document.getElementById('malette-graduated-palette').style.display = 'none'; 834 | document.getElementById('malette-size-palette').style.display = 'block'; 835 | document.getElementById('malette-single-size-option').className = 'malette-option-toggle malette-option-toggle-selected'; 836 | document.getElementById('malette-graduated-size-option').className = 'malette-option-toggle'; 837 | this.state._isGraduated = false; 838 | this.clearGraduated(); 839 | } 840 | 841 | toggleExportUI (e) { 842 | if ( e.target.checked === true ) { 843 | document.getElementById("malette-export-container").style.visibility = "visible"; 844 | document.getElementById('malette-export-toggle-text').innerHTML = 'Hide JSON'; 845 | this._isShowJson = true; 846 | } else { 847 | document.getElementById("malette-export-container").style.visibility = "hidden"; 848 | document.getElementById('malette-export-toggle-text').innerHTML = 'Show JSON'; 849 | this._isShowJson = false; 850 | } 851 | } 852 | 853 | /* 854 | * Logic for toggling the export type in the Export UI 855 | * 856 | * 857 | */ 858 | changeExportType (e) { 859 | 860 | var checkbox = document.getElementsByClassName( 'export-type-toggle' ); 861 | for(var i=0;i>>', this.style); 1041 | this.emit( 'style-change', this.style); 1042 | } else { 1043 | 1044 | if ( this.exportFormat === 'css' ) { 1045 | this._toCss(function(css) { 1046 | css.layerId = self.state.layerId; 1047 | css.defaultSymbol = css.symbol; 1048 | self.emit( 'style-change', css ); 1049 | }); 1050 | } 1051 | 1052 | } 1053 | 1054 | this._generateExportStyle(); 1055 | } 1056 | 1057 | _generateExportStyle (type) { 1058 | //codeBox.innerHTML = JSON.stringify(this.style, null, 2); 1059 | type = type || this.selectedExportType; 1060 | 1061 | if ( type === 'esri-json' ) { 1062 | 1063 | this.style.symbol.color = rgbaToDojoColor( this.style.symbol.color, this.state.fillOpacity ); //change colors BACK to dojo :( 1064 | 1065 | if ( this.state.type !== 'line' ) { 1066 | this.style.symbol.outline.color = rgbaToDojoColor( this.style.symbol.outline.color ); 1067 | } 1068 | 1069 | document.getElementById('export-code-block').innerHTML = JSON.stringify(this.style, null, 2); 1070 | } else { 1071 | 1072 | if ( type === 'css' ) { 1073 | this._toCss(function(css) { 1074 | document.getElementById('export-code-block').innerHTML = JSON.stringify(css, null, 2); 1075 | }); 1076 | } 1077 | 1078 | } 1079 | } 1080 | 1081 | /************* EVENTS **************/ 1082 | 1083 | /* 1084 | * Register Malette events 1085 | * 1086 | */ 1087 | on (eventName, handler){ 1088 | this._handlers[ eventName ] = handler; 1089 | } 1090 | 1091 | // trigger callback 1092 | emit (eventName, val) { 1093 | if (this._handlers[ eventName ]){ 1094 | this._handlers[ eventName ](val); 1095 | } 1096 | } 1097 | 1098 | _onColorClick (e) { 1099 | if( e.which === 1 && !(e.metaKey || e.ctrlKey)){ 1100 | e.preventDefault(); 1101 | this.setSelectedColor(e.target.style.backgroundColor); 1102 | } 1103 | } 1104 | 1105 | _onThemeRowClick (e) { 1106 | e.preventDefault(); 1107 | this.setSelectedThemeRow(e); 1108 | } 1109 | 1110 | _onAttributeChange (e) { 1111 | var index = document.getElementById('malette-attr-select').selectedIndex; 1112 | var field = document.getElementById('malette-attr-select')[index].innerHTML; 1113 | this.state.selectedField = field; 1114 | this.setTheme(null, field); 1115 | 1116 | if ( this.state._isGraduated ) { 1117 | this.setGraduated(field); 1118 | } 1119 | } 1120 | 1121 | _onGradAttributeChange (e) { 1122 | var index = document.getElementById('malette-grad-attr-select').selectedIndex; 1123 | var field = document.getElementById('malette-grad-attr-select')[index].innerHTML; 1124 | this.state.selectedField = field; 1125 | this.setGraduated(field); 1126 | 1127 | if ( this.state._isTheme ) { 1128 | this.setTheme(null, field); 1129 | } 1130 | } 1131 | 1132 | _onStrokeColorClick (e) { 1133 | if( e.which === 1 && !(e.metaKey || e.ctrlKey)){ 1134 | e.preventDefault(); 1135 | this.setSelectedStrokeColor(e.target.style.backgroundColor); 1136 | } 1137 | } 1138 | 1139 | _onSizeChanged (e) { 1140 | e.preventDefault(); 1141 | this.setSelectedSize(e.target.value); 1142 | } 1143 | 1144 | _onStrokeWidthChanged (e) { 1145 | e.preventDefault(); 1146 | this.setStrokeWidth(e.target.value); 1147 | } 1148 | 1149 | _onOpacityChanged (e) { 1150 | e.preventDefault(); 1151 | this.setOpacity(e.target.value); 1152 | } 1153 | 1154 | _onToggleExportUI (e) { 1155 | this.toggleExportUI(e); 1156 | } 1157 | 1158 | _onExportTypeChange (e) { 1159 | //e.preventDefault(); 1160 | this.changeExportType(e); 1161 | } 1162 | 1163 | _onTabClick (e) { 1164 | 1165 | if ( e.target.classList.contains('disabled') ) { 1166 | return; 1167 | } 1168 | 1169 | if( e.which === 1 && !(e.metaKey || e.ctrlKey)){ 1170 | e.preventDefault(); 1171 | 1172 | var els = document.getElementsByClassName( 'malette-tab' ); 1173 | for(var i=0;i\n
Malette
\n
\n \n '; 163 | 164 | var container = document.getElementById(this.container); 165 | 166 | container.appendChild(stringToDom(template)); 167 | 168 | var innerContainer = document.getElementById('malette'); 169 | var content = document.getElementById('malette-content'); 170 | 171 | if (this.options.title) { 172 | header = document.createElement('div'); 173 | innerContainer.appendChild(header).id = 'malette-title'; 174 | header.innerHTML = this.options.title; 175 | document.getElementById('malette-content').style['margin-top'] = '17px'; 176 | } 177 | 178 | this._addTabs(innerContainer); 179 | this._constructColorRegion(content); 180 | } 181 | 182 | /* 183 | * Builds the navigation tabs 184 | * Default: Color, Size 185 | * @param {String} el Builds UI for navigation tabs 186 | */ 187 | }, { 188 | key: '_addTabs', 189 | value: function _addTabs(el) { 190 | var self = this; 191 | 192 | var disabled = this.state.type === 'point' ? '' : 'disabled'; 193 | var stroke = this.state.type !== 'line' ? 'stroke' : 'line'; 194 | 195 | var template = '\n
\n
color
\n
size
\n
' + stroke + '
\n
opacity
\n
\n '; 196 | el.appendChild(stringToDom(template)); 197 | 198 | //toggle the tabs!! 199 | this._classEventBuilder('click', 'malette-tab', '_onTabClick'); 200 | } 201 | 202 | /* 203 | * Exporter UI 204 | * 205 | * 206 | */ 207 | }, { 208 | key: '_addExporter', 209 | value: function _addExporter() { 210 | var self = this; 211 | 212 | var container = document.getElementById('malette-content'); 213 | var checked = this._isShowJson ? 'checked' : ''; 214 | 215 | var template = '\n
\n Show JSON\n \n
\n '; 216 | 217 | container.appendChild(stringToDom(template)); 218 | 219 | var content = document.getElementById('malette'); 220 | var cssChecked = this.exportFormat === 'css' ? 'checked' : ''; 221 | var esriChecked = this.exportFormat === 'esri-json' ? 'checked' : ''; 222 | var template = '\n
\n
\n \n CSS\n \n Esri Renderer\n
\n \n
\n '; 223 | 224 | content.appendChild(stringToDom(template)); 225 | 226 | this.selectedExportType = this.exportFormat; 227 | this._generateExportStyle(this.exportFormat); 228 | 229 | //toggle export UI event handler 230 | this._idEventBuilder('click', 'malette-export-toggle', '_onToggleExportUI'); 231 | 232 | //export type toggle 233 | this._classEventBuilder('click', 'export-type-toggle', '_onExportTypeChange'); 234 | } 235 | 236 | /* 237 | * Color swatch UI generator 238 | * Used both in fill and stroke color UI 239 | * @param {String} el parenet element 240 | * @param {String} selectedColor currently selected color rgba 241 | */ 242 | }, { 243 | key: '_addColors', 244 | value: function _addColors(el, selectedColor) { 245 | var swatch; 246 | var colors = colorSwatches; 247 | 248 | var colorPalette = this._createElement('div', el, 'malette-color-palette', '', ''); 249 | 250 | var selectedEl = this._createElement('div', colorPalette, 'malette-selected-color', 'Selected color', ''); 251 | swatch = this._createElement('span', selectedEl, 'malette-selected-swatch', '', 'malette-color-swatch-selected'); 252 | swatch.style.backgroundColor = selectedColor; 253 | 254 | colors.forEach(function (color, i) { 255 | swatch = document.createElement('div'); 256 | swatch.style.backgroundColor = color; 257 | colorPalette.appendChild(swatch).className = 'malette-color-swatch'; 258 | }); 259 | } 260 | 261 | /* 262 | * Color theme UI generator 263 | * creates color ramps 264 | * @param {String} el parenet element 265 | * @param {String} 266 | */ 267 | }, { 268 | key: '_addThemes', 269 | value: function _addThemes(el) { 270 | var self = this; 271 | var swatch; 272 | 273 | var select = this._createAttributeSelect('malette-attr-select'); 274 | 275 | this.themeColors = themeColors; 276 | 277 | var template = '\n
\n
\n
\n '; 278 | el.appendChild(stringToDom(template)); 279 | 280 | var palette = document.getElementById('malette-theme-palette'); 281 | var colorPalette = document.getElementById('malette-theme-palette-inner'); 282 | 283 | palette.insertBefore(select, colorPalette); 284 | 285 | this.themeColors.forEach(function (colors, i) { 286 | var row = self._createElement('div', colorPalette, 'malette-theme-row-' + i, '', 'malette-theme-row'); 287 | colorPalette.appendChild(row); 288 | 289 | colors.forEach(function (color) { 290 | swatch = document.createElement('div'); 291 | swatch.style.backgroundColor = color; 292 | row.appendChild(swatch).className = 'malette-theme-swatch'; 293 | }); 294 | }); 295 | } 296 | 297 | /* 298 | * Creates the color tab UI 299 | * @param {String} el Parent element to append the color UI 300 | * 301 | */ 302 | }, { 303 | key: '_constructColorRegion', 304 | value: function _constructColorRegion(el) { 305 | var self = this; 306 | 307 | el.innerHTML = ''; 308 | 309 | this._createElement('div', el, 'malette-single-color-option', 'Single', 'malette-option-toggle malette-option-toggle-selected'); 310 | 311 | if (this._hasApplicableFields === true) { 312 | this._createElement('div', el, 'malette-theme-color-option', 'Theme', 'malette-option-toggle'); 313 | } else { 314 | this._createElement('div', el, 'malette-theme-color-option', 'Theme', 'malette-option-toggle disabled'); 315 | } 316 | 317 | var colorContainer = this._createElement('div', el, 'malatte-color-container', '', ''); 318 | 319 | this._addColors(colorContainer, this.style.symbol.color); 320 | 321 | //Color swatch events 322 | this._classEventBuilder('click', 'malette-color-swatch', '_onColorClick'); 323 | 324 | //show single colors event 325 | this._idEventBuilder('click', 'malette-single-color-option', 'showSingleColorUI'); 326 | 327 | if (this._hasApplicableFields === true) { 328 | this._addThemes(colorContainer); 329 | 330 | //show ui theme event 331 | this._idEventBuilder('click', 'malette-theme-color-option', 'showThemeUI'); 332 | 333 | //theme color change event 334 | this._idEventBuilder('change', 'malette-attr-select', '_onAttributeChange'); 335 | 336 | //on theme click handler 337 | this._classEventBuilder('click', 'malette-theme-row', '_onThemeRowClick'); 338 | } 339 | 340 | this._selectOption('malette-attr-select', 'selectedField'); 341 | 342 | if (this.state._isTheme || this.style.visualVariables) { 343 | if (this.style.visualVariables) { 344 | this.state.selectedField = this.style.visualVariables[0].field; 345 | this._selectOption('malette-attr-select', 'selectedField'); 346 | } 347 | self.showThemeUI(); 348 | } 349 | } 350 | 351 | /* 352 | * Creates UI for graduated symbols; only called if fields exist 353 | * @param {String} el Parent element to append the graduated ui to 354 | * 355 | */ 356 | }, { 357 | key: '_addGraduated', 358 | value: function _addGraduated(el) { 359 | var select = this._createAttributeSelect(); 360 | var graduatedPaletteContainer = this._createElement('div', el, 'malette-graduated-palette', '', ''); 361 | 362 | graduatedPaletteContainer.appendChild(select).id = 'malette-grad-attr-select'; 363 | } 364 | 365 | /* 366 | * Creates the size tab UI 367 | * @param {String} el Parent element to append the size UI 368 | * 369 | */ 370 | }, { 371 | key: '_constructSizePalette', 372 | value: function _constructSizePalette(el) { 373 | var self = this; 374 | 375 | el.innerHTML = ''; 376 | 377 | this._createElement('div', el, 'malette-single-size-option', 'Single', 'malette-option-toggle malette-option-toggle-selected'); 378 | if (this._hasApplicableFields === true) { 379 | this._createElement('div', el, 'malette-graduated-size-option', 'Graduated', 'malette-option-toggle'); 380 | } else { 381 | this._createElement('div', el, 'malette-graduated-size-option', 'Graduated', 'malette-option-toggle disabled'); 382 | } 383 | 384 | var size = this.style.symbol.size || 8; 385 | 386 | var template = '\n
\n \n
Radius: ' + size + 'px
\n
\n '; 387 | 388 | el.appendChild(stringToDom(template)); 389 | 390 | //size slide event handler 391 | this._idEventBuilder('input', 'malette-size-slider', '_onSizeChanged'); 392 | 393 | //show single size event 394 | this._idEventBuilder('click', 'malette-single-size-option', 'showSingleSizeUI'); 395 | 396 | if (this._hasApplicableFields === true) { 397 | this._addGraduated(el); 398 | 399 | //change to graduated size event 400 | this._idEventBuilder('click', 'malette-graduated-size-option', 'showGraduatedUI'); 401 | 402 | //change grad attr 403 | this._idEventBuilder('change', 'malette-grad-attr-select', '_onGradAttributeChange'); 404 | } 405 | 406 | this._selectOption('malette-grad-attr-select', 'selectedField'); 407 | 408 | if (this.state._isGraduated || this.style.classBreakInfos) { 409 | if (this.style.classBreakInfos) { 410 | this.state.selectedField = this.style.field; 411 | this._selectOption('malette-grad-attr-select', 'selectedField'); 412 | } 413 | self.showGraduatedUI(); 414 | } 415 | } 416 | 417 | /* 418 | * Creates the stroke tab UI 419 | * @param {String} el Parent element to append the stroke UI 420 | * 421 | */ 422 | }, { 423 | key: '_constructStrokePalette', 424 | value: function _constructStrokePalette(el) { 425 | var self = this; 426 | el.innerHTML = ''; 427 | 428 | var width = this.state.type !== 'line' ? this.style.symbol.outline.width : this.style.symbol.width; 429 | width = width.toFixed(1); 430 | 431 | var template = '\n \n
' + width + 'px
\n '; 432 | 433 | el.appendChild(stringToDom(template)); 434 | 435 | if (this.state.type !== 'line') { 436 | this._addColors(el, this.style.symbol.outline.color); 437 | } 438 | 439 | //stroke width change event 440 | this._idEventBuilder('input', 'malette-stroke-slider', '_onStrokeWidthChanged'); 441 | 442 | //Color events 443 | this._classEventBuilder('click', 'malette-color-swatch', '_onStrokeColorClick'); 444 | } 445 | 446 | /* 447 | * Creates the opacity tab UI 448 | * @param {String} el Parent element to append the opacity UI 449 | * 450 | */ 451 | }, { 452 | key: '_constructOpacityPalette', 453 | value: function _constructOpacityPalette(el) { 454 | var self = this; 455 | 456 | el.innerHTML = ''; 457 | 458 | var opacity = this.state.fillOpacity / 255 || 0.7; 459 | 460 | var slider = document.createElement('input'); 461 | slider.type = 'range'; 462 | slider.min = 0.1; 463 | slider.max = 1; 464 | slider.step = 0.1; 465 | slider.value = opacity; 466 | el.appendChild(slider).id = 'malette-opacity-slider'; 467 | 468 | var sizeNumber = this._createElement('div', el, 'malette-opacity-number', 'Opacity: ' + opacity * 100 + '%', ''); 469 | el.appendChild(sizeNumber); 470 | 471 | //opacity change event 472 | this._idEventBuilder('input', 'malette-opacity-slider', '_onOpacityChanged'); 473 | } 474 | 475 | /* 476 | * creates a generic element, and appends to 'parent' div 477 | * @param {String} type of HTML element to create 478 | * @param {String} parent element to append created element to 479 | * @param {String} id of newly created element 480 | * @param {String} any text one wishes to append to new element 481 | * @param {String} optional classname for new element 482 | */ 483 | }, { 484 | key: '_createElement', 485 | value: function _createElement(type, parent, id, html, className) { 486 | var el = document.createElement(type); 487 | parent.appendChild(el).id = id; 488 | el.innerHTML = html; 489 | document.getElementById(id).className = className; 490 | 491 | return el; 492 | } 493 | 494 | /* 495 | * Builds a generic attribute select drop down 496 | * Requires this.options.fields be defined; 497 | * 498 | */ 499 | }, { 500 | key: '_createAttributeSelect', 501 | value: function _createAttributeSelect(id) { 502 | var select = document.createElement('select'); 503 | if (id) select.id = id; 504 | 505 | for (var i = 0; i < this.options.fields.length; i++) { 506 | if (this.options.fields[i].type === 'esriFieldTypeDouble' || this.options.fields[i].type === 'esriFieldTypeInteger' || this.options.fields[i].type === 'esriFieldTypeSingle' || this.options.fields[i].type === 'esriFieldTypeSmallInteger') { 507 | if (this.options.fields[i].statistics && this.options.fields[i].statistics.max) { 508 | var option = document.createElement('option'); 509 | option.setAttribute('value', this.options.fields[i].type); 510 | option.setAttribute('id', this.options.fields[i].name.replace(/ /g, '')); 511 | option.appendChild(document.createTextNode(this.options.fields[i].name)); 512 | select.appendChild(option); 513 | } 514 | } 515 | } 516 | 517 | return select; 518 | } 519 | 520 | /* 521 | * Programatically select an option in dropdown 522 | * @param {String} id - id of select element 523 | * @param {String} field - value of select option 524 | * 525 | */ 526 | }, { 527 | key: '_selectOption', 528 | value: function _selectOption(id, field) { 529 | if (this.state[field]) { 530 | var index = 0; 531 | var x = document.getElementById(id); 532 | for (var i = 0; i < x.length; i++) { 533 | if (x.options[i].text === this.state[field].replace(/ /g, '')) { 534 | index = x.options[i].index; 535 | } 536 | } 537 | document.getElementById(id).getElementsByTagName('option')[index].selected = 'selected'; 538 | } 539 | } 540 | 541 | /* 542 | * Checks if we can use any of the fields passed in as options 543 | * 544 | * 545 | */ 546 | }, { 547 | key: '_getApplicableFields', 548 | value: function _getApplicableFields() { 549 | var isApplicable = false; 550 | 551 | if (this.options.fields) { 552 | for (var i = 0; i < this.options.fields.length; i++) { 553 | if (this.options.fields[i].type === 'esriFieldTypeDouble' || this.options.fields[i].type === 'esriFieldTypeInteger' || this.options.fields[i].type === 'esriFieldTypeSingle' || this.options.fields[i].type === 'esriFieldTypeSmallInteger') { 554 | if (this.options.fields[i].statistics && this.options.fields[i].statistics.max) { 555 | isApplicable = true; 556 | } 557 | } 558 | } 559 | } 560 | 561 | return isApplicable; 562 | } 563 | 564 | /* 565 | * Event builder for classes 566 | * @param {String} eventName, type of event 567 | * @param {String} className, what element class are we binding to 568 | * @param {String} fnName, what action (function to call) when event fires 569 | * 570 | */ 571 | }, { 572 | key: '_classEventBuilder', 573 | value: function _classEventBuilder(eventName, className, fnName) { 574 | var self = this; 575 | 576 | var linkEl = document.getElementsByClassName(className); 577 | for (var i = 0; i < linkEl.length; i++) { 578 | if (linkEl[i].addEventListener) { 579 | linkEl[i].addEventListener(eventName, function (e) { 580 | self[fnName].call(self, e); 581 | }); 582 | } else { 583 | linkEl[i].attachEvent('on' + eventName, function (e) { 584 | self[fnName].call(self, e); 585 | }); 586 | } 587 | } 588 | } 589 | 590 | /* 591 | * Event builder for ids 592 | * @param {String} eventName, type of event 593 | * @param {String} id, what element are we binding to 594 | * @param {String} fnName, what action (function to call) when event fires 595 | * 596 | */ 597 | }, { 598 | key: '_idEventBuilder', 599 | value: function _idEventBuilder(eventName, id, fnName) { 600 | var self = this; 601 | 602 | var linkEl = document.getElementById(id); 603 | if (linkEl.addEventListener) { 604 | linkEl.addEventListener(eventName, function (e) { 605 | self[fnName].call(self, e); 606 | }); 607 | } else { 608 | linkEl.attachEvent('on' + eventName, function (e) { 609 | self[fnName].call(self, e); 610 | }); 611 | } 612 | } 613 | 614 | /************* METHODS **************/ 615 | 616 | /* 617 | * Self distruct 618 | * Really only called from external resources 619 | * 620 | */ 621 | }, { 622 | key: 'destroy', 623 | value: function destroy() { 624 | var parent = document.getElementById(this.container); 625 | parent.removeChild(document.getElementById('malette')); 626 | } 627 | 628 | /* 629 | * Change tab 630 | * 631 | * 632 | */ 633 | }, { 634 | key: 'changeTab', 635 | value: function changeTab(tab) { 636 | var el = document.getElementById('malette-content'); 637 | 638 | switch (tab) { 639 | case 'color': 640 | this._constructColorRegion(el); 641 | break; 642 | case 'size': 643 | this._constructSizePalette(el); 644 | break; 645 | case 'stroke': 646 | this._constructStrokePalette(el); 647 | break; 648 | case 'line': 649 | this._constructStrokePalette(el); 650 | break; 651 | case 'opacity': 652 | this._constructOpacityPalette(el); 653 | break; 654 | default: 655 | this._constructColorRegion(el); 656 | } 657 | 658 | if (this.options.exportStyle) { 659 | this._addExporter(); 660 | } 661 | } 662 | 663 | /* 664 | * Sets thematic styles 665 | * @param {Array} ramp (optional) color ramp 666 | * @param {String} field Field being styled 667 | * 668 | */ 669 | }, { 670 | key: 'setTheme', 671 | value: function setTheme(ramp, field) { 672 | var self = this; 673 | 674 | this.state.selectedField = field ? field : this.state.selectedField; 675 | 676 | //default theme map 677 | if (!ramp && !this.selectedRamp) { 678 | ramp = [[255, 247, 251, this.state.fillOpacity], [236, 226, 240, this.state.fillOpacity], [208, 209, 230, this.state.fillOpacity], [166, 189, 219, this.state.fillOpacity], [103, 169, 207, this.state.fillOpacity], [54, 144, 192, this.state.fillOpacity], [2, 129, 138, 130], [1, 100, 80, this.state.fillOpacity]]; 679 | } else if (!ramp && this.selectedRamp) { 680 | ramp = this.selectedRamp; 681 | } 682 | 683 | this.selectedRamp = ramp ? ramp : this.selectedRamp; 684 | 685 | //set opacity on ramp colors 686 | this.selectedRamp.forEach(function (color, i) { 687 | self.selectedRamp[i][3] = self.state.fillOpacity; 688 | }); 689 | 690 | var values = classify(this.state.selectedField, this.options.fields); 691 | 692 | this.style.visualVariables = [{ 693 | "type": "colorInfo", 694 | "field": this.state.selectedField, 695 | "stops": [{ 696 | "value": values[0], 697 | "color": this.selectedRamp[0], 698 | "label": null 699 | }, { 700 | "value": values[1], 701 | "color": this.selectedRamp[1], 702 | "label": null 703 | }, { 704 | "value": values[2], 705 | "color": this.selectedRamp[2], 706 | "label": null 707 | }, { 708 | "value": values[3], 709 | "color": this.selectedRamp[3], 710 | "label": null 711 | }, { 712 | "value": values[4], 713 | "color": this.selectedRamp[4], 714 | "label": null 715 | }, { 716 | "value": values[5], 717 | "color": this.selectedRamp[5], 718 | "label": null 719 | }, { 720 | "value": values[6], 721 | "color": this.selectedRamp[6], 722 | "label": null 723 | }, { 724 | "value": values[7], 725 | "color": this.selectedRamp[7], 726 | "label": null 727 | }] 728 | }]; 729 | this.updateStyle(); 730 | } 731 | 732 | /* 733 | * Sets graduated styles 734 | * @param {String} field Field being styled 735 | * 736 | * 737 | */ 738 | }, { 739 | key: 'setGraduated', 740 | value: function setGraduated(field) { 741 | this.state.selectedField = field ? field : this.state.selectedField; 742 | 743 | var values = classify(this.state.selectedField, this.options.fields); 744 | 745 | this.style.type = "classBreaks"; 746 | this.style.field = this.state.selectedField; 747 | this.style.minValue = 1; 748 | this.style.classBreakInfos = [{ 749 | "symbol": { 750 | "color": rgbaToDojoColor(this.style.symbol.color), 751 | "size": 4, 752 | "xoffset": 0, 753 | "yoffset": 0, 754 | "type": "esriSMS", 755 | "style": "esriSMSCircle", 756 | "outline": { 757 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 758 | "width": this.style.symbol.outline.width, 759 | "type": "esriSLS", 760 | "style": "esriSLSSolid" 761 | } 762 | }, 763 | "label": values[0], 764 | "classMaxValue": values[0] 765 | }, { 766 | "symbol": { 767 | "color": rgbaToDojoColor(this.style.symbol.color), 768 | "size": 10, 769 | "xoffset": 0, 770 | "yoffset": 0, 771 | "type": "esriSMS", 772 | "style": "esriSMSCircle", 773 | "outline": { 774 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 775 | "width": this.style.symbol.outline.width, 776 | "type": "esriSLS", 777 | "style": "esriSLSSolid" 778 | } 779 | }, 780 | "label": "> " + values[0] + " to " + values[1], 781 | "classMaxValue": values[1] 782 | }, { 783 | "symbol": { 784 | "color": rgbaToDojoColor(this.style.symbol.color), 785 | "size": 16, 786 | "xoffset": 0, 787 | "yoffset": 0, 788 | "type": "esriSMS", 789 | "style": "esriSMSCircle", 790 | "outline": { 791 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 792 | "width": this.style.symbol.outline.width, 793 | "type": "esriSLS", 794 | "style": "esriSLSSolid" 795 | } 796 | }, 797 | "label": "> " + values[1] + " to " + values[2], 798 | "classMaxValue": values[2] 799 | }, { 800 | "symbol": { 801 | "color": rgbaToDojoColor(this.style.symbol.color), 802 | "size": 22, 803 | "xoffset": 0, 804 | "yoffset": 0, 805 | "type": "esriSMS", 806 | "style": "esriSMSCircle", 807 | "outline": { 808 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 809 | "width": this.style.symbol.outline.width, 810 | "type": "esriSLS", 811 | "style": "esriSLSSolid" 812 | } 813 | }, 814 | "label": "> " + values[2] + " to " + values[3], 815 | "classMaxValue": values[3] 816 | }, { 817 | "symbol": { 818 | "color": rgbaToDojoColor(this.style.symbol.color), 819 | "size": 30, 820 | "xoffset": 0, 821 | "yoffset": 0, 822 | "type": "esriSMS", 823 | "style": "esriSMSCircle", 824 | "outline": { 825 | "color": rgbaToDojoColor(this.style.symbol.outline.color), 826 | "width": this.style.symbol.outline.width, 827 | "type": "esriSLS", 828 | "style": "esriSLSSolid" 829 | } 830 | }, 831 | "label": "> " + values[3] + " to " + values[4], 832 | "classMaxValue": values[4] 833 | }]; 834 | 835 | this.updateStyle(); 836 | } 837 | 838 | /* 839 | * Set to single, remove and destroy theme 840 | * 841 | * 842 | */ 843 | }, { 844 | key: 'clearTheme', 845 | value: function clearTheme() { 846 | this.style.visualVariables = null; 847 | this.updateStyle(); 848 | } 849 | 850 | /* 851 | * 852 | * Clear graduated styles 853 | * 854 | */ 855 | }, { 856 | key: 'clearGraduated', 857 | value: function clearGraduated() { 858 | this.style.type = "simple"; 859 | this.style.field = null; 860 | this.style.minValue = 1; 861 | this.style.classBreakInfos = null; 862 | this.updateStyle(); 863 | } 864 | 865 | /* 866 | * Crazy UI handlers 867 | * 868 | */ 869 | }, { 870 | key: 'showThemeUI', 871 | value: function showThemeUI() { 872 | document.getElementById('malette-theme-palette').style.display = 'block'; 873 | document.getElementById('malette-color-palette').style.display = 'none'; 874 | document.getElementById('malette-single-color-option').className = 'malette-option-toggle'; 875 | document.getElementById('malette-theme-color-option').className = 'malette-option-toggle malette-option-toggle-selected'; 876 | this.state._isTheme = true; 877 | 878 | var index = document.getElementById('malette-attr-select').selectedIndex; 879 | var field = document.getElementById('malette-attr-select')[index].innerHTML; 880 | 881 | this.setTheme(null, field); 882 | } 883 | }, { 884 | key: 'showSingleColorUI', 885 | value: function showSingleColorUI() { 886 | document.getElementById('malette-theme-palette').style.display = 'none'; 887 | document.getElementById('malette-color-palette').style.display = 'block'; 888 | document.getElementById('malette-single-color-option').className = 'malette-option-toggle malette-option-toggle-selected'; 889 | document.getElementById('malette-theme-color-option').className = 'malette-option-toggle'; 890 | this.state._isTheme = false; 891 | this.clearTheme(); 892 | } 893 | }, { 894 | key: 'showGraduatedUI', 895 | value: function showGraduatedUI() { 896 | document.getElementById('malette-graduated-palette').style.display = 'block'; 897 | document.getElementById('malette-size-palette').style.display = 'none'; 898 | document.getElementById('malette-single-size-option').className = 'malette-option-toggle'; 899 | document.getElementById('malette-graduated-size-option').className = 'malette-option-toggle malette-option-toggle-selected'; 900 | this.state._isGraduated = true; 901 | 902 | var index = document.getElementById('malette-grad-attr-select').selectedIndex; 903 | var field = document.getElementById('malette-grad-attr-select')[index].innerHTML; 904 | 905 | this.setGraduated(field); 906 | } 907 | }, { 908 | key: 'showSingleSizeUI', 909 | value: function showSingleSizeUI() { 910 | document.getElementById('malette-graduated-palette').style.display = 'none'; 911 | document.getElementById('malette-size-palette').style.display = 'block'; 912 | document.getElementById('malette-single-size-option').className = 'malette-option-toggle malette-option-toggle-selected'; 913 | document.getElementById('malette-graduated-size-option').className = 'malette-option-toggle'; 914 | this.state._isGraduated = false; 915 | this.clearGraduated(); 916 | } 917 | }, { 918 | key: 'toggleExportUI', 919 | value: function toggleExportUI(e) { 920 | if (e.target.checked === true) { 921 | document.getElementById("malette-export-container").style.visibility = "visible"; 922 | document.getElementById('malette-export-toggle-text').innerHTML = 'Hide JSON'; 923 | this._isShowJson = true; 924 | } else { 925 | document.getElementById("malette-export-container").style.visibility = "hidden"; 926 | document.getElementById('malette-export-toggle-text').innerHTML = 'Show JSON'; 927 | this._isShowJson = false; 928 | } 929 | } 930 | 931 | /* 932 | * Logic for toggling the export type in the Export UI 933 | * 934 | * 935 | */ 936 | }, { 937 | key: 'changeExportType', 938 | value: function changeExportType(e) { 939 | 940 | var checkbox = document.getElementsByClassName('export-type-toggle'); 941 | for (var i = 0; i < checkbox.length; i++) { 942 | document.getElementsByClassName('export-type-toggle')[i].checked = false; 943 | } 944 | e.target.checked = true; 945 | 946 | var id = e.target.id; 947 | if (id === 'malette-export-esri-toggle') { 948 | this.selectedExportType = 'esri-json'; 949 | this._generateExportStyle('esri-json'); 950 | } else if (id === 'malette-export-css-toggle') { 951 | this.selectedExportType = 'css'; 952 | this._generateExportStyle('css'); 953 | } 954 | } 955 | 956 | /* 957 | * Sets the selected color 958 | * 959 | * 960 | */ 961 | }, { 962 | key: 'setSelectedColor', 963 | value: function setSelectedColor(color) { 964 | this.style.symbol.color = color; 965 | var swatch = document.getElementById('malette-selected-swatch'); 966 | swatch.style.backgroundColor = this.style.symbol.color; 967 | 968 | if (this.state._isGraduated) { 969 | this.setGraduated(); 970 | } else { 971 | this.updateStyle(); 972 | } 973 | } 974 | }, { 975 | key: 'setSelectedThemeRow', 976 | value: function setSelectedThemeRow(e) { 977 | var self = this; 978 | var index = parseInt(e.target.id.replace(/malette-theme-row-/g, '')); 979 | var ramp = []; 980 | 981 | this.themeColors[index].forEach(function (color) { 982 | var c = rgbaToDojoColor(color); 983 | ramp.push(c); 984 | }); 985 | 986 | this.setTheme(ramp); 987 | } 988 | }, { 989 | key: 'setSelectedStrokeColor', 990 | value: function setSelectedStrokeColor(color) { 991 | this.style.symbol.outline.color = color; 992 | var swatch = document.getElementById('malette-selected-swatch'); 993 | swatch.style.backgroundColor = this.style.symbol.outline.color; 994 | 995 | if (this.state._isGraduated) { 996 | this.setGraduated(); 997 | } else { 998 | this.updateStyle(); 999 | } 1000 | } 1001 | }, { 1002 | key: 'setSelectedSize', 1003 | value: function setSelectedSize(size) { 1004 | this.style.symbol.size = parseInt(size); 1005 | var el = document.getElementById('malette-size-number'); 1006 | this._setInnerHTML(el, 'Radius: ' + size + 'px'); 1007 | this.updateStyle(); 1008 | } 1009 | }, { 1010 | key: 'setStrokeWidth', 1011 | value: function setStrokeWidth(width) { 1012 | if (this.state.type !== 'line') { 1013 | this.style.symbol.outline.width = parseFloat(width); 1014 | } else { 1015 | this.style.symbol.width = parseFloat(width); 1016 | } 1017 | 1018 | var el = document.getElementById('malette-stroke-width'); 1019 | this._setInnerHTML(el, width + 'px'); 1020 | 1021 | if (this.state._isGraduated) { 1022 | this.setGraduated(); 1023 | } else { 1024 | this.updateStyle(); 1025 | } 1026 | 1027 | if (this.state._isTheme) { 1028 | this.setTheme(); 1029 | } else { 1030 | this.updateStyle(); 1031 | } 1032 | } 1033 | }, { 1034 | key: 'setOpacity', 1035 | value: function setOpacity(opacity) { 1036 | this.state.fillOpacity = parseFloat(opacity) * 255; 1037 | var el = document.getElementById('malette-opacity-number'); 1038 | this._setInnerHTML(el, 'Opacity: ' + opacity * 100 + '%'); 1039 | 1040 | if (this.state._isGraduated) { 1041 | this.setGraduated(); 1042 | } else if (this.state._isTheme) { 1043 | this.setTheme(); 1044 | } else { 1045 | this.updateStyle(); 1046 | } 1047 | } 1048 | }, { 1049 | key: '_setInnerHTML', 1050 | value: function _setInnerHTML(el, html) { 1051 | el.innerHTML = html; 1052 | } 1053 | }, { 1054 | key: '_setRamp', 1055 | value: function _setRamp() { 1056 | if (!this.selectedRamp) this.selectedRamp = []; 1057 | var self = this; 1058 | 1059 | this.style.visualVariables[0].stops.forEach(function (stop) { 1060 | var color = stop.color; 1061 | self.selectedRamp.push(color); 1062 | }); 1063 | } 1064 | 1065 | /* 1066 | * Convert various style inputs to esri-json which is used in Malette 1067 | * 1068 | * 1069 | */ 1070 | }, { 1071 | key: '_toEsriJson', 1072 | value: function _toEsriJson() { 1073 | if (this.format === 'css') { 1074 | this.style = { 1075 | type: 'simple', 1076 | symbol: {} 1077 | }; 1078 | this.style.symbol.color = this.options.style.fillColor ? this.options.style.fillColor : 'rgba(202,58,45,130)'; 1079 | this.style.symbol.size = this.options.style.radius ? this.options.style.radius : 8; 1080 | 1081 | if (this.state.type !== 'line') { 1082 | this.style.symbol.outline = {}; 1083 | this.style.symbol.outline.width = this.options.style.weight || 1; 1084 | this.style.symbol.outline.color = [this.options.style.color] || 'rgba(255,255,255,255'; 1085 | } 1086 | 1087 | this.state.fillOpacity = this.options.style.fillOpacity ? this.options.style.fillOpacity * 255 : 255; 1088 | } 1089 | } 1090 | 1091 | /* 1092 | * Convert esri-json to CSS 1093 | * 1094 | * 1095 | */ 1096 | }, { 1097 | key: '_toCss', 1098 | value: function _toCss(callback) { 1099 | var css = {}; 1100 | css.fillColor = this.style.symbol.color; 1101 | 1102 | if (this.state.type !== 'line') { 1103 | css.weight = this.style.symbol.outline.width; 1104 | css.color = this.style.symbol.outline.color; 1105 | css.radius = this.style.symbol.size; 1106 | } 1107 | 1108 | css.fillOpacity = this.state.fillOpacity / 255; 1109 | 1110 | callback(css); 1111 | } 1112 | 1113 | /* 1114 | * Master style object 1115 | * Updates and emits 1116 | * 1117 | */ 1118 | }, { 1119 | key: 'updateStyle', 1120 | value: function updateStyle() { 1121 | var self = this; 1122 | 1123 | if (this.exportFormat === 'esri-json') { 1124 | 1125 | if (this.style.symbol) { 1126 | this.style.symbol.color = rgbaToDojoColor(this.style.symbol.color, this.state.fillOpacity); //change colors BACK to dojo :( 1127 | if (this.state.type !== 'line') { 1128 | this.style.symbol.outline.color = rgbaToDojoColor(this.style.symbol.outline.color); 1129 | } 1130 | } 1131 | 1132 | this.style.layerId = this.state.layerId; 1133 | this.style.defaultSymbol = this.style.symbol; 1134 | console.log('emit --->>>', this.style); 1135 | this.emit('style-change', this.style); 1136 | } else { 1137 | 1138 | if (this.exportFormat === 'css') { 1139 | this._toCss(function (css) { 1140 | css.layerId = self.state.layerId; 1141 | css.defaultSymbol = css.symbol; 1142 | self.emit('style-change', css); 1143 | }); 1144 | } 1145 | } 1146 | 1147 | this._generateExportStyle(); 1148 | } 1149 | }, { 1150 | key: '_generateExportStyle', 1151 | value: function _generateExportStyle(type) { 1152 | //codeBox.innerHTML = JSON.stringify(this.style, null, 2); 1153 | type = type || this.selectedExportType; 1154 | 1155 | if (type === 'esri-json') { 1156 | 1157 | this.style.symbol.color = rgbaToDojoColor(this.style.symbol.color, this.state.fillOpacity); //change colors BACK to dojo :( 1158 | 1159 | if (this.state.type !== 'line') { 1160 | this.style.symbol.outline.color = rgbaToDojoColor(this.style.symbol.outline.color); 1161 | } 1162 | 1163 | document.getElementById('export-code-block').innerHTML = JSON.stringify(this.style, null, 2); 1164 | } else { 1165 | 1166 | if (type === 'css') { 1167 | this._toCss(function (css) { 1168 | document.getElementById('export-code-block').innerHTML = JSON.stringify(css, null, 2); 1169 | }); 1170 | } 1171 | } 1172 | } 1173 | 1174 | /************* EVENTS **************/ 1175 | 1176 | /* 1177 | * Register Malette events 1178 | * 1179 | */ 1180 | }, { 1181 | key: 'on', 1182 | value: function on(eventName, handler) { 1183 | this._handlers[eventName] = handler; 1184 | } 1185 | 1186 | // trigger callback 1187 | }, { 1188 | key: 'emit', 1189 | value: function emit(eventName, val) { 1190 | if (this._handlers[eventName]) { 1191 | this._handlers[eventName](val); 1192 | } 1193 | } 1194 | }, { 1195 | key: '_onColorClick', 1196 | value: function _onColorClick(e) { 1197 | if (e.which === 1 && !(e.metaKey || e.ctrlKey)) { 1198 | e.preventDefault(); 1199 | this.setSelectedColor(e.target.style.backgroundColor); 1200 | } 1201 | } 1202 | }, { 1203 | key: '_onThemeRowClick', 1204 | value: function _onThemeRowClick(e) { 1205 | e.preventDefault(); 1206 | this.setSelectedThemeRow(e); 1207 | } 1208 | }, { 1209 | key: '_onAttributeChange', 1210 | value: function _onAttributeChange(e) { 1211 | var index = document.getElementById('malette-attr-select').selectedIndex; 1212 | var field = document.getElementById('malette-attr-select')[index].innerHTML; 1213 | this.state.selectedField = field; 1214 | this.setTheme(null, field); 1215 | 1216 | if (this.state._isGraduated) { 1217 | this.setGraduated(field); 1218 | } 1219 | } 1220 | }, { 1221 | key: '_onGradAttributeChange', 1222 | value: function _onGradAttributeChange(e) { 1223 | var index = document.getElementById('malette-grad-attr-select').selectedIndex; 1224 | var field = document.getElementById('malette-grad-attr-select')[index].innerHTML; 1225 | this.state.selectedField = field; 1226 | this.setGraduated(field); 1227 | 1228 | if (this.state._isTheme) { 1229 | this.setTheme(null, field); 1230 | } 1231 | } 1232 | }, { 1233 | key: '_onStrokeColorClick', 1234 | value: function _onStrokeColorClick(e) { 1235 | if (e.which === 1 && !(e.metaKey || e.ctrlKey)) { 1236 | e.preventDefault(); 1237 | this.setSelectedStrokeColor(e.target.style.backgroundColor); 1238 | } 1239 | } 1240 | }, { 1241 | key: '_onSizeChanged', 1242 | value: function _onSizeChanged(e) { 1243 | e.preventDefault(); 1244 | this.setSelectedSize(e.target.value); 1245 | } 1246 | }, { 1247 | key: '_onStrokeWidthChanged', 1248 | value: function _onStrokeWidthChanged(e) { 1249 | e.preventDefault(); 1250 | this.setStrokeWidth(e.target.value); 1251 | } 1252 | }, { 1253 | key: '_onOpacityChanged', 1254 | value: function _onOpacityChanged(e) { 1255 | e.preventDefault(); 1256 | this.setOpacity(e.target.value); 1257 | } 1258 | }, { 1259 | key: '_onToggleExportUI', 1260 | value: function _onToggleExportUI(e) { 1261 | this.toggleExportUI(e); 1262 | } 1263 | }, { 1264 | key: '_onExportTypeChange', 1265 | value: function _onExportTypeChange(e) { 1266 | //e.preventDefault(); 1267 | this.changeExportType(e); 1268 | } 1269 | }, { 1270 | key: '_onTabClick', 1271 | value: function _onTabClick(e) { 1272 | 1273 | if (e.target.classList.contains('disabled')) { 1274 | return; 1275 | } 1276 | 1277 | if (e.which === 1 && !(e.metaKey || e.ctrlKey)) { 1278 | e.preventDefault(); 1279 | 1280 | var els = document.getElementsByClassName('malette-tab'); 1281 | for (var i = 0; i < els.length; i++) { 1282 | els[i].classList.remove('malette-tab-selected'); 1283 | } 1284 | e.target.classList.add('malette-tab-selected'); 1285 | 1286 | this.changeTab(e.target.innerHTML); 1287 | } 1288 | } 1289 | }]); 1290 | 1291 | return Malette; 1292 | })(); 1293 | 1294 | 'use strict'; --------------------------------------------------------------------------------