block by larskotthoff 8689540

8689540

Full Screen

index.html

<!DOCTYPE html>
 
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <style>
            .container {                
                width: 100%;
                height: 500px;
            }
        </style>
         <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
         <script type="text/javascript" src="progress.js"></script>
    </head>
    <body>
        <div class="container"> 
            <svg id="cp_svg">
                
            </svg>    
        </div>
        <script>
		          
            function getRandomRange(min, max) {
                return Math.random() * (max - min) + min;
            }
			
			var graph = ht.cp;
			graph.init("#cp_svg", 800, 500);
            graph.labels[0].startValue=0;
            graph.labels[0].endValue=300;
            graph.setProgress(280);
            graph.graph();
 
            setInterval(function(){
               graph.setProgress(getRandomRange(200,250));
               graph.graph();
                
            },2000);
        </script>
    </body>
</html>

progress.js

var ht = ht || {};
ht.cp = (function () {
    var svg;
    var cp ={};	
    cp.svgId = '';
    cp.dotLabelSettings = new Array();	
    cp.textLabelSettings = new Array();	
	cp.arcSettings = [
		{
		   "totalArcAngle":300,
			"startAngle":-150,
			"endAngle":-150,
			//"progressValue":200,
			"radius":150,
			"thickness":40,		
		}
    ]; 
	//settings for labels	
	cp.labels = [
		{
			"pointThickness": 3,
            "distance": 60,
            "textDistance": 30,
            "strokeColor": "#888",
            "strokeWidth": 0.5,
            "textColor": "#777",
            "pointColor": "#888",
            "textSize": 4,
            //"interval":100,
            //"precision":2,
            "num": 10,
            "startValue": 0,
            "endValue": 300
		}
	];

    cp.graphTitle = {
        "text":"Power",
        "size":20,
        "color":"#bbb"        
    }
	
	//styling circular graph elements
	cp.graphStyles = {					
			"progressColor":'#3791ed',
			"transitionTiming":1500,
			"innerCircle":{
				"radius":null,
				"lineWidth":0,
				"strokeColor":"rgba(200,200,200,0.9)",
				"fillColor":"#2e2e2e",
				"text":"270",
				"textSize":7,
				"textColor":"#096ed4"
			}																	        
    };

    cp.init = function (svgId, width, height) {
      this.svgId = svgId;  
      this.setCenter(width,height);
      svg = d3.select(svgId)
        .attr("height", height)
        .attr("width", width)
        //.attr("viewBox","0 0 500 500")
        //.attr("preserveAspectRatio", "xMidYMid meet")
        .append("g")
        .attr("transform", "translate("+width/2+","+height/2+")");

    //initailize graph styles    
    this.initGraphStyles(); 


    svg.append("text")
            .attr("x",0)
            .attr("y",10)
            .attr("text-anchor","middle")
            .attr("fill",this.graphTitle.color)
            .attr("font-size",12)
            .attr("id", "progressValue"); 
   
    };

    cp.getSvg = function(){
        return d3.select(this.svgId);
    }

    cp.setCenter = function(width,height){
        this.svgCenter = {
            cx:0,
            cy: 0
        }
    }

    cp.getCenter = function(){
        return this.svgCenter;
    }

    cp.getOneUnit = function(){
        return (this.arcSettings[0].totalArcAngle) / (this.labels[0].endValue - this.labels[0].startValue);		        
    }

    cp.currentProgress = cp.arcSettings[0].endAngle;

    cp.getCurrentProgress = function(){
        return this.currentProgress;
    }

    cp.setProgress = function(val){        
         var oneUnit = this.getOneUnit();
         this.currentProgress = this.arcSettings[0].startAngle + (val * oneUnit);
         this.displayValue(val);		 
    }
    cp.degreeToRadian = function(deg){
         return deg * Math.PI / 180.0;
    }

    var arc = d3.svg.arc()
                     .startAngle(function (d) {
                         return cp.degreeToRadian(d.startAngle);
                     })
                     .endAngle(function (d) {
                         return cp.degreeToRadian(d.endAngle);
                     })
                     .innerRadius(function (d) {
                         return d.radius
                     })
                     .outerRadius(function (d) {
                         return d.thickness + d.radius;
                     });
    cp.bind = function(){
        var g;                       
        g = svg.selectAll("g")
                .data(this.arcSettings)
                  .enter().append("g")
                .attr("class", "arc");        
        g.append("path")
            .style("fill", this.graphStyles.progressColor)
            .attr("d", arc);           
    }

    cp.graph = function(){
        this.bind();    
        selectArcs();              
    }

    cp.initGraphStyles = function(){
        
        //circle that passes through dot labels
        svg.append("circle")        
        .attr("class","dotLabelsCircle")
        .attr("cx",0)
        .attr("cy",0)       
        .attr("r",this.arcSettings[0].radius + this.labels[0].distance)
        .style("fill","none")
        .style("stroke",this.labels[0].strokeColor);

        //inncer circle
        svg.append("circle")
            .attr("class","innerCircle")
            .attr("cx",0)
            .attr("cy",0)       
            .attr("r",this.arcSettings[0].radius + this.arcSettings[0].thickness-0.6)
            .style("fill",this.graphStyles.innerCircle.fillColor)            
            .style("stroke","none");

        svg.append("text")
            .attr("x",0)
            .attr("y",-this.arcSettings[0].radius/2)
            .attr("text-anchor","middle")
            .attr("fill",this.graphTitle.color)
            .attr("font-size",this.graphTitle.size)
            .text(this.graphTitle.text);

               
        this.drawLabel();
  
    }

    function selectArcs() {
                d3.selectAll("g.arc > path")
                 .each(arcTween);
            }

    function arcTween() {
        d3.select(this)
         .transition().duration(cp.graphStyles.transitionTiming)
         .attrTween("d", tweenArc({ endAngle: cp.getCurrentProgress() }));
    }

    function tweenArc(b) {        
        return function (a) {           
            var i = d3.interpolate(a, b);
            for (var key in b) a[key] = b[key]; // update data
            return function (t) {
                return arc(i(t));
            };
        };
    }

    cp.polarToCartesian = function(centerX, centerY, radius, angleInDegrees) {
        var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
        return {
        x: centerX + (radius * Math.cos(angleInRadians)),
        y: centerY + (radius * Math.sin(angleInRadians))
        };
    }

    cp.displayValue = function(val){
        svg.select("#progressValue")
            .text(val);
    }

    // i am planning to use this function for drawing the labels
    cp.drawLabel = function() {

        var textLabelRadius = this.arcSettings[0].radius + this.labels[0].distance + this.labels[0].textDistance;
       
       //invisible circle for label text
       // this.drawCircle(this.circularProgressSettings.x, this.circularProgressSettings.y, textLabelRadius, 1, "rgba(0,0,0,1)","none");

        label = this.labels[0];
        if (label.num) {
            interval = (label.endValue - label.startValue) / label.num;
        } else {
            interval = label.interval;
        }
        numOfLabels = (label.endValue - label.startValue) / interval;
        angleInterval = (this.arcSettings[0].totalArcAngle) / numOfLabels;

        labels = new Array();
        angle = (-this.arcSettings[0].totalArcAngle/2);

        for (var value = label.startValue; value <= label.endValue; value += interval) {        
            labels.push({
                angle: angle,
                value: value
            });
            angle += angleInterval;
        } 
        //console.log(labels);

        //loop for label and text
        for (i = 0; i < labels.length; i++) {
            angle = labels[i].angle;
            value = labels[i].value;
            if(label.precision == null){
                if( value % 1 !== 0) {
                    value = value.toFixed(2);
                }
            } else {
                value = value.toFixed(label.precision);
            }



            pointRadius = this.arcSettings[0].radius + label.distance;        
            DotPoints = this.polarToCartesian(this.getCenter().cx, this.getCenter().cy, pointRadius, angle);
            TextPoints = this.polarToCartesian(this.getCenter().cx, this.getCenter().cy, textLabelRadius, angle);                              
           
            this.dotLabelSettings.push(
                {
                    dotX:DotPoints.x,
                    dotY:DotPoints.y,
                                         
                }
            );
            this.textLabelSettings.push(
                {
                    value:value,    
                    textX:TextPoints.x,
                    textY:TextPoints.y      
                }
            )
            
          
            //draw dots here using d3 and the data i that i will be probably binding is this.labelSettings
            /**this.drawCircle(DotPoints.x, DotPoints.y,this.circularProgressSettings.label.pointThickness, '', '', this.circularProgressSettings.label.pointColor);       
            this.set("id",this.getSvgId()+"_label_dot_"+i);
            
            //draw text labels using d3
               this.drawText(value, TextPoints.x, TextPoints.y+2, this.circularProgressSettings.label.textSize, 'none', this.circularProgressSettings.label.textColor);     
               this.set("id",this.getSvgId()+"_label_text_"+i);           
            */
        }  
        this.drawDots(); 
        this.drawTextLabels();

    }

    cp.drawDots = function(){                             
    svg.selectAll("circle.dots")                
            .style("fill",this.labels[0].pointColor)
            .style("stroke","none")       
            .data(this.dotLabelSettings)
            .enter()
            .append("circle")
            .attr("class","dots")               
            .attr("r", this.labels[0].pointThickness)
            .attr("cx", function(d){            
                return d.dotX;
            })
            .attr("cy", function(d){
                return d.dotY;
            });
    
    }
    
    cp.drawTextLabels = function() {
        svg.selectAll("text.dots")      
            .data(this.textLabelSettings)
            .enter()
            .append("text")
            .attr("class","dots")
            .attr("x", function(d) { return d.textX; })
            .attr("y", function(d) { return d.textY+5; })
            .attr("text-anchor","middle")
            .text(function(d) { return d.value; });        
    }
    
    return cp;
})();