Skip to content

Instantly share code, notes, and snippets.

@benbrandt22
Last active June 2, 2016 17:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benbrandt22/48638b1d7e2e954c0735 to your computer and use it in GitHub Desktop.
Save benbrandt22/48638b1d7e2e954c0735 to your computer and use it in GitHub Desktop.
C# Razor SVG Pie Chart
public class PieChart
{
public PieChart() {
this.Slices = new List<PieChartSlice>();
}
public List<PieChartSlice> Slices { get; set; }
public class PieChartSlice {
public decimal Value { get; set; }
public string DisplayValue { get; set; }
public string Label { get; set; }
public Color Color { get; set; }
}
}
@model Application.Models.PieChart
@functions {
double pieCenterX = 0;
double pieCenterY = 0;
double pieRadius = 50;
public string PieSlicePathDesc(double startAngleRadians, double angleRadians) {
bool longArcFlag = (angleRadians > Math.PI);
var startX = pieCenterX + (pieRadius * Math.Cos(startAngleRadians));
var startY = pieCenterY + (pieRadius * Math.Sin(startAngleRadians));
var endX = pieCenterX + (pieRadius * Math.Cos((startAngleRadians + angleRadians)));
var endY = pieCenterY + (pieRadius * Math.Sin((startAngleRadians + angleRadians)));
string pathDesc = string.Format("M{0:0.###},{1:0.###} L{2:0.###},{3:0.###} A{4:0.###},{4:0.###} 0 {5},1 {6:0.###},{7:0.###} z",
pieCenterX,
pieCenterY,
startX,
startY,
pieRadius,
(longArcFlag ? 1 : 0),
endX,
endY
);
return pathDesc;
}
}
@{
double startAngle = -(Math.PI/2); // (12-o-clock position)
}
<svg width="100%" height="200" viewBox="@(pieRadius * -1.1) @(pieRadius * -1.1) @(pieRadius * 1.1 * 2) @(pieRadius * 1.1 * 2)">
<style>
/* <![CDATA[ */
.pieChartSlice {
fill-opacity: 1;
stroke: white;
stroke-width: 1px;
stroke-linejoin: bevel; /* prevents "pointy ends" from overlapping onto other pie slices */
}
/* ]]> */
</style>
@foreach (var slice in Model.Slices)
{
var slicePercentage = (double)(slice.Value / Model.Slices.Sum(s => s.Value));
var sliceAngleRadians = slicePercentage * (2 * Math.PI);
var sliceColor = (System.Drawing.ColorTranslator.ToHtml(slice.Color));
<g>
<title>
@(string.Format("{0}: {1} ({2})", slice.Label, slice.DisplayValue, string.Format("{0:0.#}%", (100 * slicePercentage))))
</title>
@if (Model.Slices.Count == 1)
{
<circle class="pieChartSlice" cx="@pieCenterX" cy="@pieCenterY" r="@pieRadius" fill="@sliceColor" />
}
else
{
<path class="pieChartSlice" d="@PieSlicePathDesc(startAngle, sliceAngleRadians)" fill="@sliceColor" />
}
<animateTransform attributeName="transform" type="scale" from="1 1 0 0" to="1.05 1.05 0 0"
begin="mouseover" dur="0.1s" fill="freeze" repeatCount="1" />
<animateTransform attributeName="transform" type="scale" from="1.05 1.05 0 0" to="1 1 0 0"
begin="mouseout" dur="0.1s" fill="freeze" repeatCount="1" />
</g>
startAngle += sliceAngleRadians; // increment to the starting position for the next slice
}
</svg>
<div>
@Html.DisplayFor(viewModel => viewModel.MyPieChart)
</div
@apeirophobe
Copy link

Is it possible to get the slice animations working in IE?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment