Skip to content

Instantly share code, notes, and snippets.

@smukked
Created December 9, 2016 22:47
Show Gist options
  • Save smukked/f3b7a6ffac4fccffddbf09bfd2d00bdc to your computer and use it in GitHub Desktop.
Save smukked/f3b7a6ffac4fccffddbf09bfd2d00bdc to your computer and use it in GitHub Desktop.
Chart - Pie - SVG - Angular - TypeScript

Chart - Pie - SVG - Angular - TypeScript

IE FIX: preserveAspectRatio="xMidYMin slice" style="padding-bottom: 50%; height: 1px;"

A Pen by Danny Schønning on CodePen.

License.

<div ng-app="PAQuickPoll">
<script type="text/ng-template" id="PAQuickPollPieTemplate.html">
<div class="paChart">
<svg class="paSvgChart" viewBox="0 0 338 338" width="100%" height="100%" preserveAspectRatio="xMidYMin slice">
<circle ng-repeat="question in questions" class="pie {{::question.id}}" r="160" cx="169" cy="169" ng-attr-data-id="{{::question.id}}" ng-attr-stroke="{{::question.color}}" ng-attr-stroke-dasharray="{{::question.percent}}, 1000" ng-attr-stroke-dashoffset="{{::question.dashOffset}}" ng-mouseover="highlightOver(question.id)" ng-mouseleave="highlightLeave(question.id)" />
<line ng-repeat="question in questions" class="pieline" x1="169" y1="169" ng-attr-x2="{{::question.lineX}}" ng-attr-y2="{{::question.lineY}}" />
</svg>
<div ng-repeat="question in questions" class="paChartResult {{::question.id}}" ng-mouseover="highlightOver(question.id)" ng-mouseleave="highlightLeave(question.id)">
<h2 ng-if="resultAsPercent" ng-style="{ color: question.color }">{{::question.percentTxt}}%</h2>
<h2 ng-if="!resultAsPercent" ng-style="{ color: question.color }">{{::question.votes}}</h2>
<p>{{::question.text}}</p>
</div>
</div>
</script>
<div style="width: 300px; float: left; padding-right: 30px;">
<h1>Do you have a problem?</h1>
<div pa-quick-poll-pie='{"resultAsPercent":false,"questions":[{"id":"p1","text":"No","color":"rgb(255, 56, 35)","votes":10},{"id":"p2","text":"Yes","color":"rgb(114, 187, 83)","votes":50}]}'></div>
</div>
<div style="width: 100%; float: left;">
<h1>Favorite dish?</h1>
<div pa-quick-poll-pie='{"resultAsPercent":true,"questions":[{"id":"pie1","text":"Salad Culvers fresh garden salades with big bold flavors","color":"rgb(114, 187, 83)","votes":35},{"id":"pie2","text":"Pancakes americanos espectaculare","color":"rgb(193, 208, 69)","votes":50},{"id":"pie3","text":"Chicken Florences Marsala, flavorful meal of mushrooms and prosciutto","color":"rgb(254, 198, 61)","votes":10},{"id":"pie4","text":"Pizza Di Napoli","color":"rgb(255, 56, 35)","votes":20}]}'></div>
</div>
</div>
namespace PAQuickPoll {
"use strict";
export class QuickPollPie {
public scope = {};
public link: any;
public restrict = "A";
public templateUrl = "PAQuickPollPieTemplate.html";
public static factory() {
let directive = () => {
return new QuickPollPie();
};
return directive;
}
constructor() {
this.link = (
$scope: any,
element: ng.IAugmentedJQuery,
attrs: any) => {
let props = angular.fromJson(attrs.paQuickPollPie);
let questions = props.questions;
let dashOffset = 0;
let totalVotes = 0;
let getLineCoords = (percentage: number): any => {
let x = 169 + 318 * Math.cos(2 * Math.PI * percentage / 100);
let y = 169 + 318 * Math.sin(2 * Math.PI * percentage / 100);
return {
x: x,
y: y
}
}
$scope.resultAsPercent = props.resultAsPercent;
for (let k in questions) {
totalVotes = totalVotes + questions[k].votes;
}
for (let k in questions) {
questions[k].dashOffset = dashOffset - (k * 2);
let lineCords = getLineCoords(dashOffset * -1 / 10);
questions[k].lineX = lineCords.x;
questions[k].lineY = lineCords.y;
questions[k].percent = questions[k].votes * 1000 / totalVotes;
questions[k].percentTxt = Math.round(questions[k].percent * 10) / 100;
dashOffset = dashOffset - questions[k].percent;
}
// Initialize
$scope.questions = questions;
$scope.highlightOver = (id: string) => {
element.find(".pie, .paChartResult").addClass("paChartOpacity");
element.find(".paChartResult." + id + ", .pie." + id).removeClass("paChartOpacity");
}
$scope.highlightLeave = (id: string) => {
element.find(".paChartResult, .pie").removeClass("paChartOpacity");
}
};
}
}
}
namespace PAQuickPoll {
export let moduleName = "PAQuickPoll";
let app = angular.module(moduleName, []);
app.directive("paQuickPollPie", QuickPollPie.factory());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
body { font-family: Calibri; }
h1 { font-size: 16px; }
.paChart {
svg.paSvgChart {
transform: rotate(-90deg);
border-radius: 50%;
}
circle.pie {
fill-opacity: 0;
stroke-width: 317;
pointer-events: visibleStroke;
cursor: pointer;
animation-name: paPie;
animation-duration: 1s;
animation-timing-function: ease-in;
}
line.pieline {
stroke: rgb(255, 255, 255);
stroke-linecap: round;
stroke-width: 5;
}
.paSvgChart {
width: 50%;
display: block;
margin: 0 auto;
/* IE HACK */
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
overflow: visible;
padding-bottom: 50%;
height: 1px;
}
.paChartOpacity {
opacity: .7;
}
}
.paChartResult {
cursor: pointer;
&.paChartOpacity {
opacity: .5;
}
h2 {
border-bottom: solid 1px;
margin: 0;
}
p {
margin: 0;
padding: 5px 0 10px;
}
}
@keyframes paPie {
from { stroke-dasharray: 0, 1000;}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment