Update datapanel when the model is switched - javascript

I have an application linked with my autodesk account and I also have a panel dashboard that load the data from the current model, the issue is that this panel isnt update when I choose another model into the hub.
Im trying to find the Autodesk.viewing.EVENT that can record this step but I couldnt. All of them have been tryed and whitout success...
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT,
Autodesk.Viewing.MODEL_ADDED_EVENT...

I have got this working. Don't worry about events, it's working fine.
Here are my changes and additions:
PanelBarChart.js(same goes in piechart as well)
loadWithCustomProperty(property) {
this.propertyToUse = property;
this.chart.destroy();
this.drawChart();
}
After creating list in dashboard.js, add the change event:
$('#'+_this._selectcontainer).change(function() {
console.log($('#'+_this._selectcontainer+' option:selected').text())
_this._panel.loadWithCustomProperty($('#'+_this._selectcontainer+' option:selected').text())
});
Here _this._selectcontainer is UUID, because you're adding multiple chards, so id needs to be unique.

Related

How to get titles of the pages of a PowerBI report in JavaScript or C#?

I have a PowerBI report having 5 different pages. The code below helps me to set a desired page as the default page when the web page I embedded the PowerBI report comes up to my screen.
var report = powerbi.embed(reportContainer, config);
report.on('loaded', () => {
report.getPages().then(pages => pages[3].setActive());
});
Two questions I have at this point that I couldn't find answers:
1- How can I set a page as default by using its exact name instead of the array number? I need to do something like: pages => pages['Overall Summary'].setActive();
2- Is there a way to receive the pages on C#, or pass the ones I am getting to the C#? The reason I ask this that I want to hide some pages based on the user logged in.
Any advice would be appreciated. Thanks!
EDIT: By saying pagename, I meant the tab names at the bottom of the powerBI report, each page has a different name as to been:
1- Unfortunately the "page" object is not holding an ID or INDEX property currently. You can see all the properties by doing console.log(page); However, we have the "displayname" property, and this is what I was looking for. All we need to do is to save the pages in an array object and use a counter to have the index of that while looping. Check the code below that handles this issue:
report.on('loaded', () => {
report.getPages().then(function (pages)
pages.forEach(function(page) { pageArray.push(page);});
var i = 0;
while (i < pageArray.length) {
if (pageArray[i].displayName == \"" + activePageSet + "\") { pages[i].setActive(); }
i = i + 1;
}
});
});
2- There is no way to reach the pages in the C# currently, only JS works. To hide any page, you can go to PowerBI Report Editor, simply right click any page and click "Hide Page" option. For such cases you need to hide/unhide pages based on a user or a group, this link has a great solution for that:
https://community.powerbi.com/t5/Developer/Power-BI-Embed-Page-Menu-as-List-View/td-p/174938
For
Can you think about updating the embed config to provide the page name in the config. So you'll not have to update it after calling embed.
This will load the report with the provided page as the Active Page:
var config = {
...
pageName: 'Overall Summary'
};
Reference: https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details
Not sure about C#, In JS Client, Power BI returns the pages object which has all the information about pages.
You'll not be able to modify the navigation pane without editing the source report which will update it for all the users. So for hiding pages based on users, you can add your own navigation pane and then only display the restricted set of pages there. You can then update the active page to change to that page.
For this you can follow the community link Erray has shared.

update values in jquery based on angular change

In my application I have used calendar widget using fullcalender.js:
$(document).ready(function() {
$('#profile-calendar').fullCalendar({
events: $scope.calendarEvent
});
});
What I wanted to do is, I need to give different values to the event attribute based a angular event. the below code snippet is what I have used to update the $scope.calendarEvent attribute.
$scope.$on('profile_selection',function(event, args){
$scope.calendarEvent = $rootScope.calendarEvent;
$scope.$apply();
});
But this is not working as I expected, the calendar is showing the initial value given to the $scope.calendarEvent. What should I do to make the $scope.calendarEvent take the changed value by the broadcast message and update dynamically.

Angular Material md-chips not refreshing correctly

I am developing an app that works with a "Widget layout".
The user gets a page which is a Dashboard with different widgets he can interact with, such as a table, graphs etc.
I am adding a global "filter" using <md-chips>, the objective of this is having filters that are shared by all the widgets and can be updated by all the widgets.
My Filter list uses <md-chips>, with read-only and md-removable set to True. So filters can only be deleted, or added by interacting with the widgets (so only added programmatically).
One of the feature of this "module" is to add a new filter on a field when a Graph element is clicked.
Example :
Here is my Filters list before clicking a Graph element
Now I click on a Graph element which is in a Child controller of my Filter controller, it will $emit an event to say to the global controller : "I want to update the filters ! here is the filter to add"
And the Filter Controller will get that event and update his filters accordingly ($scope.tags is the list of filters and the model used in <md-chips>)
// CHIPS
$scope.tags = [];
$scope.readOnly = true;
$scope.removable = true;
// FILTER LISTENER
$scope.$on('filterChildChanged', function (event, filter) {
$scope.tags.push(filter);
console.log($scope.tags);
console.log("Parent event fired !");
});
At that point I would expect the <md-chips>element to refresh, because $scope.tags just got a new filter :
<md-chips
ng-model="tags"
readonly="readOnly"
md-removable="removable"
id="filters">
<md-chip-template>{{$chip.value}}</md-chip-template>
</md-chips>
But instead, nothing happens! and the weird part is, it refreshes when I click on one of the existing chip (I had a "test" chip) !
TESTS :
So when I push a test chip on the array before rendering :
$scope.tags.push({field: "testField", value: "test"});
And click on a bunch of Graph elements, $scope.tags is perfectly updated, BUT the visual stays the same until I select the chip "test", then all the <md-chips> appear just like it triggered some refresh function.
Any hint on why the <md-chips> element is not refreshed as $scope.tags (its model) is updated BUT is updated when a chip is selected ?
I tried to trigger md-on-select to force this behavior to happen every time I add a new filter to $scope.tags but I got no luck so far !
Thanks for reading !
NOTE : I am using the latest version of Angular MATERIAL (HEAD MASTER) see doc here : https://material.angularjs.org/HEAD/ | built from the GitHub repository.
EDIT : The problem comes from $$hashKey not being added to the objects, they are only added when I click on one of the existing tags, I need to find a way to add this $$hashKey attribute when I add a new filter
The problem came from the absence of $$hashKey when I added a new filter to my filters model for my chips ($scope.tags).
So I just needed to change
$scope.tags.push(filter);
to
$scope.$apply(function () {
$scope.tags.push(filter);
});
And here is my console.log test
Good thing I learned :
the <md-chips> directive only knows it needs to be updated if its <chip> objects have a $$hashKey
See this on scope.$apply

