AngularJS Kendo chart not using complete space of screen - angularjs

I have used AngularJS,KendoCharts and Bootstrap in my project. I have used nav-tabs and have added three tabs on my screen which display three different Kendo charts. All is working well but I am facing one issue. When I click on second tab, the Kendo chart is not displayed on the whole screen but if I add a button on the screen which refresh the chart then it works fine and occupies the whole space. But why this is not occupying the whole space the first time it is shown. I tried various solutions/workarounds but none is fulfilling my criteria.
-- I added the width in the chart area of the chart and that works but then it disturbs the responsiveness of the chart.
-- I tried refresh/redraw on the chart after creating it in the angular controller/service but that also failed and gave the error that the id of the chart is undefined.
How can I refresh/redraw the chart after it is created in angular. I do not want any code in html, it should come happen in angular files. Or can this problem be resolved in any other way.

You can use Bootstrap Grid System. In your HTML, Create a row, then a column of span 12. In that column put your chart.
e.g.:
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<!-- your chart goes here -->
</div>
</div>
It should work.

How to make the Kendo chart on mobile responsive?
I've done small directive:
app.directive("chartAligner", function ($window) {
return function (scope, element) {
var _kChart;
angular.element($window).bind('resize', function () {
if (_kChart) {
_kChart.resize();
} else {
_kChart = element.getKendoChart()
}
});
};
});

Related

Passing multiple 'button' parameters to Angular component

I'm creating a reusable item picker component using Angular 1.5. The picker has a search field and a list of items to choose from. An example use case for the picker is a popup where the user selects some items and then has a "Continue" button to proceed.
Conceptually, the search field and the list of items belong to the component and the "Continue" button belongs to the surrounding dialog. However, I want to position the button next to the search field. In some cases there are no extra buttons, sometimes one extra button, sometimes two.
Something like this:
What is the best way to create such a component?
Options I've thought of:
Create a component / directive for the item picker, put the button before or after the directive in the HTML, and use CSS to position the button.
Here the positioning of the button is ugly and fragile, as it's not in the proper position within the HTML. It would probably need a wrapper div and absolute positioning on top of the picker component:
<div style="position: relative">
<item-picker></item-picker>
<button name="Continue" ng-click="submit()" style="position:absolute; top:5px; right: 5px"></button>
</div>
Somehow pass the buttons and callbacks as parameters to the item picker component. Here the ugliness is in the hard-coding of the buttons and styles and amount of buttons:
<item-picker btn1-text="Continue" btn1-style="primary" btn1-callback="submit()" btn2-text="Cancel" btn2-style="secondary" btn2-callback="cancel()"></item-picker>
I'm unsure whether the button configuration and callbacks could be passed as a single configuration object. I'm mainly concerned about the callback functions, whether they will work properly if passed through a configuration object instead of proper '&' callback binding.
Stop trying to make the picker into a component / directive and just use <ng-include> to include the picker code which reads the button configuration from the scope. Ugliness is in lack of scoping and not using components.
Is there some best practise for such cases?
One possible solution is to use ng-transclude, so your code could look something like:
Markup
<item-picker>
<button ng-click="parentScopeFn()">Btn 1</button>
...
</item-picker>
Directive
angular.module('myApp', [])
.directive('itemPicker', function() {
return {
restrict: 'E',
transclude: true,
scope: {
...
},
templateUrl: 'item-picker.html'
};
});
itemPicker template markup
<div class="item-picker">
<div class="item-picker-controls">
<div class="item-picker-search"><input type="search" ng-model="..."></div>
<div class="btn-group" ng-transclude></div>
</div>
<ul class="item-picker-list">
<li ng-repeat="item in items" ng-bind="item"></li>
</ul>
</div><!-- end item-picker template -->
Of course the above code is just an example and is making a lot of assumptions about your itemPicker component. Also, you'll still need to use CSS to position your buttons, but it might be easier to reason with b/c it'll be in the context of your component.
Note
You could also make use of "multi slot transclusion". This is probably useful in cases where the number and type of buttons you'll have is predictable and you want them arranged in a consistent way no matter how they are placed in the markup.
Hope this helps.

nvd3 chart starts out squished in browser

