-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathknapsack.js
More file actions
208 lines (188 loc) · 7.21 KB
/
knapsack.js
File metadata and controls
208 lines (188 loc) · 7.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/* Burglar's Dilemma: interactive lesson of Knapsack Problem */
//checks to see how page should be initialized
//determines if local storage should be used or not
function pageInitialization(){
var totalWeight = 0;
var totalValue = 0;
//if not the first time opening page or not following a start-over click
if (localStorage.getItem('ifStorage') == 'yes') {
//check if local storage should be restored for each DOM and make sure DOM's properties are correct
var sackData = localStorage.getItem('sack');
var houseData = localStorage.getItem('house');
var chartData = localStorage.getItem('chart');
if (sackData) {
$('#sack').html(sackData);
$('.item').attr("style","")
.css("display", "inline-block");
//calculate total weight and total value of objects in sack to restore display
$.each($('.item img'), function() {
if ($(this).attr("data-location") == "sack") {
totalWeight += parseInt($(this).attr("data-weight"));
totalValue += parseInt($(this).attr("data-value"));
}
});
}
if (houseData) {
$('#house').html(houseData);
$('.item').attr("style","")
.css("display", "inline-block");
}
if (chartData) {
$('#chart').html(chartData);
}
$('#weight').html(totalWeight);
$('#value').html(totalValue);
}
//first time loading page or following a start-over click
else {
//initialize data-location value of each item
var items = $('.item img');
items.attr("data-location","house");
//set flag indicating a start-over button click to 'no'
localStorage.setItem('ifStorage', 'yes');
}
//to be used in main function
return [totalWeight, totalValue];
};
//updates the local storage of all the html on the page that may be changed
function updateLocalStorage() {
function saveElement(object) {
//save the object id's html
var objectHTML = $('#'+object).html();
localStorage.setItem(object, objectHTML);
};
saveElement("sack");
saveElement("house");
saveElement("chart");
};
//if in "house" itemBox (left), move to "sack" itemBox (right) and vice versa
function moveItem(item) {
if (item.attr("data-location") == "house") {
item.attr("data-location","sack");
//display item in new itemBox with animation
var new_item = $(item.parent()).hide();
$('#sack').append(new_item);
new_item.show("slow");
}
else{
item.attr("data-location","house");
//display item in new itemBox with animation
var new_item = $(item.parent()).hide();
$('#house').append(new_item);
new_item.show("slow");
}
};
//check whether totalWeight is still under 20 after new item possibly moved
function canAddToTotal(weight, totalWeight) {
return (totalWeight + weight <= parseInt($('.knapsack').attr("data-maxweight")));
};
//a tasteful alert alerting the user that they have exceeded the knapsack capacity
function tastefulAlert() {
//classic failure noise
//from http://www.youtube.com/watch?v=iMpXAknykeg
var errorSound = new Audio('SadTrombone.mp3');
errorSound.play();
$('.alert').animate({opacity: 1}, 1500);
$('.alert').animate({opacity: 0}, 1500);
};
//d3 pie chart of knapsack contents (how much room left/how much already filled)
function updatePieChart(totalWeight){
//used to fill in pie chart
var dataset = [totalWeight, 20- totalWeight];
var labels = [' kg used', ' kg available'];
var pie = d3.layout.pie();
var color = d3.scale.ordinal()
.range(["red", "gray"]);
//set pie chart dimensions
var width = 347;
var height = 347;
var outerRadius = width / 2;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
//update the chart from last move of user
$("#chart").html("");
var svg = d3.select('#chart')
.append("svg")
.attr("width", width)
.attr("height", height);
//set up groups
var arcs = svg.selectAll("g.arc")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + ", " + outerRadius + ")");
//Draw arc paths
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
//generate text labels for each wedge
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
//make sure text label isn't hidden (just omit label if pie slice to be covered too small)
.text(function(d, i) {
if ((d.value > 2) || (d.value == 0)) {
return d.value + labels[i];}
else {return d.value};
});
};
//happens after web page is loaded
$(function() {
//set up page and get totalWeight and totalValue
var dataArray = pageInitialization();
var totalWeight = dataArray[0];
var totalValue = dataArray[1];
updateLocalStorage();
//burglar on creaky floor noise loops every duration of mp3 file (approx 95 seconds)
//from https://www.youtube.com/watch?v=XBSsaK-r9nU
var backgroundNoise = new Audio('FloorCreak.mp3');
backgroundNoise.play();
setInterval(function(){var backgroundNoise = new Audio('FloorCreak.mp3'); backgroundNoise.play();}, 94000);
//controls movement of the items when user clicks each item
var items = $('.item img');
items.on('click', function(event) {
var target = $(event.target);
var weight = parseInt(target.attr('data-weight'))
//can always move item if it's in the "sack" (right) itemBox
if (target.attr('data-location') == "sack")
{
moveItem(target);
totalWeight -= weight;
totalValue -= parseInt(target.attr("data-value"));
updatePieChart(totalWeight);
$('#weight').html(totalWeight);
$('#value').html(totalValue);
}
//must check if can add weight from "house" (left) itemBox to "sack" itemBox
else if (canAddToTotal(weight, totalWeight))
{
moveItem(target);
totalWeight += weight;
totalValue += parseInt(target.attr("data-value"));
updatePieChart(totalWeight);
$('#weight').html(totalWeight);
$('#value').html(totalValue);
}
else{
tastefulAlert();
}
//update local storage of all changeable html
updateLocalStorage();
});
//when user clicks start-over button
var button = $('#startOver');
button.on('click', function(event) {
var target = $(event.target);
//set flag indicating start-over
localStorage.setItem('ifStorage', 'no');
//reload the page
location.reload();
});
});