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
|
return null
|
||||||
|
|
||||||
//Load inputs
|
//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
|
//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:{}}}
|
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
|
else
|
||||||
console.debug(`metrics/compute/${login}/plugins > habits > linguist not available`)
|
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
|
//Results
|
||||||
@@ -122,3 +168,8 @@ export default async function({login, data, rest, imports, q, account}, {enabled
|
|||||||
throw {error:{message:"An error occured", instance:error}}
|
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
|
type: boolean
|
||||||
default: no
|
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:
|
plugin_habits_trim:
|
||||||
description: Trim unused hours on charts
|
description: Trim unused hours on charts
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<% if (plugins.habits) { %>
|
<% if (plugins.habits) { %>
|
||||||
<section>
|
<section class="habits">
|
||||||
<h2 class="field wrap">
|
<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>
|
<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
|
Recent coding habits
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } else if (plugins.habits.facts) { %>
|
<% } else if (plugins.habits.facts) { %>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<ul class="habits">
|
<ul class="facts">
|
||||||
<% if (plugins.habits.indents.style) { %>
|
<% if (plugins.habits.indents.style) { %>
|
||||||
<li>Uses <%= plugins.habits.indents.style %> for indentation</li>
|
<li>Uses <%= plugins.habits.indents.style %> for indentation</li>
|
||||||
<% } %>
|
<% } %>
|
||||||
@@ -37,9 +37,15 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<% if (plugins.habits.charts) { %>
|
<% if (plugins.habits.charts) { %>
|
||||||
|
<section class="habits">
|
||||||
<% if (!Number.isNaN(plugins.habits.commits.hour)) { %>
|
<% 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>
|
<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">
|
<div class="chart-bars">
|
||||||
<% var displayedValues = []; %>
|
<% 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]]) } %>
|
<% 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>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<% } %>
|
||||||
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<div class="row largeable">
|
<div class="row largeable">
|
||||||
<% if (!Number.isNaN(plugins.habits.commits.day)) { %>
|
<% if (!Number.isNaN(plugins.habits.commits.day)) { %>
|
||||||
<section class="column chart">
|
<section class="column chart">
|
||||||
<h3>Commit activity per day of week</h3>
|
<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">
|
<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); %>
|
<% for (let d = 0; d < 7; d++) { const p = (plugins.habits.commits.days[d]??0)/(plugins.habits.commits.days.max??1); %>
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
@@ -73,11 +85,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
<% } %>
|
||||||
</section>
|
</section>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% if (plugins.habits.linguist.available) { %>
|
<% if (plugins.habits.linguist.available) { %>
|
||||||
<section class="column chart">
|
<section class="column chart">
|
||||||
<h3>Language activity</h3>
|
<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">
|
<div class="chart-bars horizontal">
|
||||||
<% for (const [language, p] of plugins.habits.linguist.ordered) { %>
|
<% for (const [language, p] of plugins.habits.linguist.ordered) { %>
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
@@ -87,8 +105,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
<% } %>
|
||||||
</section>
|
</section>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
@@ -335,15 +335,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Habits */
|
/* Habits */
|
||||||
.habits {
|
.habits .facts {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding-left: 37px;
|
padding-left: 37px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stargazers */
|
/* Chartist */
|
||||||
/* purgecss ignore */
|
/* purgecss ignore */
|
||||||
.stargazers .chartist .ct-post {
|
.chartist .ct-post {
|
||||||
fill: rgba(127, 127, 127, 0.8) !important;
|
fill: rgba(127, 127, 127, 0.8) !important;
|
||||||
color: rgba(127, 127, 127, 0.8) !important;
|
color: rgba(127, 127, 127, 0.8) !important;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
@@ -1365,6 +1365,10 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin-left: -12px;
|
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 {
|
.ct-line {
|
||||||
stroke-width: 2px !important;
|
stroke-width: 2px !important;
|
||||||
stroke: #58A6FF !important;
|
stroke: #58A6FF !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user