Angular UI-Grid and D3 graph in a row - angularjs

I am wondering if any of you had any experience with injecting a graph into a ui-grid. What I am doing, is I have a row defined as follows:
{ name:'Column Name', cellTemplate: '<spark-line-chart values="grid.appScope.valuesStacked"></spark-line-chart>'}
Spark-line-chart directive is responsible for creating a D3 chart (actually, nvd3 to be precise). This creates svg graph.
Now, each time I am trying to sort my table, all of the values within the table get sorted, apart from the graphs. So far, I am mocking up data, and use one array of values for all of the graphs.
Anyone had similar issues, and knows the answer to this question?

At first which kind of Angular module for nvd3.js are you using?
If you use angular-nvd3 you can check this example:
http://plnkr.co/edit/XESqEPwfXF3ulQkfuBOE
Pay attention that in your cell templates you must wrap the nvd3 graphic inside a <DIV> with .ui-grid-cell-contents CSS class:
<div class="ui-grid-cell-contents">
<nvd3 options="row.entity.spark.options" data="row.entity.spark.data"></nvd3>
</div>

Related

$("#highcharts-2i5ujpv-2").highcharts() is undefined

I have an AngularJS application in which I am using highcharts-ng version 0.0.86. I am generating the highchart by the following code
<highchart config="highchartsNg"></highchart>
The chart gets properly generated with this dynamic id "highcharts-2i5ujpv-2"
But whenever I type $("#highcharts-2i5ujpv-2").highcharts() in the browser console, it gives me undefined.
Also, I have other charts in my app for which I am creating the chart using jQuery inside a div container and it works fine. eg
<div id="multi-chart-container"></div>
$("#multi-chart-container").highcharts(chartconfig);
I need to understand why I does it give me undefined in the first case
Thanks in advance
Highcharts creates it's own div element with dynamic id. You need to get one level higher to get the chart:
$("#highcharts-2i5ujpv-2").parent().highcharts()
Live demo: http://jsfiddle.net/BlackLabel/5eq6yhg3/

Angularjs material one row with 2 columns

