Skip to content

Commit

Permalink
add music statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
FlickerMi committed Oct 18, 2020
1 parent 036e4bc commit a7077fb
Show file tree
Hide file tree
Showing 4 changed files with 339 additions and 3 deletions.
2 changes: 1 addition & 1 deletion book.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ optionContainer.addEventListener("change", function(e) {
};
book = {
id : book.id,
img : "http://lab.eming.li/dou/book/{id}.jpg".replace("{id}", book.id),
img : item.querySelector(".pic img").src,
des : desDOM.textContent || "",
date : book.date.join("-"),
year : +book.date[0],
Expand Down
12 changes: 11 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"https://movie.douban.com/people/*/collect",
"https://movie.douban.com/mine?status=collect",
"https://book.douban.com/people/*/collect",
"https://book.douban.com/mine?status=collect"
"https://book.douban.com/mine?status=collect",
"https://music.douban.com/people/*/collect",
"https://music.douban.com/mine?status=collect"
],
"js" : [
"jquery-2.0.3.min.js",
Expand All @@ -35,6 +37,14 @@
],
"js" : ["book.js"],
"run_at" : "document_end"
},
{
"matches" : [
"https://music.douban.com/people/*/collect",
"https://music.douban.com/mine?status=collect"
],
"js" : ["music.js"],
"run_at" : "document_end"
}
]
}
2 changes: 1 addition & 1 deletion movie.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ optionContainer.addEventListener("change", function(e) {
};
var film = {
id : film.id,
img : "http://lab.eming.li/dou/{id}.jpg".replace("{id}", film.id),
img : item.querySelector(".pic img").src,
des : desDOM ? desDOM.textContent : "",
date : film.date,
year : +film.date.split("-")[0],
Expand Down
326 changes: 326 additions & 0 deletions music.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
var optionContainer = document.querySelector(".article .sort"),
contentContainer = document.querySelector(".grid-view");
optionContainer.innerHTML += '<span class="gray-dot">·</span><a href="javascript:void(0);" id="tj">音乐统计</a>';
optionContainer.addEventListener("click", function(e) {
if(e.target.id === "tj") {
if(document.querySelector("#year")) return true;
var now = new Date().getFullYear(), option = "<option> - </option>";
for(var year=now;year>=2005;year--) option+="<option>{{year}}</option>".replace("{{year}}",year);
optionContainer.innerHTML += '<span class="gray-dot">·</span>选择统计年份:<select id="year" value="">'+option+'</select>';
}
return true;
})
optionContainer.addEventListener("change", function(e) {
if(e.target.id != "year") return true;
try {
document.querySelector(".paginator").innerHTML = "";
} catch(e) {};
contentContainer.innerHTML = "";

var year = +e.target.value,
user = document.querySelector("#db-usr-profile a").href.split("/").reverse()[1],
total = +document.querySelector("title").textContent.match(/[0-9]+/),
films = localStorage[user] ? JSON.parse( localStorage[user] ) : [];

if(films.length === total) return render(films, year);
else films = [];

var pages = getPages(user, total, "music"), percent = {
init: function() {
contentContainer.innerHTML = '<div class="percent" style="font-size:100px;text-align:center;"><span>0</span>%</div>';
},
update: function(percent) {
contentContainer.querySelector(".percent span").innerHTML = (percent*100).toFixed(1);
},
remove: function() {
contentContainer.innerHTML = "";
},
length: pages.length
};

percent.init();
getPages(user, total, "music").map(getHTML).reduce(function(seq, html) {
return seq.then(function() {
percent.length--;
percent.update((pages.length - percent.length)/pages.length);
return html;
}).then(getMusics);
}, Promise.resolve()).then(function() {
percent.remove();
render(films, year);
localStorage.setItem(user, JSON.stringify(films));
});
function getMusics(dom) {
return [].forEach.call(dom.querySelectorAll(".item"), function(item) {
var dateDOM = item.querySelector(".date"),
rateDOM = dateDOM.previousElementSibling,
desDOM = item.querySelector(".comment"),
film = {
id : item.querySelector(".nbg").href.split("subject/")[1].split("/")[0],
date : dateDOM.innerHTML
};
var film = {
id : film.id,
img : item.querySelector(".pic img").src,
des : desDOM ? desDOM.textContent : "",
date : film.date,
year : +film.date.split("-")[0],
rate : rateDOM ? rateDOM.className.substring(6,7) : 0,
title: item.querySelector(".title em").innerHTML
};
films.push(film);
});
}
});
contentContainer.addEventListener("click", function(e) {
switch(e.target.tagName.toLowerCase()) {
case "span":
var clicked;
if(clicked = document.querySelector("#command span.click")) {
clicked.classList.toggle("click");
}
showPostByRate(e.target.className);
e.target.classList.toggle("click");
break;
case "button":
showPostWall();
break;
}
})
function render(films, year) {
const MONTHES = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
const SMALLMONTH = [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];
const BIGGERMONTH = [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];
const BIGMONTH = [0,2,4,6,7,9,11];
const RATENAME = ["zero", "one", "two", "three", "four", "five"];
var counts = {
rate: [].slice.call(new Uint8Array(6)),
month: [].slice.call(new Uint8Array(12)),
day: [].slice.call(new Uint8Array(12)).map(function(v,k) {
return [].slice.call(new Uint8Array( BIGMONTH.indexOf(k) != -1 ? 31 : 30 ));
})
},
template = {
basicHTML: '\
<div id="column"></div>\
<div id="column_2"></div>\
<div id="pie"></div>\
<div id="mc"></div>\
<div id="command">\
<span class="one">一星</span>\
<span class="two">二星</span>\
<span class="three">三星</span>\
<span class="four">四星</span>\
<span class="five">五星</span>\
<span class="all">所有</span>\
<button class="poster-wall" style="float: right;">生成海报墙</button>\
</div>\
<ul id="msh">\
{{musicList}}\
</ul>\
<div id="raw">\
<p style="background-color:#d9edf7;color:#3a87ad;padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow: 0 1px 0 rgba(255,255,255,0.5);border:1px solid #bce8f1;-webkit-border-radius:4px;font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;font-size:13px;">\
{{word}}\
<a class="jiathis_button_douban" href="http://shuo.douban.com/!service/share?image=&href={{url}}&name={{title}}&text={{word}}" target="_blank" style="float:right;">\
分享到豆瓣\
</a>\
</p>\
<p style="margin-top:50px;">\
<label>\
引用代码:\
</label>\
</p>\
<textarea style="height:600px;resize:vertical;width:100%;">\
<ul id="msh">\
{{musicList}}\
</ul>\
</textarea>\
</div>\
<style type="text/css">\
#command {\
border-bottom: 1px solid #06F;\
margin-bottom: 10px;\
margin-top: 10px;\
padding: 10px 0 6px 0;\
font-size: 16px;\
text-shadow: 1px 1px 1px #FFF;\
}\
#command span {\
cursor: pointer;\
padding: 10px 20px;\
}\
#command span:hover, #command span.click {\
border: 1px solid #06F;\
background: #FFF;\
border-bottom: 1px solid #FFF;\
}\
#msh {\
width: 100%;\
margin: 0;\
}\
#msh li {\
display: inline-table;\
margin: 3px;\
}\
</style>',
musicListItem:'<li class="{{rateName}}">\
<a href="http://music.douban.com/subject/{{id}}" title="{{title}}">\
<img src="{{img}}" crossOrigin="*" alt="{{title}}" width="67px" height="97px" />\
</a>\
</li>',
word : "{{year}}年我一共听了{{total}}首音乐,平均每月听歌{{average}}首。其中{{mostMonth}}听了{{mostWatch}}首音乐,是我的年度最佳听歌月。 #豆瓣电影统计工具#",
render: function(str, obj) {
return str.replace(/{{(\w+)}}/g, function(_,O) {return obj[O] || O});
}

},
charts = {
renderByYear: function(title, categories, data) {
function setChart(name, categories, data, color) {
chart.xAxis[0].setCategories(categories, false);
chart.series[0].remove(false);
chart.addSeries({
name: name,
data: data,
color: color
}, false);
chart.redraw()
}
var basicName = "音乐", colors = Highcharts.getOptions().colors;
var chart = new Highcharts.Chart({
chart: {
renderTo: 'column',
type: 'column'
},
title: {text: title},
xAxis: {categories: categories},
yAxis: {title: {text: '数量(首)'}},
plotOptions: {
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) {
setChart(drilldown.name, drilldown.categories, drilldown.data, drilldown.color)
} else {
setChart(basicName, categories, data, colors[0])
}
}
}
},
dataLabels: {
enabled: true,
formatter: function() {
return this.y
}
}
}
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x + ': ' + this.y + '首<br/>';
s += point.drilldown ? '单击查看' + point.category + '详情' : '返回月份总览';
return s;
}
},
series: [{
name: basicName,
data: data,
color: colors[0]
}],
exporting: {
enabled: true
}
});
return chart;
},
renderByYears: function() {

},
renderByRate: function(rate) {
return new Highcharts.Chart({
chart: {
renderTo: 'pie',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: '评分分布'
},
tooltip: {
pointFormat: '',
percentageDecimals: 0
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function() {
return '<b>' + this.point.name + '</b>: ' + Math.round(this.percentage) + ' %'
}
}
}
},
series: [{
type: 'pie',
name: '数量',
data: [['无', rate[0]], ['1 星', rate[1]], ['2 星', rate[2]], ['3 星', rate[3]], ['4 星', rate[4]], ['5 星', rate[5]]]
}]
});
},
renderByRates: function() {

}
};