I have searched the internet for a solution to this problem but have yet to come across one yet. I was hoping someone here has had experience with this and can help point me in the right direction.
I have a line chart created with Angular-nvd3 and I am using Bootstrap for responsiveness. Basically I have two charts per row. The problem I am running into is that when I first load the page, the charts are squished into a small width. I am not setting the width on the charts so that it can inherit 100% width and fill the container. As soon as I do anything with the browser, such as open the console or resize the browser, the charts scale to their correct width. I was wondering if there was any way to force a resize. I had a similar issue before when using c3d3 but using chart.resize() solved the issue. I do not know if nvd3 has a similar method as I do not have as much experience with nvd3. I was wondering if there was a similar method I could use or if there was a pure way with d3 to do this.
Here are some before and after pics to help visualize the issue:
Before:
After opening the console or resizing the browser in any way, it scales correctly:
EDIT: I should add that setting a fixed width circumvents the issue but then the inherent responsiveness goes away (new problems arise where graphs overlap at smaller browser sizes)
EDIT: Added Some code snippets that I hope can help. I am using rows and columns the Bootstrap way. I am also declaring the chart options in the JS
HTML
<div class="row">
<div class="col-sm-6">
<nvd3 id="inlet" options="inletOptions" data="inletData"></nvd3>
</div>
<div class="col-sm-6">
<nvd3 id="outlet" options="outletOptions" data="outletData"></nvd3>
</div>
</div>
JS
$scope.inletOptions = {
chart: {
type: 'lineChart',
height: 300,
margin : {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function(d) { return d.x; },
y: function(d) { return d.y; }
}
};
For those running into a similar issue, please see the following posts:
https://github.com/krispo/angular-nvd3/issues/259
http://plnkr.co/edit/ncT72d?p=preview
$scope.triggerResizeEvent = function() {
window.dispatchEvent(new Event('resize'));
}
If anyone is running into this problem, for me it was actually a very simple solution without a resize event.
This is my chart.
<div id="chart" class="row">
<div class="col-xs-12">
<svg>
</svg>
</div>
</div>
If I have no data to show, I simply hide the div using JavaScript:
function ShowChart(show) {
$('#chart').css("display", (show ? "block" : "none"));
}
But it was squished when I passed "true" to the function.
My solution was that I had to first show the div, then use .update() for the graph.
So, for me, this did not work:
d3.select("#chart svg").datum(chart_data);
chart.update();
ShowChart(true);
And this did:
ShowChart(true);
d3.select("#chart svg").datum(chart_data);
chart.update()

AngularJS video issue

I am studying AngularJS by looking at the website http://campus.codeschool.com/courses/shaping-up-with-angular-js/contents and downloaded the videos, then going through the examples on my computer.
Everything went well until the video codeschool_1329.mp4, otherwise called "Shaping_Up_With_Angular_JS_Level_2b". The example works correctly when the logic for selecting the panels is in the HTML code, but when the logic is moved to a controller, it no longer works correctly. Thus I have the relevant HTML code:
<section ng-controller="PanelController as panel">
<ul class="nav nav-pills">
<li ng-class="{active:panel.isSelected(1)}">
<a href ng-click="panel.selectTab(1)">Description</a>
</li>
<!-- Repeated for Specifications and Reviews -->
</ul>
</section>
<div class="panel" ng-show="panel.isSelected(1)">
<h4>Description</h4>
<p>{{product.description}}</p>
</div>
<!-- Repeated for Specifications and Reviews -->
and for the JavaScript code I have:
app.controller('PanelController', function(){
this.tab = 1;
this.selectTab = function(setTab){
this.tab = setTab;
};
this.isSelected = function(checkTab){
return this.tab === checkTab;
};
});
exactly as in the video. The latter is with the Angular module and another Angular controller for the store.
With both Google Chrome and Firefox, when I click on the each of the tabs "Description", "Specifications" and "Reviews", the selected tab is highlighted, as in the video, albeit blue rather than dark purple, but the text that is supposed to be displayed below the selected tab does not show up at all. It looks as if there is some type of a problem with the isSelected function in PanelController with ng-show="panel.isSelected(1)", etc. in the lower part of the HTML code, although it appears to work correctly with ng-class="{active:panel.isSelected(1)}" when the tab is highlighted.
This works correctly when the logic for this is in the HTML code, as I said above, but no matter what I can do, I am unable to get this to work correctly when the logic is in PanelController.
There must be something simple that I am missing, and would be grateful to get this sorted out - many thanks.
<section ng-controller="PanelController as panel">
...
</section>
<div class="panel" ng-show="panel.isSelected(1)">
Only the section element is controlled by the panel controller, but you're trying to use panel.isSelected(1) out of that section. So that can't work.
Put the div inside the section, or wrap everything with another div and move ng-controller="PanelController as panel"to that wrapping div.

How to render basic HTML code with html elements in a view

I am having a form html as follows:
<div class=\"container\">\r\n\t<div class=\"clearfix row
\">\r\n\t\t<div class=\"col-md-12 column\">\r\n\t\t\t<h3>\r\n\t\t\t\tNew form created\r\n\t\t\t<\/h3
>\r\n\t\t\t<div class=\"form-group\">\r\n\t\t\t\t <label><strong>Enter name<\/strong><\/label><input
name=\"1430985388220267#enter_name\" id=\"1430985388220267\" class=\"form-control\" grid-name=\"Enter
name\" type=\"text\" \/>\r\n\t\t\t<\/div>\r\n\t\t<\/div>\r\n\t<\/div>\r\n<\/div>
This form i want to display in mobile app. The mobile app i have developed in ionic framework and cordova with angular JS. When i am trying to show the form as html then it is getting rendered with basic elements like header, bold, labels like content but the input tag it is not showing or else i can say the html's basic data input elements like checkbox, radio button etc are not displayed. I am doing this in the view:
<ion-view title="Fill the Form">
<ion-content class="padding-vertical" ng-repeat="htmlValue in HTML">
<div ng-bind-html="getHtml(htmlValue)">
</div>
{{htmlValue}}
<div class="clearfix"></div>
</ion-content>
</ion-view>
my getHtml function is this:
$scope.getHtml = function(html){
var trusted = $sce.trustAsHtml(html);
return trusted;
};
i have also modified:
angular.module('iot', ['ionic','chart.js','ngSanitize'])
I am pushing the code from REST response into array called HTML
but still i am not getting the expected output what else has remained in this case? Any help would be truly appreciated.
Use filter:
// Filter to enable HTML tags
app.filter('unsafe', function ($sce) {
return function (val) {
return $sce.trustAsHtml(val);
};
});
Then include this within your HTML tag along with filter ('unsafe' in this case), for example:
<!-- i.detail will be your valuable -->
<div ng-bind-html="i.detail | unsafe"></div>

Get active slide index outside angular-ui bootstrap carousel

I have a problem getting the active slide in an Angular-UI Bootstrap carousel outside the carousel.
I have a panel, with the carousel inside, and want to put buttons in the footer of the panel that makes actions using the selected slide, but using jquery selectors is not an option.
I want to implement it using something in pure angular.
I think I can use the active attribute, but maybe there is something clever that can do the trick more smoothly.
Some code (Jade syntax):
.panel.panel-info
.panel-body
carousel.imgCarousel(interval='5000')
slide(ng-repeat='media in selCard.superviseTab.media')
img.img-responsive(preload-image ng-src='/api/cards/{{selCard.superviseTab.sID}}/media/{{$index}}')
.carousel-caption
multiSelect
h4 Slide {{$index+1}} of {{selCard.superviseTab.media.length}}
p {{media.originalFilename}}
.panel-footer
.navbar-collapse.collapse
ul.nav.navbar-nav.navbar-left
li
a.btn.btn-danger
i.fa.fa-unlink
If you look at the AngularUI documentation, you can see this is how the slides are integrated into the HTML:
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
...
</slide>
</carousel>
We can see that the active slide is determined by the active property on each slide.
So, you should be able to iterate through the slides and return the first slide with the active property on it. As long as you haven't modified the slides array outside of this carousel, it should give you the index of the current slide.
For example, something like:
function isActive(slide) {
return slide.active;
};
$scope.getActiveSlide = function() {
var activeSlides = $scope.slides.filter(isActive)[0];
//return the first element, since the array should only return one item
};
Should do the job (or however you choose to implement your find functionality).

Resources