I m trying to use a standby widget that will keep loading, till the dojo datagrid is loaded.
I m trying this. But, standby widget doesn't appear. It just waits, and loads the data.
require([
"dojox/grid/DataGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojox/widget/Standby",
"dijit/form/Button",
"dojo/domReady!",
],
function (DataGrid, Memory, ObjectStore, request, Standby, Button) {
var standby = new Standby({ target: "grid" });
document.body.appendChild(standby.domNode);
standby.startup();
standby.show();
var grid, dataStore;
request.get("MyFile.aspx", {
handleAs: "json"
}).then(function (data) {
dataStore = new ObjectStore({ objectStore: new Memory({ data: data }) });
grid = dijit.byId("grid");
grid.setStore(dataStore, { id: "*" }, {});
var struct = [
{ name: "Field1", field: "Name", width: "50%" },
{ name: "Field2", field: "Name2", width: "50%" }, ];
grid.setStructure(struct);
grid.startup();
standby.hide();
I believe it's just a problem in the order of the calls. You have to first initialize your grid, then initialize the standby, then fetch the data and set it in the grid and then hide the standby. In your case:
require([
"dojox/grid/DataGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojox/widget/Standby",
"dijit/form/Button",
"dojo/domReady!",
],
function (DataGrid, Memory, ObjectStore, request, Standby, Button) {
//Create the grid
var grid = new DataGrid({
query: { id : '*' },
structure : [
{ name: "Field1", field: "Name", width: "50%" },
{ name: "Field2", field: "Name2", width: "50%" }
]
}, 'grid');
grid.startup();
//Create the stand by
var standby = new Standby({ target: "grid" });
document.body.appendChild(standby.domNode);
standby.startup();
standby.show();
//Fetch data
var grid, dataStore;
request.get("teste.php", {
handleAs: "json"
}).then(function (data) {
var grid = dijit.byId('grid');
//Create store and put in the grid
dataStore = new ObjectStore({ objectStore: new Memory({ data: data }) });
grid.setStore(dataStore, { id: "*" }, {});
//Hide standby
standby.hide();
}, function(error) {
console.log(error);
});
}
);
Related
I try to fetch stocks data from an API. This data should be used to create a chart.js graph.
how do I access in vue.js data to generate a chart.js line chart from the methods http(axios) call?
Is it possible to access the data directly in the mounted component or should I define a const in the section and create the variables there?
<template>
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
<div>
<canvas id="myChart" height="200" width="650"></canvas>
</div>
<script>
export default {
mounted() {
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: [prices[0].date],
datasets: [
{
label: 'Dataset msft',
data: prices[0].price
},
{
label: 'Dataset google',
data: prices[1].price
},
],
},
});
},
data() {
return {
selected: "",
prices: [],
options: [
{ text: "msft", value: "msft" },
{ text: "GOOGL", value: "GOOGL" },
],
};
},
watch: {
selected: function () {
this.getPrice();
},
},
methods: {
getPrice: function () {
var this_ = this;
axios
.get(
"https://site/...."
)
.then((response) => {
// JSON responses are automatically parsed.
this_.prices = response.data;
})
},
},
};
</script>
Yes, you can access variables in data() from mounted().
You need to prepend variables with this. when using the Options API
ex: this.prices[0].price
As you are putting watcher on selected but I did not see any changes in the selected variable in your code. As per my understanding you are making an API call to get the graph data based on the selected option.
If Yes, Instead of generating a chart in mounted you can generate it inside your getPrice() method itself based on the response. It should be :
methods: {
getPrice: function () {
var this_ = this;
axios
.get(
"https://site/...."
)
.then((response) => {
this.generateChart(response.data);
})
},
generateChart(prices) {
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: [prices[0].date],
datasets: [
{
label: 'Dataset msft',
data: prices[0].price
},
{
label: 'Dataset google',
data: prices[1].price
}
]
}
});
}
}
Here, a very basic example:
<script>
export default {
async mounted() {
await this.$nextTick();
const ctx = document.getElementById("myChart");
this.chart = new Chart(ctx, {
type: "line",
data: {
labels: [],
datasets: [],
},
});
},
data() {
return {
selected: "",
chart: null,
options: [
{ text: "msft", value: "msft" },
{ text: "GOOGL", value: "GOOGL" },
],
};
},
watch: {
selected: function () {
this.getPrice();
},
},
methods: {
async getPrice() {
let { data } = await axios.get("https://site/....");
this.chart.data.datasets = [{ label: "dummy data" , data: [2, 3, 4]}];
this.chart.data.label = [1, 2, 3];
this.chart.update(); //very important, always update it
},
},
};
</script>
You create a property called chart and save your chart to it.
Then, after you fetch your data, you can access your chart with this.chart and then you set your datasets and labels. Whenever you make an change to the chart, use this.chart.update() to update it on the browser.
If you execute this code, you should see some dummy data in the chart
Please note that I was able to consume the geojson data and create a layer on leaflet map with ease. Also, tried using lib arcgis-to-geojson-utils but not able to get it working.
Here is my code.
Your help is greatly appreciated.
view.when()
.then(fetchData)
.then(createGraphics)
.then(createLayer)
.then(addToView)
.catch(function(e) {
console.error("Creating FeatureLayer failed", e);
})
function fetchData() {
return fetch(url,options)
.then(response => {
return response.json()
});
}
function createGraphics(schoolsGeoData) {
const geoData = JSON.parse(schoolsGeoData);
return geoData.features.map((school, i) => {
let schoolAttr = {
OBJECTID: school.properties["id"],
name: school.properties["name"]
}
return new Graphic({
// type: "point",
attributes: schoolAttr,
geometry: new Point({
x: school.geometry.coordinates[0],
y: school.geometry.coordinates[1]
}),
});
})
}
function createLayer(graphics) {
return new FeatureLayer({
source: graphics,
objectIdField: "OBJECTID",
fields: schoolFeilds(),
popupTemplate: schoolTemplate(),
renderer: myRenderer(),
geometryType: "point" ,
spatialReference: {
wkid: 4326
},
});
}
function addToView(layer) {
if(layer) {
view.map.add(layer);
}
}
Your code have a reasonable logic, of course there are thing missing that I can not know it they are working. For example, I don't know what options you add to fetch operation, but by default it will get you the data correctly, and you do not have to convert to JSON because it realize that.
I was actually going to ask you for more code, or what exactly was your problem, but I decide to remind you that you actually have a specific layer to handle GeoJSON data, GeoJSONLayer.
ArcGIS API - GeoJSONLayer
ArcGIS Examples - GeoJSONLayer
But, anyway I will leave you here a running example of what you are trying to do, fetching the data and using FeatureLayer, using the data from the example I mention,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>GeoJSON with FeatureLayer - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/Graphic"
], function(Map, MapView, FeatureLayer, Graphic) {
const map = new Map({
basemap: "gray"
});
const view = new MapView({
center: [-80, 35],
zoom: 8,
map,
container: "viewDiv"
});
view.when()
.then(fetchData)
.then(createGraphics)
.then(createLayer)
.then(addToView)
.catch(function(e) {
console.error("Creating FeatureLayer failed", e);
})
function fetchData() {
return fetch(
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson'
)
.then(response => {
return response.json()
});
}
function createGraphics(data) {
// const geoData = JSON.parse(data);
return data.features.map((feature, i) => {
return new Graphic({
attributes: {
OBJECTID: i,
title: feature.properties["title"],
mag: feature.properties["mag"],
type: feature.properties["type"],
place: feature.properties["place"],
time: feature.properties["time"]
},
geometry: {
type: "point",
x: feature.geometry.coordinates[0],
y: feature.geometry.coordinates[1]
},
});
})
}
function createLayer(graphics) {
const popupTemplate = {
title: "{title}",
content: "Magnitude {mag} {type} hit {place} on {time}",
fieldInfos: [
{
fieldName: "time",
format: {
dateFormat: "short-date-short-time"
}
}
],
outFields: ["title", "mag", "type", "place", "time"]
}
const renderer = {
type: "simple",
field: "mag",
symbol: {
type: "simple-marker",
color: "orange",
outline: {
color: "white"
}
},
visualVariables: [
{
type: "size",
field: "mag",
stops: [
{
value: 2.5,
size: "10px"
},
{
value: 8,
size: "40px"
}
]
}
]
};
return new FeatureLayer({
source: graphics,
fields: [{
name: "OBJECTID",
alias: "ObjectID",
type: "oid"
}, {
name: "title",
alias: "Title",
type: "string"
}
, {
name: "mag",
alias: "Magnitude",
type: "double"
}
, {
name: "type",
alias: "Type",
type: "string"
}, {
name: "place",
alias: "Place",
type: "string"
}, {
name: "time",
alias: "Time",
type: "date"
}],
objectIdField: "OBJECTID",
popupTemplate,
renderer
});
}
function addToView(layer) {
if(layer) {
view.map.add(layer);
}
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
I have an empty grid, with the columns defined as below:
var json = { };
json.col1 = { label: 'Select', selector: 'checkbox' };
json.bndryName = "Boundary Name";
return json;
The boundary grid is initialized as below and the data/collection is loaded on a button click,and when I set allowSelectAll:true, I donot see the the header column rendered with a checkbox to select All. Please advise.
this._bndryGrid = new (declare([OnDemandGrid, Selection,Selector,ColumnResizer]))({
selectionMode: "multiple",
columns: columns,
class:'grid',
loadingMessage: "Loading data...",
noDataMessage: "No results found."
}, this.ap);
I'm not sure you've provided enough to go on here (and your grid doesn't even include allowSelectAll: true), but here is an example that works:
require({
packages: [
{
name: 'dgrid',
location: '//cdn.rawgit.com/SitePen/dgrid/v1.0.0'
},
{
name: 'dstore',
location: '//cdn.rawgit.com/SitePen/dstore/v1.1.1'
}
]
}, [
'dojo/_base/declare',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dgrid/Selector',
'dstore/Memory',
'dojo/domReady!'
], function(declare, OnDemandGrid, Selection, Selector, Memory) {
var data = [
{ id: 1, name: 'Peter' },
{ id: 2, name: 'Paul' },
{ id: 3, name: 'Mary' }
];
var store = new Memory({ data: data });
var options = {
allowSelectAll: true,
collection: store,
columns: [
{ field: 'id', label: '', selector: 'checkbox' },
{ field: 'name', label: 'Name' }
]
};
new (declare([ OnDemandGrid, Selection, Selector ]))(options, 'gridcontainer');
});
When using a custom grid query based on defects I often filter based on the tags of the linked user story. I would like to use the actual feature hierarchy. e.g. Show all defects where the linked story is under a given feature or initiative. I could not work this out from looking at the documentation
Tags attribute exists on Artifact object from which Requirement inherits, hence Requirement.Tags can be traversed. Feature attribute does not exist on Requirement. It exists on HierarchicalRequirement, which inherits from Requirement, hence Requirement.Feature cannot be traversed.
In this context a custom grid may not be a suitable choice. But a custom app can be written that shows all those relationships. Here is a custom app that has two comboboxes: a Release and a Feature. The Feature combobox is populated based on the selection in the Release combobox. When a feature is selected from the second combobox a grid is populated with the feature's child stories and defects (if any) associated with those stories.
You may see the full code in this repo, and copy the html file into a custom page.
Here is the js file:
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'release',
comboboxConfig: {
fieldLabel: 'Select a Release:',
labelWidth: 100,
width: 300
},
addContent: function() {
this._makeCombobox();
},
onScopeChange: function() {
this._makeCombobox();
},
_makeCombobox: function() {
if (this.down('#features')) {
this.down('#features').destroy();
}
var features = Ext.create('Rally.ui.combobox.ComboBox',{
id: 'features',
storeConfig: {
model: 'PortfolioItem/Feature',
fetch: ['FormattedID','Name','Release', 'UserStories'],
pageSize: 100,
autoLoad: true,
filters: [this.getContext().getTimeboxScope().getQueryFilter()]
},
fieldLabel: 'select Feature',
listeners:{
ready: function(combobox){
if (combobox.getRecord()) {
console.log('ready',combobox.getRecord().get('_ref'));
this._onFeatureSelected(combobox.getRecord());
}
else{
console.log('selected release has no features');
if (this.down('#grid')) {
this.down('#grid').destroy();
}
}
},
select: function(combobox){
if (combobox.getRecord()) {
console.log('select',combobox.getRecord().get('_ref'));
this._onFeatureSelected(combobox.getRecord());
}
},
scope: this
}
});
this.add(features);
},
_onFeatureSelected:function(feature){
console.log('feature', feature.get('Name'));
var f = {
FormattedID: feature.get('FormattedID'),
Name: feature.get('Name'),
_ref: feature.get("_ref"),
UserStories: []
};
var collection = feature.getCollection('UserStories', {fetch: ['Name','FormattedID','Owner', 'Defects']});
var that = this;
var count = collection.getCount();
console.log(count);
var stories = [];
var pendingStories = count;
collection.load({
callback: function(records, operation, success){
Ext.Array.each(records, function(story){
var s = {
FormattedID: story.get('FormattedID'),
Name: story.get('Name'),
_ref: story.get("_ref"),
DefectCount: story.get('Defects').Count,
Defects: []
};
var defects = story.getCollection('Defects');
var defectcount = defects.getCount();
var pendingDefects = defectcount;
defects.load({
fetch: ['FormattedID'],
callback: function(records, operation, success){
Ext.Array.each(records, function(defect){
s.Defects.push({_ref: defect.get('_ref'),
FormattedID: defect.get('FormattedID')
});
}, this);
--pendingDefects;
if (pendingDefects === 0) {
console.log(story.get('FormattedID') + ' - ' + story.get('Name'));
--pendingStories;
if (pendingStories === 0) {
console.log('stories inside callback',stories);
}
}
console.log('makeGrid');
that._makeGrid(stories);
},
scope: this
});
stories.push(s);
}, this);
}
});
},
_makeGrid: function(stories) {
var c = Ext.create('Ext.Container', {
layout: {
type: 'absolute'
},
x: 400
});
this.add(c);
this._store = Ext.create('Rally.data.custom.Store', {
data: stories,
pageSize: 100,
remoteSort:false
});
if (!this.down('#grid')){
c.add({
xtype: 'rallygrid',
itemId: 'grid',
store: this._store,
columnCfgs: [
{
text: 'Formatted ID', dataIndex: 'FormattedID', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name', dataIndex: 'Name'
},
{
text: 'Defect Count', dataIndex: 'DefectCount'
},
{
text: 'Defects', dataIndex: 'Defects',
renderer: function(value) {
var html = [];
Ext.Array.each(value, function(defect){
html.push('' + defect.FormattedID + '')
});
return html.join(', ');
}
}
]
});
}
else{
this.down('#grid').reconfigure(this._store);
}
}
});
I am working on a dojo grid, which is the new dojo dgrid but i have the dgrid working by calling the id on a html markup file but i need to create a widget like thing that will have my grid in it and be able to access it via the html using the dojotype.
I have spend like three days working on that, but for some reason my grid wouldn't show if i declare it within a widget i created.
below is my code sample:
require([
"dojo/_base/declare", "dojo/dom-construct", "dojo/parser", "dojo/ready",
"dijit/_WidgetBase", "dijit/_TemplatedMixin", "dgrid/Grid", "dgrid/Keyboard",
"dgrid/Selection","dojo/text!./templates/dumHTML.html", "dojo/domReady!"
], function(declare, domConstruct, parser, ready, _WidgetBase, _TemplatedMixin, Grid, Keyboard, Selection, template) {
declare("Grid", [_WidgetBase, _TemplatedMixin], {
templateString: template,
widgetsInTemplate: true,
postCreate: function() {
var self = this;
this.inherited(arguments);
this._showGrid();
},
_showGrid: function() {
//json data string
var gridData =[
{'id': '10', 'filename':'budget.pdf','icon':'pdf'},
{'id': '20', 'filename':'thevampirediary.avi','icon':'xsl'},
{'id': '30', 'filename':'budget2.xsl','icon':'xsl'},
{'id': '40', 'filename':'budget3.doc','icon':'doc'},
{'id': '50', 'filename':'thevampirediary.avi','icon':'xsl'}
];
// Create a new constructor by mixing in the components
var DGrid = declare([Grid, Keyboard, Selection]);
var grid = new DGrid( {
columns: {
ID: {
label: " ",
field: "id",
hidden: true,
sortable: false,
formatter: function(id) {
return '<div style="visibility: hidden>'+id+' </div>';
}
},
filename: {
field: "filename",
label: "File name",
sortable: true,
formatter: function(filename) {
return '<div style="float:left ">'+filename+' </div>';
}
},
icon: {
field: "icon",
label:" ",
sortable: false,
formatter: function(icon) {
return '<img src="resources/' + icon + '.png" width="20px" hieght="20px"/>';
}
}
},
// for Selection; only select a single row at a time
selectionMode: "single",
// for Keyboard; allow only row-level keyboard navigation
cellNavigation: true
}, "grid");
grid.renderArray(gridData);
}
});
ready( function() {
// Call the parser manually so it runs after our widget is defined,
// and page has finished loading
parser.parse();
});
});
I am just a beginner of dgrid and meet the same problem. After reading this article, I resolve it. https://github.com/SitePen/dgrid/wiki/Working-with-Widgets
The solution is: mix DijitRegistry in Dgrid instance.
Here is my code. Hope it will be helpful for beginners. ModuleWithGuideBar is my custom widget(declared with TemplatedMixin, _WidgetsInTemplateMixin).
define([
"dojo/_base/declare",
"dijit/registry",
"common/widget/ModuleWithGuideBar",
"dgrid/OnDemandGrid",
"dgrid/Keyboard",
"dgrid/Selection",
"dgrid/extensions/DijitRegistry",
"dojo/store/Memory",
"dijit/layout/ContentPane"
], function (declare, registry, ModuleWithGuideBar, OnDemandGrid, Keyboard, Selection, DijitRegistry, Memory, ContentPane) {
return declare("app.management.module.event", [ModuleWithGuideBar], {
class:"module_event",
_grid:null,
postCreate:function () {
this.inherited(arguments);
var gridContainer = new ContentPane({region:'center'});
//add to data-dojo-attach-point
this.moduleContent.addChild(gridContainer);
var memoryStore = new Memory({data:[
{ first:"Bob", last:"Barker", age:89 },
{ first:"Vanna", last:"White", age:55 },
{ first:"Pat", last:"Sajak", age:65 }
]});
this._grid = new declare([OnDemandGrid, Keyboard, Selection, DijitRegistry])({
columns:{
first:{ label:"first" },
last:{ label:"last" },
age:{ label:"age" }
},
store:memoryStore
});
gridContainer.addChild(this._grid);
}
});
});