feat(plugins/habits): add plugin_habits_charts_type (#938)
This commit is contained in:
@@ -10,7 +10,7 @@ export default async function({login, data, rest, imports, q, account}, {enabled
|
||||
return null
|
||||
|
||||
//Load inputs
|
||||
let {from, days, facts, charts, trim} = imports.metadata.plugins.habits.inputs({data, account, q}, defaults)
|
||||
let {from, days, facts, charts, "charts.type":_charts, trim} = imports.metadata.plugins.habits.inputs({data, account, q}, defaults)
|
||||
|
||||
//Initialization
|
||||
const habits = {facts, charts, trim, lines:{average:{chars:0}}, commits:{fetched:0, hour:NaN, hours:{}, day:NaN, days:{}}, indents:{style:"", spaces:0, tabs:0}, linguist:{available:false, ordered:[], languages:{}}}
|
||||
@@ -109,7 +109,53 @@ export default async function({login, data, rest, imports, q, account}, {enabled
|
||||
}
|
||||
else
|
||||
console.debug(`metrics/compute/${login}/plugins > habits > linguist not available`)
|
||||
}
|
||||
|
||||
//Generating charts with chartist
|
||||
if (_charts === "chartist") {
|
||||
console.debug(`metrics/compute/${login}/plugins > habits > generating charts`)
|
||||
habits.charts = await Promise.all([
|
||||
{type:"line", data:{...empty(24), ...Object.fromEntries(Object.entries(habits.commits.hours).filter(([k]) => !Number.isNaN(+k)))}, low:0, high:habits.commits.hours.max},
|
||||
{type:"line", data:{...empty(7), ...Object.fromEntries(Object.entries(habits.commits.days).filter(([k]) => !Number.isNaN(+k)))}, low:0, high:habits.commits.days.max, labels:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], half:true},
|
||||
{type:"pie", data:habits.linguist.languages, half:true},
|
||||
].map(({type, data, high, low, ref, labels = {}, half = false}) => {
|
||||
const options = {
|
||||
width:480 * (half ? 0.45 : 1),
|
||||
height:160,
|
||||
fullWidth:true,
|
||||
}
|
||||
const values = {
|
||||
labels:Object.keys(data).map(key => labels[key] ?? key),
|
||||
series:Object.values(data)
|
||||
}
|
||||
if (type === "line") {
|
||||
Object.assign(options, {
|
||||
showPoint:true,
|
||||
axisX:{showGrid:false},
|
||||
axisY:{showLabel:false, offset:20, labelInterpolationFnc:value => imports.format(value), high, low, referenceValue:ref},
|
||||
showArea:true,
|
||||
})
|
||||
Object.assign(values, {
|
||||
series:[Object.values(data)]
|
||||
})
|
||||
}
|
||||
return imports.chartist(type, options, values)
|
||||
}))
|
||||
data.postscripts.push(`(${function(format) {
|
||||
document.querySelectorAll(".habits .chartist").forEach(chart => {
|
||||
chart.querySelectorAll(".habits .chartist .ct-point").forEach(node => {
|
||||
const [x, y, value] = ["x1", "y1", "ct:value"].map(attribute => node.getAttribute(attribute))
|
||||
if (Number(value)) {
|
||||
const text = document.createElementNS("http://www.w3.org/2000/svg", "text")
|
||||
text.setAttributeNS(null, "x", x)
|
||||
text.setAttributeNS(null, "y", y - 5)
|
||||
text.setAttributeNS(null, "class", "ct-post")
|
||||
text.appendChild(document.createTextNode(format(value)))
|
||||
node.parentNode.append(text)
|
||||
}
|
||||
})
|
||||
})
|
||||
}})(${imports.format.toString()})`)
|
||||
}
|
||||
|
||||
//Results
|
||||
@@ -122,3 +168,8 @@ export default async function({login, data, rest, imports, q, account}, {enabled
|
||||
throw {error:{message:"An error occured", instance:error}}
|
||||
}
|
||||
}
|
||||
|
||||
/**Initialize an empty object with values from 0 to n */
|
||||
function empty(n) {
|
||||
return Object.fromEntries(new Array(n).fill(0).map((_, i) => [i, 0]))
|
||||
}
|
||||
@@ -52,6 +52,17 @@ inputs:
|
||||
type: boolean
|
||||
default: no
|
||||
|
||||
plugin_habits_charts_type:
|
||||
description: |
|
||||
Charts display type
|
||||
- `classic`: `<div>` based charts, simple and lightweight
|
||||
- `chartist`: `<svg>` based charts, smooth
|
||||
type: string
|
||||
default: classic
|
||||
values:
|
||||
- classic
|
||||
- chartist
|
||||
|
||||
plugin_habits_trim:
|
||||
description: Trim unused hours on charts
|
||||
type: boolean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<% if (plugins.habits) { %>
|
||||
<section>
|
||||
<section class="habits">
|
||||
<h2 class="field wrap">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 01-1.484.211c-.04-.282-.163-.547-.37-.847a8.695 8.695 0 00-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.75.75 0 01-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75zM6 15.25a.75.75 0 01.75-.75h2.5a.75.75 0 010 1.5h-2.5a.75.75 0 01-.75-.75zM5.75 12a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5z"></path></svg>
|
||||
Recent coding habits
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<% } else if (plugins.habits.facts) { %>
|
||||
<div class="row">
|
||||
<ul class="habits">
|
||||
<ul class="facts">
|
||||
<% if (plugins.habits.indents.style) { %>
|
||||
<li>Uses <%= plugins.habits.indents.style %> for indentation</li>
|
||||
<% } %>
|
||||
@@ -37,9 +37,15 @@
|
||||
</section>
|
||||
|
||||
<% if (plugins.habits.charts) { %>
|
||||
<section class="habits">
|
||||
<% if (!Number.isNaN(plugins.habits.commits.hour)) { %>
|
||||
<section class="column chart largeable">
|
||||
<div class="column chart largeable">
|
||||
<h3>Commit activity per hour of day</h3>
|
||||
<% if (Array.isArray(plugins.habits.charts)) { %>
|
||||
<div class="row margin-bottom chartist">
|
||||
<%- plugins.habits.charts[0] %>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<div class="chart-bars">
|
||||
<% var displayedValues = []; %>
|
||||
<% for (let h = 0; h < 24; h++) { displayedValues.push([h, (plugins.habits.commits.hours[h]??0)/(plugins.habits.commits.hours.max??1), plugins.habits.commits.hours[h]]) } %>
|
||||
@@ -57,13 +63,19 @@
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</section>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div class="row largeable">
|
||||
<% if (!Number.isNaN(plugins.habits.commits.day)) { %>
|
||||
<section class="column chart">
|
||||
<h3>Commit activity per day of week</h3>
|
||||
<% if (Array.isArray(plugins.habits.charts)) { %>
|
||||
<div class="margin-bottom chartist">
|
||||
<%- plugins.habits.charts[1] %>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<div class="chart-bars">
|
||||
<% for (let d = 0; d < 7; d++) { const p = (plugins.habits.commits.days[d]??0)/(plugins.habits.commits.days.max??1); %>
|
||||
<div class="entry">
|
||||
@@ -73,11 +85,17 @@
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
</section>
|
||||
<% } %>
|
||||
<% if (plugins.habits.linguist.available) { %>
|
||||
<section class="column chart">
|
||||
<h3>Language activity</h3>
|
||||
<% if (Array.isArray(plugins.habits.charts)) { %>
|
||||
<div class="margin-bottom chartist">
|
||||
<%- plugins.habits.charts[2] %>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<div class="chart-bars horizontal">
|
||||
<% for (const [language, p] of plugins.habits.linguist.ordered) { %>
|
||||
<div class="entry">
|
||||
@@ -87,8 +105,10 @@
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
</section>
|
||||
<% } %>
|
||||
</div>
|
||||
</section>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
@@ -335,15 +335,15 @@
|
||||
}
|
||||
|
||||
/* Habits */
|
||||
.habits {
|
||||
.habits .facts {
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
padding-left: 37px;
|
||||
}
|
||||
|
||||
/* Stargazers */
|
||||
/* Chartist */
|
||||
/* purgecss ignore */
|
||||
.stargazers .chartist .ct-post {
|
||||
.chartist .ct-post {
|
||||
fill: rgba(127, 127, 127, 0.8) !important;
|
||||
color: rgba(127, 127, 127, 0.8) !important;
|
||||
font-size: 9px;
|
||||
@@ -1365,6 +1365,10 @@
|
||||
display: flex;
|
||||
margin-left: -12px;
|
||||
}
|
||||
.ct-chart-pie .ct-label {
|
||||
fill: rgba(255, 255, 255, 0.8) !important;
|
||||
color: rgba(255, 255, 255, 0.8) !important;
|
||||
}
|
||||
.ct-line {
|
||||
stroke-width: 2px !important;
|
||||
stroke: #58A6FF !important;
|
||||
|
||||
Reference in New Issue
Block a user