Adding SVG based completion arc
This commit is contained in:
parent
a6ebafb234
commit
11e5f99ba4
2 changed files with 151 additions and 2 deletions
|
@ -9,8 +9,13 @@ import {get_strings} from 'core/str';
|
||||||
import {load_strings} from './string-helper';
|
import {load_strings} from './string-helper';
|
||||||
import {call} from 'core/ajax';
|
import {call} from 'core/ajax';
|
||||||
import notification from 'core/notification';
|
import notification from 'core/notification';
|
||||||
|
import {svgarcpath} from './svgarc';
|
||||||
//import {fixLineWrappers} from './studyplan-processor';
|
//import {fixLineWrappers} from './studyplan-processor';
|
||||||
|
|
||||||
|
// Make π available as a constant
|
||||||
|
const π = Math.PI;
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue/*,options*/){
|
install(Vue/*,options*/){
|
||||||
|
|
||||||
|
@ -30,7 +35,7 @@ export default {
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
* *
|
* *
|
||||||
* Treestudyplan Editor components *
|
* Treestudyplan Viewer components *
|
||||||
* *
|
* *
|
||||||
************************************/
|
************************************/
|
||||||
|
|
||||||
|
@ -43,6 +48,81 @@ export default {
|
||||||
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
|
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vue.component('r-progress-circle',{
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
default: 100,
|
||||||
|
},
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
type: Number,
|
||||||
|
default: 0.2,
|
||||||
|
},
|
||||||
|
bgopacity: {
|
||||||
|
type: Number,
|
||||||
|
default: 0.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedstudyplan: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
range() {
|
||||||
|
return this.max - this.min;
|
||||||
|
},
|
||||||
|
fraction(){
|
||||||
|
if(this.max - this.min == 0){
|
||||||
|
return 1;
|
||||||
|
// 0 size is always full :)
|
||||||
|
} else {
|
||||||
|
return (this.value - this.min)/(this.max - this.min);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
center() {
|
||||||
|
const x = (1+this.stroke)*50;
|
||||||
|
const y = x;
|
||||||
|
return { 'x' : x, 'y' : y };
|
||||||
|
},
|
||||||
|
size() {
|
||||||
|
const w = (1+this.stroke)*100;
|
||||||
|
const h = w;
|
||||||
|
return { 'h' : h, 'w' : w };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
arcpath(cx, cy, r) {
|
||||||
|
let fraction = 1;
|
||||||
|
if(this.max - this.min != 0){
|
||||||
|
fraction = (this.value - this.min)/(this.max - this.min);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Δ = fraction * 2*π;
|
||||||
|
return svgarcpath([cx,cy],[r,r],[0,Δ],270);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<span class='r-progress-circle'><svg
|
||||||
|
:width="(1+stroke)+'em'"
|
||||||
|
:height="(1+stroke)+'em'"
|
||||||
|
:viewbox="'0 0 '+ size.w + ' '+size.h">
|
||||||
|
<circle :cx="center.x" :cy="center.y" :r="50"
|
||||||
|
:style="'opacity: ' + bgopacity + ';stroke-width: '+ (stroke*100)+'; stroke: currentcolor; fill: none;'"/>
|
||||||
|
<path :d="arcpath(center.x,center.y,50)"
|
||||||
|
:style="'stroke-width: ' + (stroke*100) +'; stroke: currentcolor; fill: none;'"/>
|
||||||
|
</svg></span>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
Vue.component('r-report', {
|
Vue.component('r-report', {
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
|
@ -545,7 +625,13 @@ export default {
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col md="11">
|
<b-col md="11">
|
||||||
<b-card-body class="align-items-center">
|
<b-card-body class="align-items-center">
|
||||||
<i v-b-popover.top
|
<r-progress-circle v-if='value.course.completion'
|
||||||
|
:value='value.course.completion.progress'
|
||||||
|
:max='value.course.completion.count'
|
||||||
|
:min='0'
|
||||||
|
:class="'r-course-result r-completion-'+value.completion"
|
||||||
|
></r-progress-circle>
|
||||||
|
<i v-else v-b-popover.top
|
||||||
:class="'r-course-result fa fa-'+completion_icon(value.completion)+
|
:class="'r-course-result fa fa-'+completion_icon(value.completion)+
|
||||||
' r-completion-'+value.completion"
|
' r-completion-'+value.completion"
|
||||||
:title="text['completion_'+value.completion]"></i>
|
:title="text['completion_'+value.completion]"></i>
|
||||||
|
|
63
amd/src/svgarc.js
Normal file
63
amd/src/svgarc.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
Copyright © 2020 Xah Lee, © 2023 P.M Kuipers
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the “Software”),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
URL: SVG Circle Arc http://xahlee.info/js/svg_circle_arc.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
const cos = Math.cos;
|
||||||
|
const sin = Math.sin;
|
||||||
|
const π = Math.PI;
|
||||||
|
|
||||||
|
const f_matrix_times = (( [[a,b], [c,d]], [x,y]) => [ a * x + b * y, c * x + d * y]);
|
||||||
|
const f_rotate_matrix = (x => [[cos(x),-sin(x)], [sin(x), cos(x)]]);
|
||||||
|
const f_vec_add = (([a1, a2], [b1, b2]) => [a1 + b1, a2 + b2]);
|
||||||
|
|
||||||
|
// function modified by pmkuipers for text params
|
||||||
|
/**
|
||||||
|
* Create svg path text for an arc
|
||||||
|
* @param {*} center [cx,cy] center of ellipse
|
||||||
|
* @param {*} radius [rx,ry] major minor radius
|
||||||
|
* @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.
|
||||||
|
* @param {*} φ rotation on the whole, in radian
|
||||||
|
* @returns a SVG path element that represent a ellipse. Text describing the arc path in an svg path element
|
||||||
|
*/
|
||||||
|
const svgarcpath = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {
|
||||||
|
Δ = Δ % (2*π);
|
||||||
|
const rotMatrix = f_rotate_matrix (φ);
|
||||||
|
const [sX, sY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1), ry * sin(t1)] ), [cx,cy] ) );
|
||||||
|
const [eX, eY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1+Δ), ry * sin(t1+Δ)] ), [cx,cy] ) );
|
||||||
|
const fA = ( ( Δ > π ) ? 1 : 0 );
|
||||||
|
const fS = ( ( Δ > 0 ) ? 1 : 0 );
|
||||||
|
return "M " + sX + " " + sY + " A " + [ rx , ry , φ / (2*π) *360, fA, fS, eX, eY ].join(" ");
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an svg arc element
|
||||||
|
* @param {*} center [cx,cy] center of ellipse
|
||||||
|
* @param {*} radius [rx,ry] major minor radius
|
||||||
|
* @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.
|
||||||
|
* @param {*} φ rotation on the whole, in radian
|
||||||
|
* @returns a SVG path element that represent a ellipse.
|
||||||
|
*/
|
||||||
|
const svgarc = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {
|
||||||
|
const path_2wk2r = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||||
|
const d = svgarcpath([cx,cy],[rx,ry], [t1, Δ], φ );
|
||||||
|
path_2wk2r.setAttribute("d", d);
|
||||||
|
return path_2wk2r;
|
||||||
|
});
|
||||||
|
|
||||||
|
export {svgarc, svgarcpath};
|
Loading…
Reference in a new issue