├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── babel.config.js
├── dist
├── circliful.js
└── main.css
├── docs
├── api.md
├── create-new-circle.md
├── dev-environment.md
├── options.md
└── style-elements.md
├── package-lock.json
├── package.json
├── public
├── custom.css
├── fraction.html
└── index.html
├── src
├── api.ts
├── base-class
│ ├── base-circle.ts
│ ├── circle-factory.ts
│ ├── circle.ts
│ ├── options.ts
│ └── svg-tags.ts
├── circle-type
│ ├── fraction-circle.ts
│ ├── half-circle.ts
│ ├── plain-circle.ts
│ └── simple-circle.ts
├── helper
│ ├── object-helper.ts
│ ├── style-helper.ts
│ └── svg-tags-helper.ts
├── index.ts
└── interface
│ ├── iattributes.ts
│ ├── iavailable-options.ts
│ ├── icalculation-params.ts
│ ├── idictionary.ts
│ ├── iprogress-color.ts
│ ├── isize.ts
│ ├── itag.ts
│ ├── itype.ts
│ └── iview-box-attributes.ts
├── style
├── main.scss
└── modules
│ ├── background-circle.scss
│ ├── circle-container.scss
│ ├── circle-icon.scss
│ ├── circle-text.scss
│ ├── foreground-circle.scss
│ └── point-circle.scss
├── test
├── base-class
│ ├── circle-factory.test.ts
│ └── options.test.ts
└── helper
│ ├── object-helper.test.ts
│ └── svg-tags-helper.test.ts
├── tsconfig.json
├── tslint.json
├── webpack.dev.config.js
└── webpack.prod.config.js
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | coverage
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | coverage
4 | public
5 | docs
6 | src
7 | style
8 | test
9 | babel.config.js
10 | tsconfig.json
11 | tslint.json
12 | webpack.dev.config.js
13 | webpack.prod.config.js
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Patric Gutersohn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Circle Statistics #
2 |
3 | Test it https://stackblitz.com/edit/js-2m2bs7
4 |
5 | New implementation of circliful, without any dependencies - dependencies are only used for development like webpack, jest, typescript, tslint and babel.
6 |
7 | * show Infos as Circle Statistics, no images used
8 | * based on SVG
9 | * many options can be set
10 | * fully responsive
11 |
12 | ## How to use circliful
13 |
14 | Include circliful to your Site via script tag. If you want to use font-awesome icons you need to include the files separately.
15 |
16 | Github clone / download
17 |
18 | ```
19 |
20 |
21 |
22 |
23 |
24 |
31 | ```
32 |
33 | npm package
34 |
35 | ```
36 | npm i js-plugin-circliful
37 | ```
38 |
39 | ```javascript
40 | import {circliful} from 'js-plugin-circliful';
41 |
42 | circliful.newCircle({
43 | percent: 50,
44 | id: 'circle',
45 | type: 'simple',
46 | });
47 | ```
48 |
49 | ```css
50 | @import 'js-plugin-circliful/dist/main.css';
51 | ```
52 |
53 | ```html
54 |
55 | ```
56 |
57 | ## Documentation
58 |
59 | * [Api](./docs/api.md)
60 | * [Create custom circle](./docs/create-new-circle.md)
61 | * [Setup dev enviroment (with webpack)](./docs/dev-environment.md)
62 | * [List of available options](./docs/options.md)
63 | * [Style your cirles via css](./docs/style-elements.md)
64 |
65 | If you feel there is something missing in the documentation or the library please open a issue.
66 |
67 | Donation
68 | --------
69 | If you find this plugin useful or/and use it commercially feel free to donate me a cup of coffee :)
70 |
71 | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=D3F2MMNDHQ9KQ)
72 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | // for jest (unit testing)
2 | module.exports = {
3 | presets: [
4 | ["@babel/preset-env", {targets: {node: "current"}}],
5 | "@babel/preset-typescript",
6 | ],
7 | };
8 |
--------------------------------------------------------------------------------
/dist/circliful.js:
--------------------------------------------------------------------------------
1 | var circliful=function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=7)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(){}return t.setAttributes=function(t,e){for(var i=0,n=Object.entries(e);ia.x&&(u=!0,a.x=a.x-.001),["M",a.x,a.y,"A",n,n,0,d,s,c.x,c.y,u?"Z":""].join(" ")},t.calculatePathEndCoordinates=function(e,i,n,r){return t.polarToCartesian(e,i,n,r)},t}();e.default=n},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(){}return t.extractPropertyFromObject=function(t,e){var i;return t.hasOwnProperty(e)&&t[e]&&(i=t[e]),i},t}();e.default=n},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(1),r=i(0),o=function(){function t(){}return t.addSvg=function(e){var i=document.createElementNS(t.namespaceURI,"svg");return e.class="circle-container "+n.default.extractPropertyFromObject(e,"class"),r.default.setAttributes(i,e),i},t.addCircle=function(e){var i=document.createElementNS(t.namespaceURI,"circle");return r.default.setAttributes(i,e),i},t.addArc=function(e){var i=document.createElementNS(t.namespaceURI,"path");return r.default.setAttributes(i,e),i},t.addText=function(e){var i=document.createElementNS(t.namespaceURI,"text");return i.setAttributeNS(null,"text-anchor","middle"),r.default.setAttributes(i,e),i},t.addDefs=function(e){var i=document.createElementNS(t.namespaceURI,"defs"),n=document.createElementNS(t.namespaceURI,"linearGradient");r.default.setAttributes(n,{id:"linearGradient"});var o=document.createElementNS(t.namespaceURI,"stop"),s={offset:"0","stop-color":e.gradientStart};r.default.setAttributes(o,s);var a=document.createElementNS(t.namespaceURI,"stop"),c={offset:"1","stop-color":e.gradientEnd};return r.default.setAttributes(a,c),n.appendChild(o),n.appendChild(a),i.appendChild(n),i},t.namespaceURI="http://www.w3.org/2000/svg",t}();e.default=o},function(t,e,i){"use strict";var n=this&&this.__assign||function(){return(n=Object.assign||function(t){for(var e,i=1,n=arguments.length;ie},t.prototype.drawContainer=function(t){var e=this.getViewBoxParams(),i=e.minX,o=e.minY,s=e.width,a=e.height,c=r.default.addSvg(n({width:"100%",height:"100%",viewBox:i+" "+o+" "+s+" "+a,id:"svg-"+this.options.id,preserveAspectRatio:"xMinYMin meet"},t));this.tags.push({element:c,parentId:this.options.id})},t.prototype.getViewBoxParams=function(){var t=this.options,e=t.foregroundCircleWidth,i=t.backgroundCircleWidth,n=i;e>i&&(n=e);var r=this.size.width,o=this.size.height;return(e>5||i>5)&&(r=this.size.width,o=this.size.height),{minX:0,minY:0,width:r,height:o}},t.prototype.append=function(){this.tags.forEach((function(t){document.getElementById(t.parentId).appendChild(t.element)}))},t.prototype.initialize=function(t,e){this.options=t,this.size=e},t}();e.BaseCircle=o},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(0),r=function(){function t(){}return t.animateArc=function(e,i){var r=e.arc,o=e.arcParams,s=e.animationStep,a=e.progressColors,c=o.startAngle?o.startAngle:0,d=o.endAngleGrade?o.endAngleGrade:360,u=this.getMilliseconds(o.ms,o.endAngleGrade),p=Array.isArray(a)&&a.length>0,l=1,h=setInterval((function(e,r,a){var u=d/100*l,f=c<0&&u>286?"1":"0";n.default.setAttributes(e,{d:n.default.describeArc(o.x,o.y,o.radius,c,u,f)}),p&&t.updateCircleColor(l,e,a),((l+=s)>r||l>100)&&(clearInterval(h),"function"==typeof i&&i())}),u,r,o.percent,a)},t.updateCircleColor=function(t,e,i){var r=i.find((function(e){return e.percent===t}));r&&n.default.setAttributes(e,{style:"stroke: "+r.color})},t.getMilliseconds=function(t,e){var i=t||50;return e<=180&&(i/=3),i},t}();e.StyleHelper=r},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(9),r=i(10),o=i(14),s=function(){function t(){}return t.getParentSize=function(t){return{maxSize:100,height:100,width:100}},t.initializeCircleType=function(e,i){void 0===i&&(i=!1);var n=t.getParentSize(e.id),s=r.CircleFactory.create(e.type),a=(new o.default).mergeOptions(e,i);return s.initialize(a,n),s.drawCircle(),s},t.prototype.newCircle=function(e){return t.initializeCircleType(e),new n.Api(e)},t.prototype.newCircleWithDataSet=function(e,i){var r={id:e,type:i,percent:1};return t.initializeCircleType(r,!0),new n.Api(r)},t}();e.default=s},function(t,e,i){"use strict";var n,r=this&&this.__extends||(n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)},function(t,e){function i(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)});Object.defineProperty(e,"__esModule",{value:!0});var o=i(3),s=i(2),a=i(1),c=i(4),d=i(0),u=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.coordinates={x:0,y:0},e.additionalCssClasses={},e}return r(e,t),e.prototype.initialize=function(e,i){t.prototype.initialize.call(this,e,i);var n=this.size.maxSize;this.coordinates={x:n/2,y:n/2},this.radius=n/2.2,this.options.additionalCssClasses&&(this.additionalCssClasses=this.options.additionalCssClasses),this.animateInView()},e.prototype.drawCircle=function(){var t={class:a.default.extractPropertyFromObject(this.additionalCssClasses,"svgContainer")};this.drawContainer(t),this.options.strokeGradient&&this.drawLinearGradient(),this.drawBackgroundCircle(),this.drawForegroundCircle(),this.options.point&&this.drawPoint(),this.options.icon&&this.drawIcon(),this.drawText(),!this.options.textReplacesPercentage&&this.options.text&&this.drawInfoText(),this.append()},e.prototype.drawBackgroundCircle=function(){var t=a.default.extractPropertyFromObject(this.additionalCssClasses,"backgroundCircle"),e=s.default.addCircle({id:"circle-"+this.options.id,class:"background-circle "+t,cx:String(this.coordinates.x),cy:String(this.coordinates.y),r:String(this.radius),"stroke-width":this.options.backgroundCircleWidth});this.tags.push({element:e,parentId:"svg-"+this.options.id})},e.prototype.drawPoint=function(){var t=this.radius/100*this.options.pointSize,e=a.default.extractPropertyFromObject(this.additionalCssClasses,"point"),i=s.default.addCircle({id:"point-"+this.options.id,class:"point-circle "+e,cx:String(this.coordinates.x),cy:String(this.coordinates.y),r:String(t)});this.tags.push({element:i,parentId:"svg-"+this.options.id})},e.prototype.drawForegroundCircle=function(){var t=3.6*this.options.percent+Number(this.options.startAngle),e=this.options.startAngle?this.options.startAngle:0,i=a.default.extractPropertyFromObject(this.additionalCssClasses,"foregroundCircle"),n={id:"arc-"+this.options.id,class:"foreground-circle "+i,d:d.default.describeArc(this.coordinates.x,this.coordinates.y,this.radius,e,t),"stroke-width":this.options.foregroundCircleWidth,"stroke-linecap":this.options.strokeLinecap};this.options.strokeGradient&&(n.stroke="url(#linearGradient)",n.class="foreground-circle-without-stroke-color "+i);var r=s.default.addArc(n);this.options.animation&&!this.options.startAngle?this.animate(r):this.drawArc(r),this.tags.push({element:r,parentId:"svg-"+this.options.id})},e.prototype.drawArc=function(t){var e={percent:this.options.percent,x:this.coordinates.x,y:this.coordinates.y,radius:this.radius},i=3.6*this.options.percent;d.default.setAttributes(t,{d:d.default.describeArc(e.x,e.y,e.radius,0,i,"0")})},e.prototype.animate=function(t,e){c.StyleHelper.animateArc({arc:t,arcParams:{percent:e||this.options.percent,x:this.coordinates.x,y:this.coordinates.y,radius:this.radius},animationStep:this.options.animationStep,progressColors:this.options.progressColors},this.options.onAnimationEnd)},e.prototype.drawIcon=function(){var t=this.options.icon,e=a.default.extractPropertyFromObject(this.additionalCssClasses,"icon"),i=s.default.addText({id:"text-"+this.options.id,x:String(this.coordinates.x),y:String(this.coordinates.y-25),class:"circle-icon fa "+e});i.innerHTML=""+t+";",this.tags.push({element:i,parentId:"svg-"+this.options.id})},e.prototype.drawText=function(){var t=a.default.extractPropertyFromObject(this.additionalCssClasses,"text"),e=s.default.addText({id:"text-"+this.options.id,x:String(this.coordinates.x),y:String(this.coordinates.y),class:"circle-text "+t}),i=this.options.noPercentageSign?"":"%",n=""+this.options.percent+i;this.options.textReplacesPercentage&&this.options.text&&(n=this.options.text),e.textContent=n,this.tags.push({element:e,parentId:"svg-"+this.options.id})},e.prototype.drawInfoText=function(){var t=a.default.extractPropertyFromObject(this.additionalCssClasses,"infoText"),e=s.default.addText({id:"text-"+this.options.id,x:String(this.coordinates.x),y:String(this.coordinates.y+20),class:"circle-info-text "+t});e.textContent=this.options.text,this.tags.push({element:e,parentId:"svg-"+this.options.id})},e.prototype.drawLinearGradient=function(){var t={};t.gradientStart=this.options.strokeGradient[0],t.gradientEnd=this.options.strokeGradient[1];var e=s.default.addDefs(t);this.tags.push({element:e,parentId:"svg-"+this.options.id})},e}(o.BaseCircle);e.default=u},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),i(8);var n=i(5);e.newCircle=function(t){return(new n.default).newCircle(t)},e.newCircleWithDataSet=function(t,e){return(new n.default).newCircleWithDataSet(t,e)}},function(t,e,i){},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(5),r=i(1),o=function(){function t(t){this.options=t}return t.prototype.update=function(t){var e=this;document.getElementById("svg-"+this.options.id).remove(),Array.isArray(t)?t.forEach((function(t){return e.updateType(t.type,t.value)})):this.updateType(t.type,t.value),n.default.initializeCircleType(this.options)},t.prototype.updateType=function(t,e){switch(t){case"percent":this.options.percent=Number(e);break;case"point":this.options.point=Boolean(e);break;case"animation":this.options.animation=Boolean(e);break;case"pointSize":this.options.pointSize=Number(e);break;case"animationStep":this.options.animationStep=Number(e);break;case"strokeGradient":this.options.strokeGradient=e;break;case"icon":this.options.icon=String(e);break;case"text":this.options.text=String(e);break;case"textReplacesPercentage":this.options.textReplacesPercentage=Boolean(e);break;case"foregroundCircleWidth":this.options.foregroundCircleWidth=Number(e);break;case"backgroundCircleWidth":this.options.backgroundCircleWidth=Number(e);break;case"additionalCssClasses":this.options.additionalCssClasses=e;break;case"progressColors":this.options.progressColors=e}},t.prototype.get=function(t){return r.default.extractPropertyFromObject(this.options,t)},t}();e.Api=o},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(11),r=i(12),o=i(13),s=i(6),a=function(){function t(){}return t.create=function(t){var e;switch(t.toLowerCase()){case"half":e=new r.default;break;case"plain":e=new o.default;break;case"simple":e=new s.default;break;case"fraction":e=new n.default;break;default:e=new s.default}return e},t}();e.CircleFactory=a},function(t,e,i){"use strict";var n,r=this&&this.__extends||(n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)},function(t,e){function i(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)});Object.defineProperty(e,"__esModule",{value:!0});var o=i(3),s=i(2),a=i(0),c=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.coordinates={x:0,y:0},e.additionalCssClasses={},e}return r(e,t),e.isOdd=function(t){return t%2},e.prototype.initialize=function(e,i){t.prototype.initialize.call(this,e,i);var n=this.size.maxSize;this.coordinates={x:n/2,y:n/2},this.radius=n/2.2,this.options.additionalCssClasses&&(this.additionalCssClasses=this.options.additionalCssClasses),this.animateInView()},e.prototype.drawCircle=function(){this.drawContainer(),this.drawFraction(),this.append()},e.prototype.drawFraction=function(){this.fractionAngle=360/this.options.fractionCount;for(var t=0;t=2){var n=this.options.fractionColors;i=e.isOdd(t)?n[0]:n[1]}t>=this.options.fractionFilledCount&&(i="none"),this.drawArc(i)}},e.prototype.drawArc=function(t){var e=s.default.addArc({id:"arc-"+this.options.id,class:"fraction",d:a.default.describeArc(this.coordinates.x,this.coordinates.y,this.radius,0,this.fractionAngle)+this.getLineToCenter(),"stroke-width":this.options.foregroundCircleWidth,fill:t,stroke:this.options.strokeColor,transform:"rotate("+this.rotateDegree+", "+this.coordinates.x+", "+this.coordinates.y+")"});this.tags.push({element:e,parentId:"svg-"+this.options.id})},e.prototype.getLineToCenter=function(){var t=a.default.calculatePathEndCoordinates(this.coordinates.x,this.coordinates.y,this.radius,this.fractionAngle);return" L "+this.coordinates.y+" "+this.coordinates.x+" M "+t.x+" "+t.y+" L "+this.coordinates.y+" "+this.coordinates.x},e.prototype.animate=function(t){},e}(o.BaseCircle);e.default=c},function(t,e,i){"use strict";var n,r=this&&this.__extends||(n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)},function(t,e){function i(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)});Object.defineProperty(e,"__esModule",{value:!0});var o=i(2),s=i(1),a=i(4),c=i(0),d=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return r(e,t),e.prototype.drawCircle=function(){var t={class:s.default.extractPropertyFromObject(this.additionalCssClasses,"svgContainer")};this.drawContainer(t),this.drawBackgroundCircle(),this.drawForegroundCircle(),this.drawText(),this.append()},e.prototype.drawBackgroundCircle=function(){var t=s.default.extractPropertyFromObject(this.additionalCssClasses,"backgroundCircle"),e=o.default.addArc({id:"bg-arc-"+this.options.id,d:c.default.describeArc(this.coordinates.x,this.coordinates.y,this.radius,270,90),class:"background-circle "+t,"stroke-width":this.options.backgroundCircleWidth});this.tags.push({element:e,parentId:"svg-"+this.options.id})},e.prototype.drawForegroundCircle=function(){var t=1.8*this.options.percent,e=s.default.extractPropertyFromObject(this.additionalCssClasses,"foregroundCircle"),i=o.default.addArc({id:"arc-"+this.options.id,class:"foreground-circle "+e,d:c.default.describeArc(this.coordinates.x,this.coordinates.y,this.radius,0,t),transform:"rotate(-90, "+this.coordinates.x+", "+this.coordinates.y+")","stroke-width":this.options.foregroundCircleWidth,"stroke-linecap":this.options.strokeLinecap});this.options.animation&&this.animate(i),this.tags.push({element:i,parentId:"svg-"+this.options.id})},e.prototype.animate=function(t){a.StyleHelper.animateArc({arc:t,arcParams:{percent:this.options.percent,x:this.coordinates.x,y:this.coordinates.y,radius:this.radius,endAngleGrade:180},animationStep:this.options.animationStep,progressColors:this.options.progressColors},this.options.onAnimationEnd)},e}(i(6).default);e.default=d},function(t,e,i){"use strict";var n,r=this&&this.__extends||(n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)},function(t,e){function i(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)});Object.defineProperty(e,"__esModule",{value:!0});var o=i(3),s=i(2),a=i(1),c=i(4),d=i(0),u=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.coordinates={x:0,y:0},e.additionalCssClasses={},e}return r(e,t),e.prototype.initialize=function(e,i){t.prototype.initialize.call(this,e,i);var n=this.size.maxSize;this.coordinates={x:n/2,y:n/2},this.radius=n/2.2,this.options.additionalCssClasses&&(this.additionalCssClasses=this.options.additionalCssClasses),this.animateInView()},e.prototype.drawCircle=function(){this.drawContainer(),this.drawPlainCircle(),this.append()},e.prototype.drawPlainCircle=function(){var t=this.options.startAngle?this.options.startAngle:0,e=3.6*this.options.percent+Number(t),i=a.default.extractPropertyFromObject(this.additionalCssClasses,"foregroundCircle"),n=s.default.addArc({id:"arc-"+this.options.id,class:"foreground-circle "+i,d:d.default.describeArc(this.coordinates.x,this.coordinates.y,this.radius,t,e),"stroke-width":this.options.foregroundCircleWidth,"stroke-linecap":this.options.strokeLinecap});this.options.animation&&!this.options.startAngle&&this.animate(n),this.tags.push({element:n,parentId:"svg-"+this.options.id})},e.prototype.animate=function(t){c.StyleHelper.animateArc({arc:t,arcParams:{percent:this.options.percent,x:this.coordinates.x,y:this.coordinates.y,radius:this.radius},animationStep:this.options.animationStep,progressColors:this.options.progressColors},this.options.onAnimationEnd)},e}(o.BaseCircle);e.default=u},function(t,e,i){"use strict";var n=this&&this.__assign||function(){return(n=Object.assign||function(t){for(var e,i=1,n=arguments.length;i
16 |
17 |
18 | // javascript call
19 | circliful.newCircleWithDataSet('circle', 'simple');
20 |
21 | #### Set via config object ####
22 |
23 | // html tag
24 |
25 |
26 | // javascript call
27 | circliful.newCircle({
28 | percent: 80,
29 | id: 'circle',
30 | type: 'simple',
31 | icon: 'f179',
32 | text: 'TP Wins',
33 | noPercentageSign: true,
34 | backgroundCircleWidth: 35,
35 | foregroundCircleWidth: 20,
36 | progressColors: [
37 | {percent: 1, color: 'red'},
38 | {percent: 30, color: 'orange'},
39 | {percent: 60, color: 'green'}
40 | ]
41 | });
42 |
43 | #### Available options ####
44 |
45 | | name | default | type | description
46 | | ------------- |------------- | ----- | ----- |
47 | | id | / | string | id of the html tag
48 | | type | "simple" | string | circle type
49 | | additionalCssClasses | / | object | on each element circle, text etc a custom css for styling can be set
50 | | point | false | boolean | a point in within the circle
51 | | pointSize | 60 | number | the point size in px
52 | | percent | 75 | number | the percentage of the circle
53 | | animation | true | boolean | if set to true, the circle percentage fill will be animated
54 | | animationStep | 1 | number | the animation speed
55 | | strokeGradient | / | [string, string] | will give the foreground circle a gradient
56 | | icon | / | string | font awesome icon definition for example 'f179', you need to integrate the font awesome library its not packed with circliful
57 | | text | / | string | will be shown below the percentage text
58 | | textReplacesPercentage | false | boolean | if set to true the text replaces the percentage
59 | | noPercentageSign | / | boolean | if set to true the % sign will be removed
60 | | animateInView | false | boolean | animates the circle as soon as its in the viewport
61 | | strokeLinecap | "butt" | string | the endings of the foreground circle, can be set to "butt" or "round"
62 | | foregroundCircleWidth | 5 | number | width of the foreground circle
63 | | backgroundCircleWidth | 15 | number | width of the background circle
64 | | progressColors | / | IProgressColor[] | the foreground circle changes the color if it comes above the given percentage colors for example [{percent: 50, color: "green"}]
65 | | onAnimationEnd | / | function | event that will be triggered when animation of circle finished
66 |
67 |
--------------------------------------------------------------------------------
/docs/style-elements.md:
--------------------------------------------------------------------------------
1 | SVG style changes via CSS
2 | ===================
3 |
4 | Change Position of Element
5 |
6 | The first argument is the x (horizontal) coordinate and the second argument is the y (vertical) coordinate.
7 |
8 | transform: translate(0, 20px)
9 |
10 | Hover Effect
11 |
12 | .circle-container:hover {
13 | .background-circle {
14 | fill: #ccc; //change background color
15 | }
16 |
17 | .foreground-circle {
18 | stroke: blueviolet; //change stroke color
19 | stroke-width: 8; // change stroke width
20 | }
21 | }
22 |
23 | Change Circle Color
24 |
25 | .foreground-circle or .background-circle {
26 | stroke: blueviolet;
27 | }
28 |
29 | Change background color of Point
30 |
31 | .point-circle {
32 | fill: #999;
33 | }
34 |
35 | Change width of circle
36 |
37 | .foreground-circle or .background-circle {
38 | stroke-width: 50px;
39 | }
40 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "js-plugin-circliful",
3 | "version": "2.0.15",
4 | "description": "circle statistic plugin without dependencies",
5 | "main": "dist/circliful.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/pguso/js-plugin-circliful"
9 | },
10 | "scripts": {
11 | "start:dev": "webpack-dev-server --config webpack.dev.config.js --content-base public/",
12 | "build": "webpack --config webpack.prod.config.js",
13 | "lint": "tslint -c tslint.json -p tsconfig.json --fix",
14 | "test": "jest --collectCoverage",
15 | "test:watch": "jest --watch"
16 | },
17 | "keywords": [
18 | "circliful",
19 | "vanilla",
20 | "circle",
21 | "statistic",
22 | "stats",
23 | "presentation",
24 | "svg",
25 | "fraction"
26 | ],
27 | "author": {
28 | "name": "Patric Gutersohn",
29 | "email": "patric@gutersohn.com"
30 | },
31 | "bugs": {
32 | "url": "https://github.com/pguso/js-plugin-circliful/issues"
33 | },
34 | "_id": "js-plugin-circliful@2.0.12",
35 | "readmeFilename": "README.md",
36 | "license": "MIT",
37 | "devDependencies": {
38 | "@babel/core": "^7.9.0",
39 | "@babel/plugin-transform-modules-umd": "^7.9.0",
40 | "@babel/preset-env": "^7.9.0",
41 | "@babel/preset-typescript": "^7.9.0",
42 | "@purtuga/esm-webpack-plugin": "^1.2.1",
43 | "@types/jest": "^25.2.1",
44 | "@types/node": "^13.9.4",
45 | "babel-loader": "^8.1.0",
46 | "babel-plugin-syntax-async-functions": "^6.13.0",
47 | "babel-plugin-transform-class-properties": "^6.24.1",
48 | "clean-webpack-plugin": "^3.0.0",
49 | "css-loader": "^3.4.2",
50 | "es6-promise-promise": "^1.0.0",
51 | "html-webpack-plugin": "^4.0.2",
52 | "jest": "^25.2.7",
53 | "mini-css-extract-plugin": "^0.9.0",
54 | "node-sass": "^4.13.1",
55 | "optimize-css-assets-webpack-plugin": "^5.0.3",
56 | "sass-loader": "^8.0.2",
57 | "style-loader": "^1.1.3",
58 | "terser-webpack-plugin": "^2.3.5",
59 | "ts-loader": "^6.2.2",
60 | "tslint": "^5.20.1",
61 | "tslint-loader": "^3.5.4",
62 | "typescript": "^3.8.3",
63 | "webpack": "^4.42.0",
64 | "webpack-cli": "^3.3.11",
65 | "webpack-dev-server": "^3.10.3"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/public/custom.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Arial, sans-serif;
3 | }
4 |
5 | .container {
6 | display: grid;
7 | grid-template-columns: 1fr 1fr 1fr;
8 | grid-template-rows: 1fr 1fr 1fr;
9 | }
10 |
11 | .circle-icon.fa {
12 | font-size: .8rem;
13 | fill: #3498DB;
14 | transform: translate(0, 5%); /* change position of circle */
15 | }
16 |
17 | .circle-text {
18 | font-size: .9rem;
19 | }
20 |
21 | .circle-info-text {
22 | transform: translate(0, -6%); /* position text outside of circle */
23 | font-size: .5rem;
24 | }
25 |
26 | #svg-circle2 {
27 | transform: translate(16%, 15%);
28 | }
29 |
30 | .circle-container {
31 | transform: translate(9%, 8%);
32 | }
33 |
--------------------------------------------------------------------------------
/public/fraction.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Circliful - examples
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Circliful - examples
6 |
7 |
8 |
9 |
10 |
11 |