Pass information to bootstrap modal from Angular.js controller

Simplified problem
I have a store. For a product to be included in the store there needs to be a shelf for it. So, to add a new product to the store the workflow is:
Add a shelf
Add product to that shelf
(The workflow can not be changed)
Realization
The shelf is realized by a row in a table, which in turn is controlled by an Angular.js controller (each shelf is an object in an array). To add an product the user selects "create product" in a drop-down menu that is present on each row. This will show an bootstrap modal where I have from a controller added a tab for each product that is possible to add (since each product needs configuration :) ) , then when the user presses a "create" button in the modal a JavaScript method is called interfacing a REST interface to add the product (the UI is updated by a Socket.io event send from the server when the product has been added successfully.
Problem
The JavaScript method (CreateProduct) needs to now what row (R) was affected as well as what tab (T) was selected so that the "onclick" method for the button is CreateProduct(R, T);
My current solution is pretty ugly imho, I have two global variables for R and T, then I use jQuery to capture show event and tab event from the modal, the link in the dropdown has a field "data-row-id" that is identifying the row
HTML (Jade) snippet from dropdown menu:
a(data-toggle="modal", href="#createProduct", data-row-id="{{row.RowID}}") Create Product
JavaScript:
var R = null;
$('#productModal').on('show.bs.modal', function(e) {
R = $(e.relatedTarget).data('row-id');
});
var T = null;
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
T = e.target.text;
});
I hope there is a better solution to this, I probably am just thinking a bit upsidedown due to inexperience with Angular.js , perhaps there is a way to pass these through the model? Perhaps add these to the modal controller, but then, how to pass the row? My dream would be something like this on the button code
button(type="button", class="btn btn-default", data-dismiss="modal", ng-click="storeCtrl.CreateProduct({{modalCtrl.shelf, modalCtrl.Product)") Create Product
I found a better way (at least I don't need to use jQuery) using ModalService
I created a CreateProductModalController having a variable selectedProduct, this is set on a ng-click event in the tab
ul(class="nav nav-pills", id="tabContent")
li(ng-repeat="prod in products", ng-class="{active: $index == 0}", ng-click="activateTab(prod.name)")
a(href="#{{prod.name}}", data-toggle="tab") {{prod.name}}
The ModalService is called with the rowID that was clicked.
The only problem I have now is that all must be in $scope, I want it to be more encapsulated

Many to many relationship events with backbone.js

I have a many-to-many relationship with two of my backbone.js models implemented using a pivot table on the serverside. I'm trying to figure out how to structure it clientside. My current structure is:
1) I have a Tag model, and a TagView which renders a checkbox and the tag label, I have a checked event on the checkbox which does nothing at the moment.
I have a TagsCollection, which holds a bunch of Tags.
I have a TagsCollectionView, which binds add, reset etc of the TagsCollection, and adds TagViews for the added Tags, renders them, and appends the html to its current html (on reset, the html is reset).
I have a global TagCollection instance which contains all the possible tags
I have a Notes Model which contains an (empty) TagCollection called selectedtags on init.
The server returns an array of selected tagids for each Notes, which I add to its TagCollection.
Now comes the hard part, tying it all together.. my NotesView has its own TagsCollectionView which is bound to the global TagsCollection (so it can list all the Tags).. now, how do I get a checked event on the checkedbox of its sub TagViews to trigger an add to this Notes model's selectedtags? Should I provide a reference to the this Notes model instance to the TagsCollectionView on init which then provides it to all the TagViews it creates, whose checked event then adds/removes items from that model? That's the best way I can figure out how to do this, any other thoughts would be appreciated.
View is only for visual display of model. Please specify the need for TagsCollectionView in more details:
Use change event for checking the checkbox.
I would advise incremental coding. First work with the Tag and TagView, As it works, continue adding collection to hold the Tags. After that you can add Notes. It's a 'divide and conquer' :)
Don't confuse with the whole design, it is very simple when you start.
I can not provide the whole design due to lack of requirement details. but, I think below code should trigger the starting point of your design.
var TagsCollectionView=Backbone.View.extend({
el:$(),
});
var Tag=Backbone.Model.extend({
defaults:{
// define the default properties
}
});
var TagView=Backbone.View.extend({
el:$("body"),
events:{
'change #checkBox':'customFunction'
},
initialize: function(){
_.bindAll(this, 'render','customFunction');
this.render();
},
render:function(){
var tag=new Tag();
// code to render the checkbox and label
},
customFunction:function(){
// whatever you want to do after checking event of checkbox
}
});
// collection to collect all the tags
var TagCollection=Backbone.Collection.extend({
model:Tag
});
var Notes=Backbone.Model.extend({
defaults:{
'tagCollection':TagCollection
}
});
// you do not require TagsCollectionView

Categories

Resources