diff --git a/index.html b/index.html index 9301601..603404e 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@ font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif; font-size: 12px; background: #fff; - margin: 45px; + margin: 10px 20px; border-collapse: collapse; text-align: center; } @@ -48,7 +48,7 @@ padding: 10px 8px; border-bottom: 2px solid #6678b1; } - td + td { color: #669; padding: 9px 8px 0px 8px; @@ -56,6 +56,7 @@ tbody tr:hover td { color: #009; + background: #eee; } td.S { color: #FB3; @@ -69,6 +70,9 @@ td.C { color: #38F; } + td.negative { + text-decoration: line-through; + } div.facet { margin-left:10px; } @@ -130,9 +134,10 @@
Nikki's wardrobe. By Ivan's workshop
服装数据来自jillhx@贴吧 20150701
- Update 20150702:
+ Update 20150704:
衣服信息纠错请去jillhx的新衣柜楼汇报
功能错误或者有新需求请去主贴汇报
@@ -190,18 +195,19 @@
- 拥有 + 拥有 - 没有 + 没有

-
- [测试] 不要再去挑饰品了,直接用下面这些就可以了 -
+
+ 已选择的衣服 自动选择饰品 +
+
@@ -228,17 +234,5 @@ googletag.cmd.push(function() { googletag.display('div-gpt-ad-1433922605968-0'); });
-
- - - - -
diff --git a/model.js b/model.js index 043603d..06ba3e7 100644 --- a/model.js +++ b/model.js @@ -1,5 +1,7 @@ // Ivan's Workshop +var FEATURES = ["simple", "cute", "active", "pure", "cool"]; + // parses a csv row into object // Clothes: name, type, id, stars, gorgeous, simple, elegant, active, mature, cute, sexy, pure, cool, warm,extra // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @@ -36,10 +38,28 @@ Clothes = function(csv) { calc: function(filters) { var s = 0; var self = this; + this.tmpScoreByCategory = ScoreByCategory(); for (var i in FEATURES) { - var f = FEATURES[i]; - if (filters[f] && filters[f] * self[f][2] > 0) { - s += filters[f] * self[f][2]; + var f = FEATURES[i]; + if (filters[f]) { + var sub = filters[f] * self[f][2]; + if (filters[f] > 0) { + if (sub > 0) { + this.tmpScoreByCategory.record(f, sub, 0); // matched with major + } else { + this.tmpScoreByCategory.record(f, 0, sub); // mismatch with minor + } + } else { + if (sub > 0) { + this.tmpScoreByCategory.record(f, 0, sub); // matched with minor + } else { + this.tmpScoreByCategory.record(f, sub, 0); // mismatch with major + } + + } + if (sub > 0) { + s += sub; + } } } @@ -71,6 +91,31 @@ Clothes = function(csv) { }; } +function ScoreByCategory() { + var initial = {}; + for (var c in FEATURES) { + initial[FEATURES[c]] = [0, 0]; + } + return { + scores: initial, + // score: positive - matched, negative - no matched + record: function(category, major, minor) { + this.scores[category] = [major, minor]; + }, + add: function(other) { + for (var c in other.scores) { + this.scores[c][0] += other.scores[c][0]; + this.scores[c][1] += other.scores[c][1]; + } + }, + round: function() { + for (var c in this.scores) { + this.scores[c][0] = Math.round(this.scores[c][0]); + this.scores[c][1] = Math.round(this.scores[c][1]); + } + } + }; +} function MyClothes() { return { @@ -152,6 +197,87 @@ var clothesSet = function() { return ret; }(); +var shoppingCart = { + cart: {}, + totalScore: fakeClothes(this.cart), + clear: function() { + this.cart = {}; + }, + contains: function(c) { + return this.cart[c.type.type] == c; + }, + remove: function(c) { + delete this.cart[c]; + }, + putAll: function(clothes) { + for (var i in clothes) { + this.put(clothes[i]); + } + }, + put: function(c) { + this.cart[c.type.type] = c; + }, + toList: function(sortBy) { + var ret = []; + for (var t in this.cart) { + ret.push(this.cart[t]); + } + return ret.sort(sortBy); + }, + calc: function(criteria) { + for (var c in this.cart) { + this.cart[c].calc(criteria); + } + // fake a clothes + this.totalScore = fakeClothes(this.cart); + } +}; + +function accScore(total, items) { + if (items <= 3) { + return total; + } + return total * (1 - 0.06 * (items-3)); +} + +function fakeClothes(cart) { + var totalScore = 0; + var totalAccessories = 0; + var totalScoreByCategory = ScoreByCategory(); + var totalAccessoriesByCategory = ScoreByCategory(); + var numAccessories = 0; + for (var c in cart) { + if (c.split('-')[0] == "饰品") { + totalAccessories += cart[c].tmpScore; + totalAccessoriesByCategory.add(cart[c].tmpScoreByCategory); + numAccessories ++; + } else { + totalScore += cart[c].tmpScore; + totalScoreByCategory.add(cart[c].tmpScoreByCategory); + } + } + totalScore += accScore(totalAccessories, numAccessories); + for (var c in totalAccessoriesByCategory.scores) { + totalAccessoriesByCategory.scores[c][0] = accScore(totalAccessoriesByCategory.scores[c][0], + numAccessories); + totalAccessoriesByCategory.scores[c][1] = accScore(totalAccessoriesByCategory.scores[c][1], + numAccessories); + } + totalScoreByCategory.add(totalAccessoriesByCategory); + totalScoreByCategory.round(); + + var scores = totalScoreByCategory.scores; + return { + name: '总分', + tmpScore: Math.round(totalScore), + toCsv: function() { + return [this.name, '', '', scores.simple[0], scores.simple[1], scores.cute[0], scores.cute[1], + scores.active[0], scores.active[1], scores.pure[0], scores.pure[1], scores.cool[0], + scores.cool[1], '', '']; + } + }; +} + function realRating(a, b, type) { real = a ? a : b; symbol = a ? 1 : -1; @@ -210,7 +336,7 @@ function getCookie(c_name) { return unescape(document.cookie.substring(c_start,c_end)) } } - return "" + return ""; } function setCookie(c_name,value,expiredays) { @@ -230,21 +356,4 @@ function save() { setCookie("mine2", txt, 3650); } return myClothes; -} - -function backfillTag() { - for (var type in clothesSet) { - var cs = clothesSet[type]; - for (var id in cs) { - var c = cs[id]; - if (c.source.indexOf("定") >= 0) { - var origin = c.source.substring(1, 4); - if (cs[origin]) { - if (c.tags.length == 0) { - c.tags = cs[origin].tags; - } - } - } - } - } } \ No newline at end of file diff --git a/nikki.js b/nikki.js index 40b1ff2..f46c4b5 100644 --- a/nikki.js +++ b/nikki.js @@ -1,7 +1,5 @@ // Ivan's Workshop -var FEATURES = ["simple", "cute", "active", "pure", "cool"]; - var CATEGORY_HIERARCHY = function() { var ret = {}; for (var i in category) { @@ -15,9 +13,9 @@ var CATEGORY_HIERARCHY = function() { }(); // for table use -function thead(simple, score) { +function thead(isShoppingCart, score) { var ret = ""; - if (!simple) { + if (!isShoppingCart) { ret += "拥有"; } if (score) { @@ -38,6 +36,7 @@ function thead(simple, score) { 保暖\ 特殊属性\ 来源\ +  \ \n"; } @@ -63,52 +62,92 @@ function inventoryCheckbox(type, id, own) { return ret; } +function shoppingCartButton(type, id) { + return ""; +} + +function removeShoppingCartButton(detailedType) { + return ""; +} + +function addShoppingCart(type, id) { + shoppingCart.put(clothesSet[type][id]); + refreshShoppingCart(); +} + +function removeShoppingCart(type) { + shoppingCart.remove(type); + refreshShoppingCart(); +} + function toggleInventory(type, id) { var checked = $('#' + type + id)[0].checked; clothesSet[type][id].own = checked; saveAndUpdate(); } -function row(piece, simple) { - var ret = simple ? "" : td(inventoryCheckbox(piece.type.mainType, piece.id, piece.own), ""); +function row(piece, isShoppingCart) { + var ret = isShoppingCart ? "" : td(inventoryCheckbox(piece.type.mainType, piece.id, piece.own), ""); if (!isFilteringMode) { ret += td(piece.tmpScore); } var csv = piece.toCsv(); for (var i in csv) { - ret += td(csv[i], getStyle(csv[i])); + ret += td(render(csv[i]), getStyle(csv[i])); + } + if (isShoppingCart) { + // use id to detect if it is a fake clothes + if (piece.id) { + ret += td(removeShoppingCartButton(piece.type.type), ''); + } + } else { + ret += td(shoppingCartButton(piece.type.mainType, piece.id), ''); } return tr(ret); } +function render(rating) { + if (rating < 0) { + return -rating; + } + return rating; +} + function getStyle(rating) { + if (rating < 0) { + return 'negative'; + } switch (rating) { case "SS": return 'S'; case "S": return 'S'; case "A": return 'A'; case "B": return 'B'; case "C": return 'C'; - default: return "" + default: return ""; } } -function list(rows, simple) { - ret = thead(simple, !isFilteringMode); +function list(rows, isShoppingCart) { + ret = thead(isShoppingCart, !isFilteringMode); ret += ""; for (var i in rows) { - ret += row(rows[i], simple); + ret += row(rows[i], isShoppingCart); + } + if (isShoppingCart) { + ret += row(shoppingCart.totalScore, isShoppingCart); } ret += ""; return table(ret); } -function drawTable(data, div, simple) { - $('#' + div).html(list(data, simple)); +function drawTable(data, div, isShoppingCart) { + $('#' + div).html(list(data, isShoppingCart)); } -function refreshTable() { - var filters = {}; - var accfilters = {} +var criteria = {}; +function onChangeCriteria() { + criteria = {}; for (var i in FEATURES) { var f = FEATURES[i]; var weight = parseFloat($('#' + f + "Weight").val()); @@ -117,34 +156,55 @@ function refreshTable() { } var checked = $('input[name=' + f + ']:radio:checked'); if (checked.length) { - filters[f] = parseInt(checked.val()) * weight; - accfilters[f] = parseInt(checked.val()) * weight; + criteria[f] = parseInt(checked.val()) * weight; } } - + if (!isFilteringMode){ + if ($('#accessoriesHelper')[0].checked) { + chooseAccessories(criteria); + } else { + refreshShoppingCart(); + } + } + drawLevelInfo(); + refreshTable(); +} + +var uiFilter = {}; +function onChangeUiFilter() { + uiFilter = {}; $('input[name=inventory]:checked').each(function() { - filters[$(this).val()] = true; + uiFilter[$(this).val()] = true; }); if (currentCategory) { if (CATEGORY_HIERARCHY[currentCategory].length > 1) { $('input[name=category-' + currentCategory + ']:checked').each(function() { - filters[$(this).val()] = true; + uiFilter[$(this).val()] = true; }); } else { - filters[currentCategory] = true; + uiFilter[currentCategory] = true; } } - if (!isFilteringMode) { - // show top accessories - $('#topAccessories').show(); - drawTable(filterTopAccessories(accfilters), "topAccessoriesTable", true); - } else { - $('#topAccessories').hide(); + refreshTable(); +} + +function refreshTable() { + drawTable(filtering(criteria, uiFilter), "clothes", false); +} + +function chooseAccessories(accfilters) { + var accCate = CATEGORY_HIERARCHY['饰品']; + for (var i in accCate) { + shoppingCart.remove(accCate[i]); } + shoppingCart.putAll(filterTopAccessories(accfilters)); + refreshShoppingCart(); +} - drawLevelInfo(); - drawTable(filtering(filters), "clothes", false); +function refreshShoppingCart() { + shoppingCart.calc(criteria); + drawTable(shoppingCart.toList(byCategoryAndScore), "shoppingCartTable", true); } function drawLevelInfo() { @@ -200,7 +260,7 @@ function filterTopAccessories(filters) { } var result = {}; for (var i in clothes) { - if (matches(clothes[i], filters)) { + if (matches(clothes[i], {}, filters)) { if (!isFilteringMode) { clothes[i].calc(filters); if (!result[clothes[i].type.type]) { @@ -229,19 +289,12 @@ function filterTopAccessories(filters) { return toSort.slice(0, i); } -function accScore(total, items) { - if (items <= 3) { - return total; - } - return total * (1 - 0.06 * (items-3)); -} - -function filtering(filters) { +function filtering(criteria, filters) { var result = []; for (var i in clothes) { - if (matches(clothes[i], filters)) { + if (matches(clothes[i], criteria, filters)) { if (!isFilteringMode) { - clothes[i].calc(filters); + clothes[i].calc(criteria); } result.push(clothes[i]); } @@ -254,12 +307,12 @@ function filtering(filters) { return result; } -function matches(c, filters) { +function matches(c, criteria, filters) { // only filter by feature when filtering if (isFilteringMode) { for (var i in FEATURES) { var f = FEATURES[i]; - if (filters[f] && filters[f] * c[f][2] < 0) { + if (criteria[f] && criteria[f] * c[f][2] < 0) { return false; } } @@ -284,7 +337,7 @@ function toggleAll(c) { x.each(function() { this.checked = all; }); - refreshTable(); + onChangeUiFilter(); } function drawFilter() { @@ -302,7 +355,7 @@ function drawFilter() { // draw sub categories for (var i in CATEGORY_HIERARCHY[c]) { out += "