i am trying to achieve that, and can't figure how:
|-------------80%---------------------|----20%---|
one row with 2 columns with specific width.
i don't understand something, columns (usage in Material) are look to me like rows > in rows
|-------------------------------------|----//---|
|-------------------------------------|----//---|
|-------------------------------------|----//---|
and not like my example.
How can i achieve it?
After you have imported AngularJS and Angular Material (including the css file), you need to import Angular Material in your AngularJS app. To do this, you need to add the "ngMaterial" provider in your AngularJS module, like this:
var app = angular.module("myApp", ["ngMaterial"]);
(if you skip this part, it won't work).
Then you can write your HTML code as follows
<div layout="row" layout-wrap>
<div flex="80">80%</div>
<div flex="20">20%</div>
</div>
This will create a div that will act as a container. It will contain the elements you want to show and they will be aligned in a row and, if necessary, they will be displayed in a second row. In the flex property you can specify the width (as a percentage) of the element compared to the width of the container.
Obviously you can change the name of your Angular module and the number/ width of your html elements as you want.
And there you can see some examples and a bit of documentation
First you need to declare:
md-cols Number of columns in the grid.
In your case (8+2=10):
<md-grid-list md-cols="10" ...
Then your items:
<md-grid-tile md-colspan="8">...</md-grid-tile>
<md-grid-tile md-colspan="2">...</md-grid-tile>
Codepen Sample - Angular Material Docs

Apply rowTemplate on Kendo grid without overriding current

I'm using Angular 1.4 typescript, with Kendo (using angular directives).
I'm trying to make a RowTemplate for each row, to change the color based on a property of the item.
I know there are some approaches with jQuery, but I find them very displeasing... If I'm using angular, I would like to reference items with angular.
This is my HTML:
<div id="resultSubTasksGrid"
kendo-grid="resultGrid"
k-options="vm.gridOptions"
k-columns="vm.columns">
</div>
This is my gridOptions:.
gridOptions: kendo.ui.GridOptions = {
rowTemplate : "<tr data- uid='#: uid #' ng-class='sent: item.IsSent'></tr>"
}
My problem comes here: I don't want to override the full row. This approach does so. I have lot of columns, and almost all of them have celltemplates I don't want to lose (but I don't want to have them all in the RowTemplate either).
I would like to know if is it possible to have something like:
rowTemplate : "<tr data- uid='#: uid #' ng-class='sent: item.IsSent'>{{RENDERCONTENT}}</tr>"
Well, it seems that by how Kendo it's developed, once you set up a row-template, you need to go all in. There is not such thing as partial template or wrapper.
More information here.

How should I integrate my directive and scope object in the view?

In my controller I have an array of objects. The object is called Well has a few properties, one of which is Location, which stores a string like "A1", "B4", "B13", etc. The location indicates a position on a grid. The letter represents the row, and the number represents the column.
Now that I have this nice list of objects, I would like to display them all on a grid in my view. When I say grid, I mean that loosely. The grid I have come up with is a series of divs, each with an id equal to a location name.
I have created a directive called tile that will display the properties of a single object. The directive looks like so:
<div class="row">
<div class="col-md-3" ng-repeat="well in wellArray">
<ul><li ng-repeat="prop in well">{{ prop }}</li></ul>
</div>
</div>
Great! And then I can create a tile in my view for a specific Well in the list of Well objects like so:
<div tile name="{{my.getName()}}" dil="{{my.getDilution()}}"></div>
If this list of objects was ordered by the location property, I could simply turn it into an array of arrays, one array for each row, and then use a double ng-repeat in my view. Unfortunately they are not in order, and I do not want to create a sorting method given the format that the location property is in. If i were to do the double ng-repeat on this list as it is now, I would end up with a grid of tiles that are in no particular order.
Given my limited exposure to javascript, I thought of using jquery's .append() method.(note: i have referenced jquery before angular, so angular.element() will use the jquery library instead of jqlite so I can use jquery selectors) In my view I created a bunch of divs in the following format:
<div id="A1"></div>
<div id="A2"></div>
etc.
And then in my controller I created a method that attempts to append a single Well which has a location of "A1" to the element on the view that has an id="A1". My code looks like so:
angular.element('#A1').append('<div tile name="{{my.getName()}}" dil ="{{my.getDilution()}}"></div>');
I thought it would append the div with the tile directive, to the div with id="A1", however, it does nothing. In fact, there are no errors at all.
Surely my psuedo jquery approach is not the best way to go about this. Not only is it not working (no idea why, maybe because angular needs to compile something somehow), but it's also not a very Angular approach. I keep reading in tutorials and introductions to "not use jquery at all for the first few weeks" and "90% of the things you'll waste lines of code in jquery, can be done suceinctly in Angular". Someone please lend this poor excuse of a programmer a hand!!
Just following your example in comments with .append, instead of iterating over your array and appending elements to a container element, create a conceptual representation of the data, and then use it in the view.
In controller, do something like the following:
$scope.wellData = {};
for (well in wellArray){
var key = wellArray[well].getLocation();
$scope.wellData[key] = well;
}
Then in the view, do ng-repeat over wellData:
<div id="item.getLocation()" ng-repeat="item in wellData">
<div tile name="{{item .getName()}}" dil="{{item .getDilution()}}"></div>
</div>
You definitely should stay away from jQuery in controllers. Just assume that there is no DOM in controllers whenever you get the urge to do anything related to DOM. Controller deals with ViewModels which are conceptual representation of the view, but it is view-independent. Whenever you break that separation, you make your controllers harder to test, and you make your view more difficult to change. And, by going against MVVM principles, you will keep bumping into issues with AngularJS.

Angular UI bootstrap: Type ahead select multiple

I am using angular UI bootstrap type-ahead directive for type-ahead in a form
http://angular-ui.github.io/bootstrap/
I am fetching the records from remote server via $http service. It is working fine.
However I can select only one element from list at a time.
I want to select multiple values from the list and show all currently selected element in input field with a remove button just like tags for SO. The selected tags are stored in angular array model.
How to achieve this ?
I have read documentation for Angular UI bootstrap but I am not able to find anything.
This guy made a directive for this. Should do exactly what you want and it's even using the ui-bootstraps typeahead.
https://github.com/mbenford/ngTagsInput
The best solution I have found so far is io.select
it does exactly what you require, multi-select typeahead.
and the markup is neat and clean too e.g:
<oi-select
oi-options="list.id as list.description for list in lists"
ng-model="tags"
multiple
placeholder="Select">
</oi-select>
This component is also compatible with bootstrap and the new bootstrap 4.
In js file :
To list all selected items, use $item with typeahead-on-select and push to an array for ex.evtMem. delete fn to delete selected item.
HTML :
Use table to list all array values using ng-repeat. Addition to that add remove glyphicon image and function to delete corresponding item.

Resources