mirror of
https://github.com/gwenhael-le-moine/credger.git
synced 2024-12-26 09:58:36 +01:00
donut's tooltip; period navigation
This commit is contained in:
parent
5cde92fea3
commit
cff645a9cf
1 changed files with 58 additions and 22 deletions
|
@ -43,48 +43,84 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const UI = {
|
const UI = {
|
||||||
|
/* https://medium.com/@heyoka/scratch-made-svg-donut-pie-charts-in-html5-2c587e935d72 */
|
||||||
donut: ( element, dataset ) => {
|
donut: ( element, dataset ) => {
|
||||||
|
const thickness = 9;
|
||||||
let filed_percent = 0;
|
let filed_percent = 0;
|
||||||
const data_to_donut_segment = ( data ) => {
|
const data_to_donut_segment = ( data ) => {
|
||||||
|
if ( data.amount > 0 ) {
|
||||||
const stroke_dashoffset = ( percent ) => {
|
const stroke_dashoffset = ( percent ) => {
|
||||||
let offset = ( 100 - filed_percent ) + 25;
|
let offset = 100 - filed_percent;
|
||||||
|
|
||||||
return offset > 100 ? offset - 100 : offset;
|
return offset > 100 ? offset - 100 : offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
const donut_segment = `<circle class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="${data.color}" stroke-width="3" stroke-dasharray="${data.percent} ${100 - data.percent}" stroke-dashoffset="${stroke_dashoffset( data.percent )}"></circle>`;
|
const donut_segment = `<circle class="donut-segment ${data.account.split(':').join(' ')}" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="${data.color}" stroke-width="${thickness}" stroke-dasharray="${data.percent} ${100 - data.percent}" stroke-dashoffset="${stroke_dashoffset( data.percent )}"><title>${data.tooltip}</title></circle>`;
|
||||||
filed_percent += data.percent;
|
filed_percent += data.percent;
|
||||||
|
|
||||||
return donut_segment;
|
return donut_segment;
|
||||||
|
} else
|
||||||
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
element.innerHTML = `<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
|
element.innerHTML = `<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
|
||||||
<circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
|
<circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
|
||||||
<circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3"></circle>
|
<circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="${thickness}"></circle>
|
||||||
|
|
||||||
${dataset.map( line => data_to_donut_segment( line ) ).join("")}
|
${dataset.map( line => data_to_donut_segment( line ) ).join("")}
|
||||||
</svg><pre>${JSON.stringify( dataset )}</pre>`;
|
</svg><pre>${JSON.stringify( dataset )}</pre>`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="donut"></div>
|
|
||||||
|
|
||||||
<script>
|
let current_period;
|
||||||
const period = (new Date()).toISOString().split("T")[0].slice( 0, -3 );
|
const Period = {
|
||||||
API.balance( period, ["Expenses"].join(" "), 2 )
|
set: ( period ) => {
|
||||||
|
current_period = period;
|
||||||
|
document.querySelector( "#period #display" ).innerHTML = current_period.toISOString();
|
||||||
|
|
||||||
|
monthly( current_period.toISOString().split("T")[0].slice( 0, -3 ), "#month" );
|
||||||
|
},
|
||||||
|
get: () => current_period,
|
||||||
|
prev: () => {
|
||||||
|
current_period.setMonth( current_period.getMonth() - 1 );
|
||||||
|
Period.set( current_period );
|
||||||
|
},
|
||||||
|
next: () => {
|
||||||
|
current_period.setMonth( current_period.getMonth() + 1 );
|
||||||
|
Period.set( current_period );
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const monthly = ( month, element_selector ) => {
|
||||||
|
API.balance( month, ["Expenses"].join(" "), 3 )
|
||||||
.then( balance => {
|
.then( balance => {
|
||||||
const total = balance.reduce( (memo, line) => memo + line.amount, 0 );
|
const total = balance.reduce( (memo, line) => memo + line.amount, 0 );
|
||||||
|
|
||||||
UI.donut( document.getElementById( "donut" ),
|
UI.donut( document.querySelector( `${element_selector} #donut` ),
|
||||||
balance.map( line => {
|
balance.sort( (a, b) => b.amount - a.amount )
|
||||||
|
.map( line => {
|
||||||
line.color = Utils.text_to_color( line.account );
|
line.color = Utils.text_to_color( line.account );
|
||||||
line.percent = ( line.amount / total ) * 100;
|
line.percent = ( line.amount / total ) * 100;
|
||||||
|
line.tooltip = `${line.account} : ${line.amount} €`;
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
} ) );
|
} ) );
|
||||||
} );
|
} );
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="period">
|
||||||
|
<button onclick="Period.prev()">-</button>
|
||||||
|
<button onclick="Period.next()">+</button>
|
||||||
|
<h3 id="display"></h3>
|
||||||
|
</div>
|
||||||
|
<div id="month">
|
||||||
|
<div id="donut" style="height: 256; width: 256;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Period.set( new Date() );
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue