GithubHelp home page GithubHelp logo

adrisolid / wab-custom-widgets Goto Github PK

View Code? Open in Web Editor NEW
31.0 7.0 16.0 8.42 MB

Web AppBuilder Custom Widgets

HTML 11.02% JavaScript 87.42% CSS 1.56%
esri webappbuilder wab-custom-widgets wab-widgets dojo dojo-toolkit maps mapping gis javascript css html arcgis-api web-development

wab-custom-widgets's Introduction

Web App Builder Custom Widgets

I need some caffeine to work :)

Buy Me a Coffee at ko-fi.com

My other side: I'm electronic music producer 🎹

I really enjoy everything related to synthesizers and drum machines. I like dark electronics πŸ–€ (EBM, dark wave) the most, but also techno

You can also support me in:


AdriΓ‘n PΓ©rez Beneito Web App builder Custom Widget List

Bar Chart Cedar πŸ“Š live demo

See Cedar.js and how to create charts using ArcGIS Geoservices. Pre-coded Web App Builder 2.6 Chart Widget doesn't allow you to create charts on the fly. You can select the available layers in the Web Map. Choose, for the 'x' axis, the field you want to show information, repeat the procedure for the 'y' axis. Select the type of graphic, bars or horizontal bars. The widget is ready to filter the data by extension (by activating the check button). Inside the container of the widget, the graphic will be updated being this responsive.

.

Don't forget to add the Cedar dependencies. How to add other libraries to WAB?

Version 1.2, pending improvements. All suggestions for improvement will be welcome.

List of the latest enhancements and changes:

  • Added a new class => select the layers ids from the Web Map (Dojo Select)
  • Added geometry icon; geometry selector (now => "*")

IntroJS ft WAB πŸ’« live demo

Why using intro.js?

When new users visit your website or product you should demonstrate your product features using a step-by-step guide. Even when you develop and add a new feature to your product, you should be able to represent them to your users using a user-friendly solution. Intro.js is developed to enable web and mobile developers to create a step-by-step introduction easily.

.

Integration with a Web App Builder app

Add intro.js dependencies How to add other libraries to WAB?

Create the configuration js file and refer to it in the application in the file 'index.html' Explore and get with the console the ids of the containers to which you want to add as a step. Whether the container doesn't have the 'id' property, get it with 'settingid' -element: getNode('[settingid="widgets_LayerList_Widget_19"]'), position: 'left'- (e.g. the header widgets). Fill the 'intro' and 'position' options:

const getNode = node => document.querySelector(node);

const initIntro = () => {
    introJs().setOptions({
        steps: [{
                intro: "Hello Web App Builder, I'm IntroJS, wanna join me? :)"
            },
            {
                element: getNode('#widgets_Search_Widget_3'),
                intro: "The Search widget enables end users to find locations or search features on the map.",
                position: 'bottom'
            }
            .
            .
            .
        ]
    }).start();
}

Call the 'initIntro' function Simply add a button that calls the function. For example, go to the 'HeaderController' widget:

  • Add the button at the container (Widget.html):
<div class="container-section jimu-float-leading" data-dojo-attach-point="containerNode">
    <button data-dojo-attach-point="executeIntroJS" type="button"></button>
</div>
  • Add a new function for contain the button and call it at 'startup' (Widget.js):
startup: function() {
  this.inherited(arguments);
  this.resize();
  setTimeout(lang.hitch(this, this.resize), 100);
  this.IntroJS();
},

IntroJS: function(){
  new Button({
      label: "INTRO JS",
      style: "position:absolute;top:5px;left:400px;",
      onClick: () => {
        initIntro();
      }
  }, this.executeIntroJS).startup();
},

Heat Map WAB 2.7 πŸ”₯ live demo

Using ArcGIS API for JavaScript 3.23 for create a Heat Map in WAB 2.7