films = films.filter(function(film) {return film.year === year});
var musicList = films.map(function(film) {
var date = film.date.split("-"),
filmMonth = +date[1]-1;
filmDay = +date[2]-1;
counts.rate[ film.rate ] += 1;
counts.month[ filmMonth ] += 1;
counts.day[ filmMonth ][ filmDay ] += 1;
film.rateName = RATENAME[film.rate];
return template.render(template.musicListItem, film);
}).join("");

var mostWatchKey = mwatch(counts.month);
contentContainer.innerHTML = template.render(template.basicHTML, {
musicList:musicList,
url:"http://douban.com",
title:"豆瓣",
word: template.render(template.word, {
year:year,
total:films.length,
average:Math.round(films.length/12*10)/10,
mostMonth:MONTHES[mostWatchKey],
mostWatch:counts.month[mostWatchKey],
watchAverage:av(films.length, counts.month),
watchLevel:arate(counts.rate)
})
});

var colors = Highcharts.getOptions().colors;
charts.renderByYear(year + '年你一共听过' + films.length + '首音乐', MONTHES, counts.month.map(function(count, i) {
return {
y: count,
color: colors[0],
drilldown: {
name: MONTHES[i],
categories: BIGMONTH.indexOf(i) != -1 ? BIGGERMONTH : SMALLMONTH,
data: counts.day[i],
color: colors[0]
}
}
}));
charts.renderByRate(counts.rate);
}

0 comments on commit a7077fb

Please sign in to comment.