I have a new problem with Morris.js. I am currently using the redraw function to redraw the graph on tab click in order for it to display correctly. The problem is that when doing this with the donut graphs, when the graph is redrawn, the centre label position is miscalculated. Once on the tab if you hover over a section it works fine again. If you leave the tab and come back it's fine. It is just the first time the centre text loads. I assume the redraw() in morris is not covering the text. Not sure how to tackle this one.
Here is the jsfiddle http://jsfiddle.net/d1owfmoc/1/
HTML:
<div id="tabs2">
<div id="tabs-1" class="statdiv">
<h4>Tab 1</h4>
<div class="statgrid">
<div class="col-2-6">
<div id="morris-donut-chart"></div>
</div>
</div>
<div class="statgrid">
<div class="col-4-6">
<div class="col-5-6">Item 1</div>
<div class="col-1-6">£10.00</div>
</div>
</div>
</div>
<div id="tabs-2" class="statdiv">
<h4>Tab 2</h4>
<div class="statgrid">
<div class="col-2-6">
<div id="morris-donut-chart2"></div>
</div>
</div>
<div class="statgrid">
<div class="col-4-6">
<div class="col-5-6">Item 2</div>
<div class="col-1-6">£10.00</div>
</div>
</div>
</div>
<div id="tabs-3" class="statdiv">
<h4>Tab 3</h4>
<div class="statgrid">
<div class="col-2-6">
<div id="morris-donut-chart3"></div>
</div>
</div>
<div class="statgrid">
<div class="col-4-6">
<div class="col-5-6">Item 3</div>
<div class="col-1-6">£10.00</div>
</div>
</div>
</div>
<div id="tabs-4" class="statdiv">
<h4>Tab 4</h4>
<div class="statgrid">
<div class="col-2-6">
<div id="morris-donut-chart4"></div>
</div>
</div>
<div class="statgrid">
<div class="col-4-6">
<div class="col-5-6">Item 4</div>
<div class="col-1-6">£10.00</div>
</div>
</div>
</div>
<div id="tabcontain3">
<ul class="mytabs2">
<li class="stattab1">Tab 1
</li>
<li class="stattab2">Tab 2
</li>
<li class="stattab3">Tab 3
</li>
<li class="stattab4">Tab 4
</li>
</ul>
</div>
JS:
$(function () {
$("#tabs2").tabs();
});
$('ul.mytabs a').on('shown.bs.tab', function (e) {
var types = $(this).attr("data-identifier");
var typesArray = types.split(",");
$.each(typesArray, function (key, value) {
eval(value + ".redraw()");
})
});
$(function () {
var donut1_data = [{
label: "Download Sales",
value: 12
}, {
label: "In-Store Sales",
value: 30
}, {
label: "Mail-Order Sales",
value: 20
}];
var donut1 = {
element: 'morris-donut-chart',
data: donut1_data,
resize: false
}
donut1 = Morris.Donut(donut1)
var donut2_data = [{
label: "Download Sales",
value: 10
}, {
label: "In-Store Sales",
value: 30
}, {
label: "Mail-Order Sales",
value: 20
}];
var donut2 = {
element: 'morris-donut-chart2',
data: donut2_data,
resize: false
}
donut2 = Morris.Donut(donut2)
var donut3_data = [{
label: "Download Sales",
value: 8
}, {
label: "In-Store Sales",
value: 30
}, {
label: "Mail-Order Sales",
value: 20
}];
var donut3 = {
element: 'morris-donut-chart3',
data: donut3_data,
resize: false
}
donut3 = Morris.Donut(donut3)
var donut4_data = [{
label: "Download Sales",
value: 2
}, {
label: "In-Store Sales",
value: 30
}, {
label: "Mail-Order Sales",
value: 20
}];
var donut4 = {
element: 'morris-donut-chart4',
data: donut4_data,
resize: false
}
donut4 = Morris.Donut(donut4)
});
CSS:
#morris-donut-chart svg, #morris-donut-chart2 svg, #morris-donut-chart3 svg, #morris-donut-chart4 svg {
width:250px;
height:250px;
}
#morris-donut-chart, #morris-donut-chart2, #morris-donut-chart3, #morris-donut-chart4 {
width:250px;
height:250px;
}
First of all you should replace mytabs with mytabs2 in your jquery code because you dont have a mytabs class.
After that change shown.bs.tab to click because you want to redraw the donut when a tab is clicked.
And at last, move your click function into the $(function () because the variables donut1,donut2, etc are not accessible outside function():
$(function () {
$('ul.mytabs2 a').on('click', function (e) {
var types = $(this).attr("data-identifier");
var typesArray = types.split(",");
$.each(typesArray, function (key, value) {
eval(value + ".redraw()");
})
});
});
Here's the working example: DEMO
Related
I am looking to allow only certain elements to be nested inside others and I did not managed to do so.
Example: Application element can contain only Container elements. Container only Queries, and Queries different types of Components.
Codepen - Code
HTML:
<div class="container">
<div id="cloning" class="row">
<div id="example3Left" class="list-group col">
<div class="list-group-item nested-sortable" name="container">Container</div>
<div class="list-group-item nested-1 nested-sortable" name="query">Query</div>
<div class="list-group-item nested-2" name="component text">Component Text</div>
<div class="list-group-item nested-2" name="component bool">Component Bool</div>
</div>
<div class="list-group col">
<div id="example3Right" class="list-group-item tinted nested-sortable" name="application">Application
</div>
</div>
<div style="padding: 0" class="col-12">
</div>
</div>
</div>
JAVASCRIPT:
<script>
createNesting();
var example3LeftSortable = new Sortable(example3Left, {
group: {
name: 'shared',
pull: 'clone',
put: false
},
animation: 150,
onEnd: function (/**Event*/evt, /**Event*/originalEvent) {
createNesting();
}
});
var example3RightSortable = new Sortable(example3Right, {
group: {
name: 'shared',
pull: false
},
animation: 150,
sort: false
});
function createNesting() {
// Nested demo
const container = document.querySelector("#example3Right");
var nestedSortables = [].slice.call(container.querySelectorAll('.nested-sortable'));
// Loop through each nested sortable element
for (var i = 0; i < nestedSortables.length; i++) {
new Sortable(nestedSortables[i], {
group: {
name: 'shared',
pull: false
},
animation: 150,
sort: false,
fallbackOnBody: true,
swapThreshold: 0.50
});
}
}
</script>
I'm using donut twice on the same page but somehow it's appearing in one div only whereas I defined it in two different Divs
Library : React-donut
<div className={this.state.selected == 2 ? "col-xs-6 col-sm-6 selected linkpointer" : "col-xs-6 col-sm-6 linkpointer"} onClick={this.programsClickEvent}>
<div className="card p_15 program">
<div className="mahroon-block">
<strong>Programs</strong>
</div>
<div id = "program-donut">
<Donut
chartData={[
{ name: `${this.state.programCompleted} Completed`, data: this.state.programCompleted },
{ name: `${this.state.programStarted} Started`, data: this.state.programStarted },
{ name: `${this.state.programNotStarted} Not Started`, data: this.state.programNotStarted },
]}
chartWidth={100}
chartHeight={300}
title=""
chartThemeConfig={{
series: {
colors: ['#28B463', '#F39C12 ', '#E74C3C'],
},
}}
/>
</div>
</div>
</div>
<div className={this.state.selected == 3 ? "col-xs-6 col-sm-6 selected linkpointer" : "col-xs-6 col-sm-6 linkpointer"} onClick={this.coursesClickEvent} >
<div className="card p_15 course">
<div className="mahroon-block">
<strong>Courses</strong>
</div>
<div id = "course-donut">
<Donut
chartData={[
{ name: `${this.state.courseCompleted} Completed`, data: this.state.courseCompleted },
{ name: `${this.state.courseStarted} Started`, data: this.state.courseStarted },
{ name: `${this.state.courseNotStarted} Not Started`, data: this.state.courseNotStarted },
]}
chartWidth={200}
chartHeight={300}
title=""
chartThemeConfig={{
series: {
colors: ['#28B463', '#F39C12 ', '#E74C3C'],
},
}}
/>
</div>
</div>
</div>
I'm using two different divs for both the donuts but they are appearing in first div only.
There is a great tut which illustrates how to accomplish this, however I can't seem to get it right. Here is the example and here is my take on it. And even stranger I am not getting any errors in the console.
Here is the HTML from my project locally.
<div ng-controller="DrawingsController">
<div class="controls">
<label>Filter:</label>
<button class="filter" data-filter="all">All</button>
<button class="filter" data-filter=".category-{{category}}" ng-repeat="category in categories">{{category}}</button>
<label>Sort:</label>
<button class="sort" data-sort="myorder:asc">Asc</button>
<button class="sort" data-sort="myorder:desc">Desc</button>
</div>
<div class="test">
<div id="MixItUpContainer1" class="container">
<div class="mix category-{{drawing.category}}" data-myorder="{{drawing.value}}" ng-repeat="drawing in drawings">Value : {{drawing.name}}</div>
</div>
</div>
<div class="gap"></div>
<div class="gap"></div>
</div> <!-- end of DrawingsController -->
JS:
rustyApp.controller('DrawingsController', function DrawingsController($scope) {
$scope.categories = ['Soft', 'Elements'];
$scope.drawings = [{
category: 'Elements',
value: '1',
source: 'http://placehold.it/350x150'
}, {
category: 'Elements',
value: '1',
source: 'http://placehold.it/350x150'
}, {
category: 'Elements',
value: '2',
source: 'http://placehold.it/350x150'
}, {
category: 'Soft',
value: '2',
source: 'http://placehold.it/350x150'
}, {
category: 'Soft',
value: '3',
source: 'http://placehold.it/350x150'
}];
});
I tried to use Bootstrap radio button data toggle for tabs, my render of DOM for this happens through Knockout. the tab does not seem to switch between active and inactive tab correctly.
Here is a working example: http://jsfiddle.net/msurguy/x8GvJ/
Here is how to recreate the problem (JSFiddle):
<div id="tabtest" data-bind="foreach: arrayItems">
<div data-bind="attr:{'id':'itemtab' + $index()}" class="btn-group " data-toggle="buttons-radio">
<a data-bind="attr:{href:'#entitysearchitem' + $index()}" class="btn " style="background-color: #f5f5f5" data-toggle="tab">Item</a>
<a data-bind="attr:{href:'#entitymemberssearch' + $index(),'data-index':$index}" style="background-color: #f5f5f5" class="btn " data-toggle="tab">Member</a>
</div>
<div class="tab-content">
<div class="tab-pane fade in " data-bind="attr:{id:'entitysearchitem' + $index()}">
<div class="row padding3centt">
<div class="col-xs-12">
<div class="row">
<div class="col-xs-1"></div>
<div class="col-xs-11">
<ul data-bind="foreach:interests" class="list-styled">
<li>
<span class="fontsize80" data-bind="text:Description">
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" data-bind="attr:{id:'entitymemberssearch' + $index()}">
Hello i am entitymemberssearch
</div>
</div>
<br/>
</div>
JS:
var myObject = [{
"first": "John",
"interests": [ {"Description": "Reading"}, {"Description":"Mountain Biking"}, {"Description":"Hacking"} ]
},
{
"first": "Boy",
"interests": [ {"Description":"Reading"}, {"Description":"Mountain Biking"}, {"Description":"Hacking"} ]
}]
var koData ={
arrayItems :ko.observableArray()
}
ko.mapping.fromJS(myObject, {}, koData.arrayItems);
ko.applyBindings(koData, $("#tabtest").get(0));
I have described the problem in the picture below as well. Any ideas on how to correctly get the bootstrap radio tabs to work?
You need to reconsider the approach you are trying to use : Here's a beautiful solution by Ryan Niemeyer which you can refer to..
http://jsfiddle.net/rniemeyer/cGMTV/
You need to rewrite your code in following format.
var Section = function (name, selected) {
this.name = name;
this.isSelected = ko.computed(function() {
return this === selected();
}, this);
}
var ViewModel = function () {
var self = this;
self.selectedSection = ko.observable();
self.sections = ko.observableArray([
new Section('Section 1', self.selectedSection),
new Section('Section 2', self.selectedSection),
new Section('Section 3', self.selectedSection)
]);
//inialize to the first section
self.selectedSection(self.sections()[0]);
}
ko.applyBindings(new ViewModel());
1) When a user clicks an anchor inside div with class='thumbs'
2) I want to automatically update ViewModel's IMAGE_PATH and IMAGE_DESCRIPTION
3) based on clicked thumb THUMB_PATH and THUMB_DESCRIPTION accordingly and update the UI inside div class='containt'
Short Version: I want Containt div always reflect the clicked thumb details.
Can someone please help me or suggest me resources on how to achieve that while using Knockout's Mapping Plugin?
Thanks in advance!
var data= {
"ImagesInfo": [
{
"IMAGE_PATH": "",
"IMAGE_DESCRIPTION": "",
"thumbs": [
{
"thumb_id": "1",
"THUMB_PATH": "url(http://..183.jpg)",
"THUMB_DESCRIPTION":"here is a car",
"type": "sponsor"
},
{
"thumb_id": "2",
"THUMB_PATH": "url(http://..184.jpg)",
"THUMB_DESCRIPTION":"here is a boat",
"type": "img"
},
{
"thumb_id": "3",
"THUMB_PATH": "url(http://..185.jpg)",
"THUMB_DESCRIPTION":"here is a plane",
"type": "video"
}
]
}
]
}
<div id="Images">
<div data-bind="foreach: ViewModelB">
<div class="containt" style="margin-top: 10px;">
<div data-bind="style: { backgroundImage: IMAGE_PATH }"></div>
<div data-bind="html: IMAGE_DESCRIPTION"></div>
<div style="clear: both;"></div>
</div>
<div class="thumbs" style="margin-top: 10px; margin-left: 4px">
<div data-bind="foreach: thumbs">
<a class="thumb" data-bind="style: { backgroundImage: THUMB_PATH }, attr: { id: thumb_id }"></a>
</div>
</div>
</div>
<script>
var ViewModelB = ko.mapping.fromJS(data);
ko.applyBindings(ViewModelB, document.getElementById("Images"))
</script>