The HeatmapRenderer renders feature layer point data into a raster visualization that emphasizes areas of higher density or weighted values. This renderer uses a Gaussian Blur technique to average the influence of each point out over the area determined by the 'blurRadius' (the radius (in pixels) of the circle over which the majority of each point's value is spread out.). A Gaussian blur uses a Gaussian, or Normal, distribution (also called a Bell-curve) to spread value out in vertical and horizontal directions.

Using HeatMap Widget

  • Select a layer (it needs point type; the widget is already prepared for filter the layers and get 'point' layers)
  • Select a field (numeric -short, float, etc-)
  • Slider: select 'Blur Radius' (The radius -in pixels- of the circle over which the majority of each point's value is spread out)
  • Slider: select 'Max Value' (The pixel intensity value which is assigned the final color in the color ramp. Values above this number will also be assigned the final color ramp color)
  • Slider: select 'Min Value' (The pixel intensity value which is assigned the initial color in the color ramp. Values below this number will also be assigned the initial color ramp color)
  • Draw Tools: Generate the map by spatially delimiting the result using drawing tools
  • Heat Map Slider: (A widget to assist in obtaining values for managing and setting properties on a HeatmapRenderer)
  • Drawing Tools: Create a HeatMap using drawing tools as a spatial delimiter. Options => Polygon, Freehand Polygon, Circle, Ellipse, Rectangle

.


ChartJS Widget πŸ“ˆ live demo

Using ChartJS for create charts using your GeoServices

Chart.js is a community maintained open-source library that helps you easily visualize data using JavaScript. ChartJS is simple and clean HTML5 based JavaScript charts. Display line and bar charts using your GeoServices.

Integration with a Web App Builder app

Add ChartJS dependencies How to add other libraries to WAB?

Using Chart Widget

.

  • Select a layer
  • Select a field for 'x' axis
  • Select a field for 'y' axis
  • Click 'Execute' button
  • Click on the tabs to switch the chart. Both graphics will be executed automatically. These will be filtered every time the map extension changes

Buffer Widget πŸ”΄ live demo

Using Turf.js. Advanced geospatial analysis for browsers and Node.js

Turf is a JavaScript library for spatial analysis. It includes traditional spatial operations, helper functions for creating GeoJSON data, and data classification and statistics tools. Turf can be added to your website as a client-side plugin, or you can run Turf server-side with Node.js.

Integration with a Web App Builder app

Add Turf.js dependencies How to add other libraries to WAB?

Using Buffer Widget

.

  • Select the distance unit
  • Pick on the map or input the coordinates
  • Select the distance
  • Intersection selection available. Select a layer and enable or disable the selection. Click the 'Execute' button

Select by Attributes Widget πŸ’  live demo

Usage

This WAB widget copies part of the functionality of the famous 'Select by Attributes' of ArcMap.

'Select By Attributes allows you to provide a SQL query expression that is used to select features that match the selection criteria.' Follow Esri's instructions here

.

wab-custom-widgets's People

Contributors

adrisolid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

wab-custom-widgets's Issues

Requesting assistance selecting widgets docked in "More" section in WAB

I have been working on this issue for some time. I wanted to see if perhaps someone ells had a brilliant idea.
image
As you can see from the screenshot the intro js tooltip is unable to find my "print plus" widget that is docked inside of the "more" section of the WAB.
image

I have tracked the code into the libs\introJS/intro.js file on line 171 there is a "for each" that builds a list of the elements that will be used later to add the tooltip to the correct items.

Any suggestions or thoughts would be very much appreciated.

CSS style on select layer buttons overrides Table widget buttons

Inside the style.css file you set

 .claro .dijitButton .dijitButtonNode, .button {
  width : 40px;
}

This has the negative effect of setting the buttons inside the Table display to 40px; (which is too small, they become squished).
I'm not exactly familiar with the way you're creating the buttons, but one fix I found was to set a width to a more specific class:
style.css :

.opSize .dijitButtonNode {
  width: 40px;
}

And widget.js :
(In the _initButtons function):
class: "button opSize",

IntroJS - Trouble adding additional widgets to config file

Hello,
Firstly I want to say thank you so much for this port of the introJS library for use in the WAB! I wondered if you could help me with an app that I am setting up. I have many additional widgets and I can't seem to find a way to adjust your config file to point to them. See screenshot.
image
If you notice this element has a (settingid="widgets_About_Widget_47") element but if I add this to the config file like so:
image
the introJS window pop's up in the middle of the screen.
image
Any ideas?

Select by attribute for newly added layers

Hi, excellent widget, thank you! I'm putting together an app that also includes the Add Data widget and it appears your widget doesn't auto-update if new layers are added to the app. Simply, for your reference, here is the approach I've taken with your code to handle the situation. The changes are way too much to make a PR. I've migrated code out of idWebMapLayers.js and into widget.js as well as a bunch of linting changes. If you or someone else finds it useful, great! If not, no problems!

Thanks again

`
define([//Dojo
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/dom-construct',
'dojo/dom-style',
'dojo/Deferred',
'dojo/dom',
'dojo/_base/html',
//Jimu
'jimu/BaseWidget',
'jimu/dijit/LoadingShelter',
'jimu/SelectionManager',
'jimu/dijit/Message',
//Dijit
'dijit/dijit',
'dijit/form/Select',
'dijit/form/Button',
//Esri
'esri/tasks/query',
'esri/tasks/QueryTask',
//Files
'xstyle/css!./files/bootstrap.min.css',
'./files/jquery-3.3.1.min',
'./files/bootstrap.min',
//domReady!
'dojo/domReady!'
],
function(declare, lang, domConstruct, domStyle, Deferred, dom, html, BaseWidget, LoadingShelter,
SelectionManager, Message, dijit, Select, Button, Query, QueryTask) {

return declare([BaseWidget], {

shelter: null,
layerName: null,
layer: null,
field: null,
url: null,
uniqueValue: null,
ese: null,
selectedField: null,
selectionManager: SelectionManager.getInstance(),

startup: function(){
this.layerChooserNodeID = "layerChooserNodeEvent";
this.inherited(arguments);
this._setWidgetSize();
this._initLoadingShelter();
this._initLayerChooser();
this._initButtons();

// Listen for new layers and add them to query options
this.map.on("layer-add-result", lang.hitch(this, function(l) {
console.log("a layer was added ");
var selectLayer = dijit.byId(this.layerChooserNodeID);
selectLayer.addOption(this._makeLayerOption(this.folderUrl, [l.layer], "*"));
}));

// Listen for layers being removed and update query list
this.map.on("layer-remove", lang.hitch(this, function(l) {
console.log("a layer was removed ");
var selectLayer = dijit.byId(this.layerChooserNodeID);
var lid = l.layer.id;

for(var i=0; i < selectLayer.options.length; i++){
    if (selectLayer.options[i].value === lid){
        selectLayer.removeOption(i);
    }
}

}));

},

_setWidgetSize: function(){
var panel = this.getPanel();
panel.position.height = 550;
//panel.setPosition(panel.position);
panel.panelManager.normalizePanel(panel);
},

_initLoadingShelter: function(){
this.shelter = new LoadingShelter({
hidden: false
});
this.shelter.placeAt(this.loadingNode);
this.shelter.startup();
this.shelter.hide();
},

_createLayerSelect: function(id, layerNode, map, geometry){
new Select({
name: layerNode,
id: id
}).placeAt(layerNode).startup();

var selectLayer = dijit.byId(id);

var layers = [];
for(var i = 0; i < map.graphicsLayerIds.length; i++) {
  var layerObject = map.getLayer(map.graphicsLayerIds[i]);
  if(layerObject.url){
    layers.push(layerObject);
  } 
}

selectLayer.addOption(this._makeLayerOption(this.folderUrl, layers, geometry));

},

_makeLayerOption: function(f, layers, geometry){
var r = layers.map(function(record){
switch(true){
case record.geometryType === "esriGeometryPolygon" && (geometry === '' || geometry === 'polygon'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryPoint" && (geometry === '
' || geometry === 'point'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryLine" && (geometry === '' || geometry === 'line'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryPolyLine" && (geometry === '
' || geometry === 'line'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryMultiPatch" && (geometry === '*' || geometry === 'multiPatch'):
return html.create("option", {
label: ' M ' + record.name,
value: record.id
});
default:
return null;
}
});
return r;
},

_initLayerChooser: function(){
var idForChangeEvent = "layerChooserNodeEvent";

this._createLayerSelect(idForChangeEvent, "layerChooserNode", this.map, "*");

this.layerName = dijit.byId(idForChangeEvent).value;
this._fieldMultiSelect(this.layerName); 
this.selectFrom.innerHTML = 'SELECT * FROM ' + this.layerName  + ' WHERE:';

dijit.byId(idForChangeEvent).on("change", lang.hitch(this, function(evt){
    this._updateFieldMultiSelect('fieldsMultiSelect', evt);
    this.selectFrom.innerHTML = 'SELECT * FROM ' + evt + ' WHERE:';
}));

},

_fieldMultiSelect: function(layerId){
this.layer = this.map.getLayer(layerId);
this.url = this.layer.url;
var fields = this.layer.fields;
this.field = this.layer.fields;

for(var i in fields){
    var opData = domConstruct.create('option');
    opData.innerHTML = fields[i].name;
    opData.value = fields[i].name;
    dom.byId('fieldsMultiSelect').appendChild(opData);
}

var self = this;
$('#fieldsMultiSelect').on('change', function(){
    self.selectedField = $(this).val();
    $('#textBoxNode').val( $('#textBoxNode').val() + $(this).val() );
    
    var $uniques = $('#uniquesMultiSelect' + ' option');
    $.each($uniques, function(index, element) {
    element.remove();
    });
});

$('#uniquesMultiSelect').on('change', function(){
    $('#textBoxNode').val( $('#textBoxNode').val() + "'" + $(this).val() + "'" );
});

},

_updateFieldMultiSelect: function(id, layerId){
var $uniques = $('#' + id + ' option');
$.each($uniques, function(index, element) {
element.remove();
});

this.layer = this.map.getLayer(layerId);
this.url = this.layer.url;
var fields = this.layer.fields;
this.field = this.layer.fields;

for(var i in fields){
    var opData = domConstruct.create('option');
    opData.innerHTML = fields[i].name;
    opData.value = fields[i].name;
    dom.byId(id).appendChild(opData);
}

},

_initButtons: function(){
for(var i in this.config.ids){
new Button({
label: this.nls.buttons[this.config.ids[i]],
value: this.nls.buttons[this.config.ids[i]],
class: "button",
onClick: function(){
$('#textBoxNode').val( $('#textBoxNode').val() + ' ' + this.get("value") + ' ' );
}
}, this[this.config.ids[i]]);
}
},

_getUniqueValues: function(){
this.shelter.show();
var query = new Query();
query.where = '1=1';
query.outFields = this.selectedField;
new QueryTask(this.url).execute(query, lang.hitch(this, function(results){
var map = results.features.map(lang.hitch(this, function(record){
return record.attributes[this.selectedField[0]];
}));
var def = new Deferred();
def.resolve(map);
def.then(lang.hitch(this, function(results){
return results.sort()
.filter(lang.hitch(this, function(x, i){
return results.indexOf(x) === i;
}));
})).then(lang.hitch(this, function(results){
var $uniques = $('#uniquesMultiSelect option');
$.each($uniques, function(index, element){
element.remove();
});
return results;
})).then(lang.hitch(this, function(results){
this._updateUniquesMultiselect('uniquesMultiSelect', results);
})).then(lang.hitch(this, function(results){
this.shelter.hide();
}));
}));
},

_updateUniquesMultiselect: function(id, data){
for(var i in data){
var opData = domConstruct.create('option');
opData.innerHTML = data[i];
opData.value = data[i];
dom.byId(id).appendChild(opData);
}
},

_performQuery: function(){
var query = new Query();
query.where = $('#textBoxNode').val();
query.outFields = ["*"];
if (this.url.indexOf("MapServer") > 0) {
query.returnGeometry = true;
}
new QueryTask(this.url).execute(query, lang.hitch(this, function(results){
this.selectionManager.setSelection(this.layer, results.features);
}),function(error){
new Message({
message: "There was a problem selecting."
});
});
},

_confirmQuery: function(){
var query = new Query();
query.where = $('#textBoxNode').val();
query.outFields = ["*"];
new QueryTask(this.url).execute(query, lang.hitch(this, function(results){
if(results.features.length !== 0){
new Message({
message: "There expression was successfully verified."
});
}else{
new Message({
message: "The expression was verified successfully, but no records were returned."
});
}
}),function(error){
new Message({
message: "There was an error with the expression."
});
});
},

_clearSelection: function(){
this.selectionManager.clearSelection(this.layer);
this.sqlquery.value = "";
var $uniques = $('#uniquesMultiSelect' + ' option');
$.each($uniques, function(index, element) {
element.remove();
});
}
});
});`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.