(Kendo UI, Angular) Pie Chart will not center - angularjs

My markup is as follows:
<div id="severity-piechart">
<div ng-controller="SingleDetailsPieCtrl">
<div kendo-chart k-theme="'metro'" k-title="{ text: 'All Issues', positon: 'top' }"
k-series-defaults="{ type: 'pie',
labels: {
visible: true,
background: 'transparent',
template: '#= category #: \n #= value#'
} }"
k-series=" [{ data: [{category: 'Issues', value: 14, color: '#FF0044'},
{category: 'Warnings', value: 4, color: '#FFD023'},
{category: 'Messages', value: 2, color: '#0B6FE8'}],
}]"
k-legend="{ visible: false }"
style="height: 35vh" >
</div>
</div>
</div>
Whenever I try the example located here I can do whatever I want to the chart as long as I touch the style attribute. However when I do the same in this example:
<div id="severity-piechart">
<div ng-controller="SingleDetailsPieCtrl">
<div kendo-chart k-theme="'metro'" k-title="{ text: 'All Issues', positon: 'top' }"
k-series-defaults="{ type: 'pie',
labels: { visible: true, background: 'transparent',
template: '#= category #: \n #= value#' } }"
k-series=" [{data: [{category: 'Issues', value: 14, color: '#FF0044'},
{category: 'Warnings', value: 4, color: '#FFD023'},
{category: 'Messages', value: 2, color: '#0B6FE8'}],
}]"
k-legend="{ visible: false }"
style="height: 35vh; width: 50%; margin: 0 auto; display: block;" >
</div>
</div>
</div>
The chart becomes incredibly small, it's not centered, and all of the labels are clipped.
Has anyone encountered a similar situation?

Related

Vue.js - show more objects from array if they have same title

I have an array of objects:
[{
title: 'foo'
id: 1,
name: 'anne'
},
{
title: 'example',
id: 2,
name: 'anne'
},
{
title: 'ex',
id: 3,
name: 'deb'
}]
The page is already showing the first object:
{
title: 'foo'
id: 1,
name: 'anne'
},
<div class="essay">
<p class="title" >{{ selectedItem.title }}</p>
<p class="id">{{ selectedItem.id }}</p>
<p class="name"> {{ selectedItem.name }} </p>
</div>
selectedItem comes from the created() life cycle
What is the best way to display the object with the same name?
I want to have a button which if clicked, will show another title from the person name 'anne'.
Try to get the filtered array.
created() {
this.selectedItem = arr.filter(item => item.name === 'anne');
// arr is the array source variable.
}
<div v-for="item in selectedItem" :key="item.id" class="essay">
<p class="title" >{{ selectedItem.title }}</p>
<p class="id">{{ selectedItem.id }}</p>
<p class="name"> {{ selectedItem.name }} </p>
</div>
I've made a snippet, maybe it would help You :-)
We need to store state somewhere, so I've created owners variable with shown counter.
There is also a computed property that groups items by owners.
Maybe there is an easier method but...
new Vue({
el: '#app',
data: {
items: [
{ owner: "John", name: "Box" },
{ owner: "John", name: "Keyboard" },
{ owner: "John", name: "Plate" },
{ owner: "Ann", name: "Flower" },
{ owner: "Ann", name: "Cup" }
],
owners: {},
},
methods: {
more(owner) {
if (this.owners[owner].shown < this.items.filter(i => i.owner == owner).length) {
this.owners[owner].shown++;
}
}
},
computed: {
ownersItems() {
let map = {};
this.items.forEach(i => {
map[i.owner] = map[i.owner] || [];
if (this.owners[i.owner].shown > map[i.owner].length) {
map[i.owner].push(i);
}
});
return map;
},
},
created() {
let owners = {};
this.items.forEach(i => {
owners[i.owner] = owners[i.owner] || {};
owners[i.owner].shown = 1;
});
this.owners = owners;
}
})
#app {
font-family: sans-serif;
padding: 1rem;
}
.header {
font-weight: bold;
margin-bottom: .5rem;
}
sup {
background: #000;
color: #fff;
border-radius: .15rem;
padding: 1px 3px;
font-size: 75%;
}
.btn {
padding: .25rem .5rem;
border: 1px solid #ddd;
background: #eee;
border-radius: .15rem;
margin: 2px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="header">Owners</div>
<template v-for="(cfg, owner) in owners">
<strong>{{ owner }} <sup>{{cfg.shown}}</sup>:</strong>
<a v-for="(item, i) in ownersItems[owner]" :key="`${owner}_${i}`" #click="more(owner)" class="btn">{{ item.name }}</a>
|
</template>
</div>

Focus custom md-checkbox in md-select control

I have implemented select control with select all option, When I open the control, it focuses on the first option. I would like to focus on the select option or at least disable the focus.
HTML
<div ng-app="selectDemoOptGroups" ng-controller="SelectOptGroupController" >
<md-select md-selected-text="selectedText" ng-model="selectedToppings" multiple>
<div class="select-all-div" >
<md-checkbox class="select-selectAll"
>Select all</md-checkbox > </div>
<md-option ng-value="topping.name" ng-repeat="topping in toppings">{{topping.name}}</md-option>
</md-select>
JS
angular
.module('selectDemoOptGroups', ['ngMaterial'])
.controller('SelectOptGroupController', function($scope) {
$scope.toppings = [
{ category: 'meat', name: 'Pepperoni' },
{ category: 'meat', name: 'Sausage' },
{ category: 'meat', name: 'Ground Beef' },
{ category: 'meat', name: 'Bacon' },
{ category: 'veg', name: 'Mushrooms' },
{ category: 'veg', name: 'Onion' },
{ category: 'veg', name: 'Green Pepper' },
{ category: 'veg', name: 'Green Olives' }
];
$scope.selectedToppings = [];
});
https://jsfiddle.net/AlexLavriv/ya6eu8kz/5/
You can't use a div for single opotion and options for the rest. You can use the same option to display the option select all.
<md-select>
<md-option>Select all</md-option>
<md-option ng-value="topping.name" ng-repeat="topping in toppings">{{topping.name}}</md-option>
</md-select>
Working Demo: JSFiDDLE
Working Demo
Try this below way
angular
.module('selectDemoOptGroups', ['ngMaterial'])
.controller('SelectOptGroupController', function($scope) {
$scope.toppings = [
{ category: 'meat', name: 'Pepperoni' },
{ category: 'meat', name: 'Sausage' },
{ category: 'meat', name: 'Ground Beef' },
{ category: 'meat', name: 'Bacon' },
{ category: 'veg', name: 'Mushrooms' },
{ category: 'veg', name: 'Onion' },
{ category: 'veg', name: 'Green Pepper' },
{ category: 'veg', name: 'Green Olives' }
];
$scope.toppings.unshift( { category: 'select', name: 'Select all' })
$scope.selectedText = $scope.toppings[0].name;
});
.select-selectAll{
text-align: left;
padding-left: 10px;
/* padding-right: 16px; */
display: flex;
cursor: pointer;
position: relative !important;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
width: 95%;
-webkit-transition: background .15s linear;
transition: background .15s linear;
/* padding: 0 16px; */
height: 48px;
}
.select-selectAll div.md-icon{
left:10px;
}
.select-all-div:hover{
background: rgb(238,238,238);
}
<div ng-app="selectDemoOptGroups" ng-controller="SelectOptGroupController" >
<md-select md-selected-text="selectedText" ng-model="selectedToppings" multiple>
<md-option ng-value="topping.name" ng-repeat="topping in toppings">{{topping.name}}</md-option>
</md-select>
</div>

Pie chart with data [] dont show any message

Hi everyone I have a pie chart made with nvd3 and when graph.data=[] it doenst show anything.. I want to display a simple message like "No data to show"
View:
<tab ng-if="dataConsNetfilter" heading="Summary" disable="!tabClick" active="true">
<p>{{dataConsNetfilter}}</p>
<div class="no-data" ng-if="dataConsNetfilter.data.length==0">
<img src="/assets/img/nodata.png"/>
<h3>No Data</h3>
</div>
<div class="col-md-12" style="text-align:center;margin-bottom:30px" ng-repeat="graph in dataConsNetfilter.types" resize>
<img ng-if="!graph.options" style="height:32px;margin:50px auto;" src="/assets/img/loader.gif" />
<div ng-if="graph.options && graph.data.length>0">
<center><nvd3 options='graph.options' data="graph.data"></nvd3></center>
<br>
</div>
</div>
</tab>
Logs from view:
{"types":[{"type":"netfilter.nfacct_bytes","options":{"chart":{"type":"pieChart","height":500,"width":1000,"margin":{"top":20,"right":20,"bottom":50,"left":55},"noData":"No data to show in the specified range","legend":{"rightAlign":false},"showValues":true,"legendPosition":"right","labelType":"percent","donut":true,"donutRatio":0.35,"duration":500,"xAxis":{"axisLabel":""},"yAxis":{"axisLabel":"Total","axisLabelDistance":-10}}},"data":[]}]}
Options:
var options = {
chart: {
type: 'pieChart',
height: 500,
width:1000,
margin : {
top: 20,
right: 20,
bottom: 50,
left: 55
},
noData: 'No data to show in the specified range',
legend: {
rightAlign:false,
},
valueFormat: function(d) {
return d.value;
},
x: function(d){return d.label;},
y: function(d){return d.value;},
showValues: true, //Display pie labels
legendPosition: 'right',
labelType: 'percent', //Configure what type of data to show in the label. Can be "key", "value" or "percent"
donut: true, //Turn on Donut mode. Makes pie chart look tasty!
donutRatio: 0.35, //Configure how big you want the donut hole size to be.
duration: 500,
xAxis: {
axisLabel: ''
},
yAxis: {
axisLabel: 'Total',
axisLabelDistance: -10
}
}
}
My tab is all blank and i want to show a message to inform the user... how to do this?
My solution was "ng-if="dataConsNetfilter.types[0].data.length==0"
<tab ng-if="dataConsNetfilter" heading="Summary" disable="!tabClick" active="true">
<p>{{dataConsNetfilter}}</p>
<div class="no-data" ng-if="dataConsNetfilter.types[0].data.length==0">
<img src="/assets/img/nodata.png"/>
<h3>No Data</h3>
</div>
<div class="col-md-12" style="text-align:center;margin-bottom:30px" ng-repeat="graph in dataConsNetfilter.types" resize>
<img ng-if="!graph.options" style="height:32px;margin:50px auto;" src="/assets/img/loader.gif" />
<div ng-if="graph.options && graph.data.length>0">
<center><nvd3 options='graph.options' data="graph.data"></nvd3></center>
<br>
</div>
</div>
</tab>

Highchart overflows modal window

In this plunk I have a Highcharts chart in an Angular UI modal window. The modal window has height and width declared in a class, and the chart is supposed to strech to width/height however it overflows at the bottom (possibly because it has two divs on top with text). How to make it fit?
Note: the chart has to be below the text divs, not as background.
HTML:
<script type="text/ng-template" id="myModalContent.html">
<div>some text</div>
<div>more text</div>
<div id="container" style="min-width: 300px; width:100%; height:100%;"> </div>
</script>
<button type="button" class="btn btn-default" ng-click="open()">Open me!</button>
Javascript:
var app = angular.module("app", ['ui.bootstrap']);
app.controller("ctl", function($scope,$uibModal,$timeout) {
var modalInstance;
$scope.open = function () {
modalInstance = $uibModal.open({
animation: false,
windowClass: 'the-modal',
templateUrl: 'myModalContent.html'
});
$timeout(function(){
plotChart();
});
};
var plotChart = function(){
$('#container').highcharts({
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
valueSuffix: '°C'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}, {
name: 'Berlin',
data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
}, {
name: 'London',
data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
}]
});
};
});
That is right, the presence of child div elements and setting height:100%; for chart container cause overflow for the parent container. One option to fix this issue is to use CSS3's Flexible Box Layout Module, another options are listed in this answer.
Using CSS3's Flexible Box Layout Module
Enable a Flexbox Layout for a parent container (modal dialog)
.the-modal .modal-content{ display: flex; flex-direction: column; }
and then set chart container to occupy the remaining space via flex-grow, in your case replace:
<div id="container" style="min-width: 300px; width:100%; height:100%;"></div>
with
<div id="container" style="min-width: 300px; width:100%; flex-grow: 1;"></div>
Updated plunker

Counting visible elements in ng-repeat

I want to know the number of visible elements shown after being subject to an ng-if and ng-show. Here is a simplified example:
$scope.fruits = [
{ name: 'apple', shape: 'round', color: 'red' },
{ name: 'stop sign', shape: 'pointy', color: 'red' },
{ name: 'orange', shape: 'round', color: 'orange' },
{ name: 'tomato', shape: 'round', color: 'red'}
];
<ul>
<li ng-repeat="fruit in fruits" ng-if="fruit.color=='red'" ng-show="fruit.shape=='round'">{{fruit.name}}</li>
</ul>
Is there a way to count the resulting number of items being shown?
I ended up not using the ng-if or ng-show at all, and just filtered the ng-repeat. This way, I did not have to hide anything and was easily able to get the length of the results.
<ul>
<li ng-repeat="fruit in fruits | filter:myFilter | filter:{shape:'round'} as filteredFruits">{{fruit.name}}</li>
{{filteredFruits.length}} fruits
</ul>
$scope.myFilter = function(x) {
if (x.color == 'red') {
return x;
}
}
With this you can remove your custom filter and use as keyword to get the li length.
var app = angular.module('myApp', []);
app.controller('Ctrl', function($scope) {
$scope.fruits = [
{ name: 'apple', shape: 'round', color: 'red' },
{ name: 'stop sign', shape: 'pointy', color: 'red' },
{ name: 'orange', shape: 'round', color: 'orange' },
{ name: 'tomato', shape: 'round', color: 'red'}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="Ctrl">
<ul>
<li ng-repeat="fruit in fruits| filter:{'shape':'round', 'color':'red'}" >{{fruit.name}}</li>
</ul>
</div>
try this
<ul>
<li ng-repeat="fruit in fruits | notEmpty as Items" ng-if="fruit.color=='red'" ng-show="fruit.shape=='round'">{{fruit.name}}</li>
</ul>
<p>Number of Items: {{Items.length}}</p>
You can count number of items,
$scope.fruits = [
{ name: 'apple', shape: 'round', color: 'red' },
{ name: 'stop sign', shape: 'pointy', color: 'red' },
{ name: 'orange', shape: 'round', color: 'orange' },
{ name: 'tomato', shape: 'round', color: 'red' }
];
$scope.FindVisible = function () {
var visibleObject=0;
$scope.fruits.forEach(function (v, k) {
if (v.shape == 'round' && v.color == 'red') {
visibleObject = visibleObject + 1;
}
});
alert(visibleObject);
}
<ul>
<li ng-repeat="fruit in fruits" ng-if="fruit.color=='red'" ng-show="fruit.shape=='round'">{{fruit.name}}</li>
<button ng-click="FindVisible()">Find</button>
</ul>

Resources