Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Arc Chart</title>
- <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
- <style type="text/css">
- .chart-gauge {
- width: 400px;
- height: 230px;
- margin: 100px auto;
- }
- .chart-filled {
- fill: steelblue;
- }
- .chart-empty {
- fill: #dedede;
- }
- .needle,
- .needle-center {
- display: none;
- }
- svg {
- font: 15px sans-serif;
- }
- .title {
- transform: translate( -40px, 10px);
- }
- .chart-gauge .percent {
- display: block;
- transform: translate( -45px, -30px);
- font-size: 50px;
- }
- .chart-gauge .sub-title {
- transform: translate(-190px, -165px);
- }
- .chart-gauge .min-perc {
- transform: translate(-150px, 20px);
- }
- .chart-gauge .max-perc {
- transform: translate(130px, 20px);
- }
- </style>
- </head>
- <body>
- <div class="chart-gauge"></div>
- <script type="text/javascript">
- var dataSet = [{
- "title": "Dollar Comps",
- "subtitle": "Bay 1",
- "percent": .45
- }, {
- "title": "Unit Comps",
- "subtitle": "Bay 1",
- "percent": .65
- }, {
- "title": "Dollar Comps",
- "subtitle": "Bay 2",
- "percent": .35
- }, {
- "title": "Unit Comps",
- "subtitle": "Bay 2",
- "percent": .75
- } ];
- function LoadChart(data) {
- for (i = 0; i < data.length; i++) {
- var needle;
- var barWidth, chart, chartInset, degToRad, repaintGauge,
- height, margin, numSections, padRad, percToDeg, percToRad,
- radius, sectionIndx, svg, totalPercent, width;
- numSections = 1;
- sectionPerc = 1 / numSections / 2;
- padRad = 0.025;
- chartInset = 10;
- // Orientation of gauge:
- totalPercent = .75;
- el = d3.select('.chart-gauge');
- margin = {
- top: 20,
- right: 20,
- bottom: 30,
- left: 20
- };
- width = el[0][0].offsetWidth - margin.left - margin.right;
- height = width;
- radius = Math.min(width, height) / 2;
- barWidth = 40 * width / 300;
- /*
- Utility methods
- */
- percToDeg = function(perc) {
- return perc * 360;
- };
- percToRad = function(perc) {
- return degToRad(percToDeg(perc));
- };
- degToRad = function(deg) {
- return deg * Math.PI / 180;
- };
- // Create SVG element
- svg = el.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom);
- // Add layer for the panel
- chart = svg.append('g').attr('transform', "translate(" + ((width + margin.left) / 2) + ", " + ((height + margin.top) / 2) + ")");
- chart.append('path').attr('class', "arc chart-filled");
- chart.append('path').attr('class', "arc chart-empty");
- chart.append("text")
- .attr("class", "title")
- .text(data[i].title);
- chart.append("text")
- .attr("class", "sub-title")
- .text(data[i].subtitle);
- chart.append("text")
- .attr("class", "min-perc")
- .text( "0%" );
- chart.append("text")
- .attr("class", "max-perc")
- .text("100%");
- arc2 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
- arc1 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
- repaintGauge = function(perc) {
- var next_start = totalPercent;
- arcStartRad = percToRad(next_start);
- arcEndRad = arcStartRad + percToRad(perc / 2);
- next_start += perc / 2;
- arc1.startAngle(arcStartRad).endAngle(arcEndRad);
- arcStartRad = percToRad(next_start);
- arcEndRad = arcStartRad + percToRad((1 - perc) / 2);
- arc2.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
- chart.select(".chart-filled").attr('d', arc1);
- chart.select(".chart-empty").attr('d', arc2);
- }
- var Needle = (function() {
- /**
- * Helper function that returns the `d` value
- * for moving the needle
- **/
- var recalcPointerPos = function(perc) {
- var centerX, centerY, leftX, leftY, rightX, rightY, thetaRad, topX, topY;
- thetaRad = percToRad(perc / 2);
- centerX = 0;
- centerY = 0;
- topX = centerX - this.len * Math.cos(thetaRad);
- topY = centerY - this.len * Math.sin(thetaRad);
- leftX = centerX - this.radius * Math.cos(thetaRad - Math.PI / 2);
- leftY = centerY - this.radius * Math.sin(thetaRad - Math.PI / 2);
- rightX = centerX - this.radius * Math.cos(thetaRad + Math.PI / 2);
- rightY = centerY - this.radius * Math.sin(thetaRad + Math.PI / 2);
- return "M " + leftX + " " + leftY + " L " + topX + " " + topY + " L " + rightX + " " + rightY;
- };
- function Needle(el) {
- this.el = el;
- this.len = width / 3;
- this.radius = this.len / 6;
- }
- Needle.prototype.render = function() {
- this.el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius);
- return this.el.append('path').attr('class', 'needle').attr('d', recalcPointerPos.call(this, 0));
- };
- Needle.prototype.moveTo = function(perc) {
- var self,
- oldValue = this.perc || 0;
- this.perc = perc;
- self = this;
- // Reset pointer position
- this.el.transition().delay(100).ease('quad').duration(200).select('.needle').tween('reset-progress', function() {
- return function(percentOfPercent) {
- var progress = (1 - percentOfPercent) * oldValue;
- repaintGauge(progress);
- return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
- };
- });
- this.el.transition().delay(200).ease("elastic").duration(500).select('.needle').tween('progress', function() {
- return function(percentOfPercent) {
- var progress = percentOfPercent * perc;
- repaintGauge(progress);
- return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
- };
- });
- };
- chart.append("text")
- .attr("class", "percent")
- .text(data[i].percent * 100 + "%");
- return Needle;
- })();
- needle = new Needle(chart);
- needle.render();
- needle.moveTo(data[i].percent);
- }
- }
- //console.log(dataSet);
- LoadChart(dataSet);
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment