Optimize stats code

This commit is contained in:
shwin0901 2020-05-15 22:51:43 +08:00
parent e4edbb6994
commit c5b956b0ff
5 changed files with 73 additions and 133 deletions

View file

@ -25,11 +25,6 @@ function barChart({ margin, height, width, data, selector,color,}) {
let x = d3.scaleLinear() let x = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)]) .domain([0, d3.max(data, d => d.value)])
.range([margin.left, width - margin.right]) .range([margin.left, width - margin.right])
// .domain(d3.range(data.length))
// .range([margin.left, width - margin.right])
// .padding(0.1);
// let format = x.tickFormat(20);
const svg = d3.select(selector) const svg = d3.select(selector)
.append("svg") .append("svg")
@ -54,7 +49,7 @@ function barChart({ margin, height, width, data, selector,color,}) {
.html(`<span>${d.value}</span>`) .html(`<span>${d.value}</span>`)
.style('width', `${tooltipWidth}px`) .style('width', `${tooltipWidth}px`)
.style('left', x(d.value) + 5 + "px") .style('left', x(d.value) + 5 + "px")
.style('top', y(i)+y.bandwidth() / 6 - tooltipWidth / 6 + "px") .style('top', y(i)+y.bandwidth() / 2 - tooltipWidth / 3 + "px")
}) })
.on("mouseout", function (d, i) { .on("mouseout", function (d, i) {
tooltip.remove(); tooltip.remove();

View file

@ -10,7 +10,7 @@
text-align: center; text-align: center;
} }
.char-histogram rect:hover { #chart rect:hover {
fill: rgb(255, 157, 0); fill: rgb(255, 157, 0);
} }

View file

@ -44,7 +44,6 @@ li {
width: 8px; width: 8px;
height: 8px; height: 8px;
border-radius: 50%; border-radius: 50%;
/* background-color: black; */
} }
.showText li { .showText li {
display: flex; display: flex;

View file

@ -34,38 +34,6 @@
</div> </div>
<div class="showText" style=" padding: 10px;"> <div class="showText" style=" padding: 10px;">
<ol style="display: flex; justify-content: space-around;"> <ol style="display: flex; justify-content: space-around;">
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
<li> <span class="color-block"></span>
<span class="lang"></span>
<span class="percent"></span>
</li>
</ol> </ol>
</div> </div>
</div> </div>

View file

@ -1,16 +1,34 @@
let history = JSON.parse(localStorage.getItem("history")); let history = JSON.parse(localStorage.getItem("history"));
let colorRange = "#F9BB2D"; let chartColor = "#F9BB2D";
let weeks = { "Sun": 0, "Mon": 0, "Tue": 0, "Wed": 0, "Thu": 0, "Fri": 0, "Sat": 0 }; let weeks = { "Sun": 0, "Mon": 0, "Tue": 0, "Wed": 0, "Thu": 0, "Fri": 0, "Sat": 0 };
let dates = num(1, 31); let dates = num(1, 31);
let hours = num(0, 23); let hours = num(0, 23);
let stats = [{ name: "docsss", value: 0, color: "#f00" }, { name: "docss", value: 0, color: "#ff00af" }, { name: "docs", value: 0, color: "#b600ff" }, { name: "%", value: 0, color: "#3400ff" }, { name: ">", value: 0, color: "#0944ff" }, { name: "@", value: 0, color: "#00f2ff" }, { name: "#", value: 0, color: "#00ff2d" }, { name: "text", value: 0, color: "#ffa600" }] function num(start, end, initial = 0) {
return Array.from({ length: end + 1 - start }).fill(initial)
.reduce((obj, current, index) => {
obj[start + index] = current;
return obj;
}, {});
};
let stats = [
// { name: "Repository", prefix: "!!!", value: 0, color: "#f00" },
{ name: "Docs", prefix: "!!", value: 0, color: "#ff00af" },
{ name: "Crates", prefix: "!", value: 0, color: "#b600ff" },
{ name: "Book", prefix: "%", value: 0, color: "#3400ff" },
{ name: "Lint", prefix: ">", value: 0, color: "#0944ff" },
{ name: "Crate docs", prefix: "@", value: 0, color: "#00f2ff" },
{ name: "Attribute", prefix: "#", value: 0, color: "#00442d" },
{ name: "Std docs", prefix: "", value: 0, color: "#ffa600" },
];
let calendarData = []; let calendarData = [];
let barChartObj = {}; //bar-chart(url)
let w = Object.keys(weeks); let w = Object.keys(weeks);
let d = Object.keys(dates); let d = Object.keys(dates);
let h = Object.keys(hours); let h = Object.keys(hours);
history.forEach(({ time }) => { history.forEach(({ query, content, time }) => {
let date = new Date(time); let date = new Date(time);
calendarData.push({ calendarData.push({
date, date,
@ -19,37 +37,35 @@ history.forEach(({ time }) => {
weeks[w[date.getDay()]] += 1; weeks[w[date.getDay()]] += 1;
dates[d[date.getDate() - 1]] += 1; dates[d[date.getDate() - 1]] += 1;
hours[h[date.getHours()]] += 1; hours[h[date.getHours()]] += 1;
//chart-heatmap
let stat = stats.find(item => query.startsWith(item.prefix));
if (stat) {
stat.value += 1;
}
// bar-chart(url)
if (["https://docs.rs", "https://crates.io", "https://lib.rs"].some(prefix => content.startsWith(prefix))) {
let url = new URL(content);
let pathname = url.pathname.replace("/crates/", "/").slice(1);
let [crate, _] = pathname.split("/");
if (barChartObj[crate]) {
barChartObj[crate] += 1;
} else {
barChartObj[crate] = 1;
}
}
}); });
let [weeksData, datesData, hoursData] = [weeks, dates, hours].map(data => { let [weeksData, datesData, hoursData] = [weeks, dates, hours].map(data => {
return Object.entries(data).map(([key, value]) => { return { name: key, value } }) return Object.entries(data).map(([key, value]) => { return { name: key, value } })
}); });
history.forEach(({ query }) => {
if (query.startsWith("!!!")) {
stats[0].value += 1
} else if (query.startsWith("!!")) {
stats[1].value += 1
} else if (query.startsWith("!")) {
stats[2].value += 1
} else if (query.startsWith("%")) {
stats[3].value += 1
} else if (query.startsWith(">")) {
stats[4].value += 1
} else if (query.startsWith("@")) {
stats[5].value += 1
} else if (query.startsWith("#")) {
stats[6].value += 1
} else {
stats[7].value += 1
}
})
let heatmap = calendarHeatmap() let heatmap = calendarHeatmap()
.data(calendarData) .data(calendarData)
.selector('.chart-heatmap') .selector('.chart-heatmap')
.tooltipEnabled(true) .tooltipEnabled(true)
.colorRange(['#f4f7f7', colorRange]) .colorRange(['#f4f7f7', chartColor])
.tooltipUnit([ .tooltipUnit([
{ min: 0, unit: 'searching' }, { min: 0, unit: 'searching' },
{ min: 1, max: 1, unit: 'searching' }, { min: 1, max: 1, unit: 'searching' },
@ -61,48 +77,33 @@ let heatmap = calendarHeatmap()
}); });
heatmap(); heatmap();
let histogramConfig = {
function num(start, end) { width: 550,
let obj = {}; height: 320,
for (let i = start; i <= end; i++) { color: chartColor,
obj[i] = 0; margin: { top: 30, right: 0, bottom: 40, left: 40 }
}
return obj;
}; };
histogram({ histogram({
selector: ".chart-histogram-week", selector: ".chart-histogram-week",
data: weeksData, data: weeksData,
width: 550, ...histogramConfig,
height: 320,
color: "#F9BB2D",
margin: { top: 30, right: 0, bottom: 40, left: 40 },
}); });
histogram({ histogram({
selector: ".chart-histogram-date", selector: ".chart-histogram-date",
data: datesData, data: datesData,
width: 550, ...histogramConfig,
height: 320,
color: "#F9BB2D",
margin: { top: 30, right: 0, bottom: 40, left: 40 },
}); });
histogram({ histogram({
selector: ".chart-histogram-hour", selector: ".chart-histogram-hour",
data: hoursData, data: hoursData,
width: 550, ...histogramConfig,
height: 320,
color: "#F9BB2D",
margin: { top: 30, right: 0, bottom: 40, left: 40 },
}); });
let spans = document.querySelector(".lang-stats-graph"); let spans = document.querySelector(".lang-stats-graph");
let showText = document.querySelector(".showText"); let showText = document.querySelector(".showText");
let lang = showText.querySelectorAll(".lang"); let ol = showText.querySelector("ol");
let percent = showText.querySelectorAll(".percent");
let colorBlock = showText.querySelectorAll(".color-block")
function byField(key) { function byField(key) {
return function (a, b) { return function (a, b) {
if (b[key] > a[key]) { if (b[key] > a[key]) {
@ -112,61 +113,38 @@ function byField(key) {
} }
} }
} }
let sort = stats.sort(byField("value")) let sort = stats.sort(byField("value"));
let sum = sort.reduce((item, { value }) => { let sum = sort.reduce((item, { value }) => {
return item + value return item + value
}, 0) }, 0);
for (let i = 0; i < sort.length; i++) { sort.forEach(({ name, color, value }) => {
lang[i].textContent = `${sort[i].name}`; let li = document.createElement("li");
percent[i].textContent = `${(sort[i].value / sum * 100).toFixed(1)} %`; li.innerHTML = `<span class="color-block" style="background-color:${color}"></span>
colorBlock[i].style.backgroundColor = `${sort[i].color}`; <span class="">${name}</span>
<span class="">${(value / sum * 100).toFixed(1)}%<span>`;
if (sort[i].value == 0) { ol.append(li);
null; if (value > 0) {
} else { spans.insertAdjacentHTML('beforeend', `<span class="show" style="width: ${value / sum * 100}%;
let p = document.createElement("span"); background-color:${color}"></span>`);
p.style.width = `${sort[i].value / sum * 100}` + "%";
p.style.backgroundColor = `${sort[i].color}`;
p.classList = "show";
spans.append(p);
}
}
let datar = {};
history.forEach(({content}) => {
if (["https://docs.rs", "https://crates.io","https://lib.rs"].some(prefix => content.startsWith(prefix))){
let url = new URL(content);
let pathname = url.pathname.replace("/crates/", "/").slice(1);
let [crate, __] = pathname.split("/");
if(datar[crate]) {
datar[crate] += 1;
} else {
datar[crate] = 1;
}
} }
}) })
let arr = []; let barChartArr = [];
for(let i in datar) { Object.entries(barChartObj).map(([key, value]) => {
arr.push({ barChartArr.push({
name: i, name: key,
value: `${datar[i]}` value
}) });
} });
let barChartData = barChartArr.sort(byField("value"));
let datat = arr.sort(byField("value")); barChartData.splice(10);
datat.splice(10);
datat[0].value = 16;
barChart({ barChart({
margin: ({ top: 30, right: 0, bottom: 10, left: 30 }), margin: ({ top: 30, right: 0, bottom: 10, left: 30 }),
height: 320, height: 320,
barHeight: 25, barHeight: 25,
width: 750, width: 750,
data: datat, data: barChartData,
selector: ".bar-chart", selector: ".bar-chart",
color: "#F9BB2D", color: "#F9BB2D",
}) });