D3 Custom Graph

In this example below you will see how to do a D3 Custom Graph with some HTML / CSS and Javascript

This graph was influenced by... something I saw on the internet. Possibly an Android screen? Sorry anonymous victims of copyright infringement!

Thumbnail
This awesome code was written by jey, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright jey ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>D3 Custom Graph</title>
  
  
  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

      <body>


    	 <div class="svg"></div>

</body>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.3/d3.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/jey/d3-custom-graph-BocGw */
@import url(https://fonts.googleapis.com/css?family=Quicksand:300);

 * {
  margin: 0;
  padding: 0;
}
body {
  background: #542854;
  font-family: 'Open-Sans',sans-serif;

}




.svg {
width:400px;
height:400px;
overflow: visible;
position:absolute;
left:50%;
margin-left:-200px;
}



.bigText{
        fill: white;
        font-family: 'Quicksand', sans-serif;
        font-size: 50px;
        text-anchor: middle;
}

.smallText{
        fill: white;
        font-family: 'Quicksand', sans-serif;
        font-size: 14px;
        text-anchor: middle;
}

.buttonText{
        fill: white;
        font-family: 'Quicksand', sans-serif;
        font-size: 10px;
        text-anchor: middle;
}


/*Downloaded from https://www.codeseek.co/jey/d3-custom-graph-BocGw */
var duckArrayLen = 100;

var ducks = new Array();
//ducks can fly and swim at same time for nicer transitions
for (var i = 0; i < duckArrayLen; i++){
    var duck = {};
    duck.id = i;
    duck.age = (Math.random());
    duck.size = (Math.random());
    var flying = (Math.random()*2);
        if (flying > 1){
            duck.isFlying = true;
        } else {
            duck.isFlying = false;
        }
    var swimming = (Math.random()*2);
    if (swimming > 0.75){ //slightly more ducks swimming
        duck.isSwimming = true;
    } else {
        duck.isSwimming = false;
    }
    ducks.push(duck);
};

var sizeScale = d3.scale.linear()
            .domain([0, 1])
            .range([5, 20]);//no ducks smaller than 5 pounds!

var ageScale = d3.scale.linear()
            .domain([0, 1])
            .range([1, 22]);


var swimmingDucks = 0;
var flyingDucks = 0;
var displaySwim = true;
var displayAge = true;

//count swimming and flying ducks so we can get a percentage
for (var i = 0; i < ducks.length; i++){
    if (ducks[i].isSwimming == true){
        swimmingDucks++;
    }
        if (ducks[i].isFlying == true){
        flyingDucks++;
    }
};

var percentDucks = swimmingDucks/ducks.length;
var percentDucksFly = flyingDucks/ducks.length;



      var diameter = 200;
      var w = 400;
      var h = 400;

      var svg = d3.select("body")
            .append("svg")
            .attr("width", w)
            .attr("height", h)
            .attr("class", "svg");



//if swim true
    var swimArc = d3.svg.arc()
    .innerRadius(diameter/2)
    .outerRadius(diameter/2+1)
    .endAngle(percentDucks * 360 * (Math.PI/180))
    .startAngle(0);

    var mySwimPath = svg.append("path")
    .attr("d", swimArc)
    .attr("transform", "translate(" + w/2+ "," + h/2 + ")")
    .attr("opacity", 0);


    var swimPathEl = mySwimPath.node();
    var swimPathLen = swimPathEl.getTotalLength();


    var swimPathEl = mySwimPath.node();
    var swimPathLen = swimPathEl.getTotalLength();

    //non-swimming ducks
    var swimArcRemainder = d3.svg.arc()
    .innerRadius(diameter/2)
    .outerRadius(diameter/2+1)
    .endAngle(360)
    .startAngle(percentDucks * 360 * (Math.PI/180));

    var mySwimPathRemainder = svg.append("path")
    .attr("d", swimArcRemainder)
    .attr("transform", "translate(" + w/2+ "," + h/2 + ")")
    .attr("opacity", 0);

    var swimPathElRemainder = mySwimPathRemainder.node();
    var swimPathLenRemainder = swimPathElRemainder.getTotalLength();

    //if fly true
    var flyArc = d3.svg.arc()
    .innerRadius(diameter/2)
    .outerRadius(diameter/2+1)
    .endAngle(percentDucksFly * 360 * (Math.PI/180))
    .startAngle(0);

    var myFlyPath = svg.append("path")
    .attr("d", flyArc)
    .attr("transform", "translate(" + w/2+ "," + h/2 + ")")
    .attr("opacity", 0);


    var flyPathEl = myFlyPath.node();
    var flyPathLen = flyPathEl.getTotalLength();


    var flyPathEl = myFlyPath.node();
    var flyPathLen = flyPathEl.getTotalLength();

    //non-flying ducks
    var flyArcRemainder = d3.svg.arc()
    .innerRadius(diameter/2)
    .outerRadius(diameter/2+1)
    .endAngle(360)
    .startAngle(percentDucksFly * 360 * (Math.PI/180));

    var myFlyPathRemainder = svg.append("path")
    .attr("d", flyArcRemainder)
    .attr("transform", "translate(" + w/2+ "," + h/2 + ")")
    .attr("opacity", 0);

    var flyPathElRemainder = myFlyPathRemainder.node();
    var flyPathLenRemainder = flyPathElRemainder.getTotalLength();



    var littleCircles = svg.selectAll("circle")
    .data(ducks)
    .enter()
    .append("circle")
    .attr("cx", function(d, i){
        if (ducks[i].isSwimming){
            return w/2 + swimPathEl.getPointAtLength(swimPathLen*i/ducks.length).x;
        } else {
            return w/2 + swimPathElRemainder.getPointAtLength(swimPathLenRemainder*i/ducks.length).x;
        }
     })
     .attr("cy", function(d, i){
        if (ducks[i].isSwimming){
       return h/2 + swimPathEl.getPointAtLength(swimPathLen*i/ducks.length).y;
        } else {
          return h/2 + swimPathElRemainder.getPointAtLength(swimPathLenRemainder*i/ducks.length).y;

        }
     })
     .attr("r", function(d){
         return ageScale(d.age);
     })
     .attr("stroke", "none")
     .attr("fill", "rgb(200,15,50)")
     .style("opacity", function(d,i){
        if(ducks[i].isSwimming){
            return ageScale(d.age)/22-0.2;
        } else {
            return 0;
        }
     });



     var bigCircle = svg.append("circle")
                         .attr("cx", w/2)
                         .attr("cy", h/2)
                         .attr("r", diameter/2-5);

    var text = svg.append("text")
        .text("" + swimmingDucks + "")
        .attr("x", w/2)
        .attr("y", h/2-5)
        .attr("class", "bigText");

    var smallText = svg.append("text")
    .text("ducks swimming,")
    .attr("x", w/2)
    .attr("y", h/2+15)
    .attr("class", "smallText");

    var smallText2 = svg.append("text")
    .text("sized by age")
    .attr("x", w/2)
    .attr("y", h/2+35)
    .attr("class", "smallText");

var buttonBackground1 = svg.append("rect")
                        .attr("x", "20")
                        .attr("y", "75")
                        .attr("width", "105")
                        .attr("height", "25")
                        .attr("fill", "#472247");

var buttonBackground2 = svg.append("rect")
                        .attr("x", "20")
                        .attr("y", "110")
                        .attr("width", "105")
                        .attr("height", "25")
                        .attr("fill", "#472247");

var agesizeButton = svg.append("rect")
                        .attr("x", "24")//alt 73
                        .attr("y", "79")
                        .attr("width", "48")
                        .attr("height", "17")
                        .attr("fill", "#7A3B7A")
                        .on("click", function ()
                                    {
  if (displayAge){
        agesizeButton.transition()
                    .attr("x","73");
                    littleCircles.transition()
                            .style("opacity", function(d,i){
                            if (displaySwim){
                            if(ducks[i].isSwimming){
                                    return sizeScale(d.size)/20-0.2;
                            } else {
                                return 0;
                            }
                        } else {
                            if(ducks[i].isFlying){
                                return sizeScale(d.size)/20-0.2;
                            } else {
                                return 0;
                            }
                        }

                         })
                         .attr("r", function(d){
                            return sizeScale(d.size);
                         });
                          smallText2.transition()
                            .text("sized by weight");
                        displayAge = false; 
                }                    
                else {
                    agesizeButton.transition()
                    .attr("x","24");
                    littleCircles.transition()
                            .style("opacity", function(d,i){
                            if (displaySwim){
                            if(ducks[i].isSwimming){
                                    return ageScale(d.age)/22-0.2;
                            } else {
                                return 0;
                            }
                        } else {
                            if(ducks[i].isFlying){
                                return ageScale(d.age)/22-0.2;
                            } else {
                                return 0;
                            }
                        }

                         })
                            .attr("r", function(d){
                            return ageScale(d.age);
                         });
                             smallText2.transition()
                            .text("sized by age");
                    displayAge = true;
                };

                                    });
console.log(displaySwim);
var flyswimButton = svg.append("rect")
                        .attr("x", "24")//alt 73
                        .attr("y", "114")
                        .attr("width", "48")
                        .attr("height", "17")
                        .attr("fill", "#7A3B7A")
                        .on("click", function(){
   if (displaySwim){
        flyswimButton.transition()
                    .attr("x","73");
                      littleCircles.transition()
                     .attr("fill", "rgb(15,75,150)")
                    .attr("cx", function(d, i){
                        if (ducks[i].isFlying){
                        return w/2 + flyPathEl.getPointAtLength(flyPathLen*i/ducks.length).x;
                        } else {
                        return w/2 + flyPathElRemainder.getPointAtLength(flyPathLenRemainder*i/ducks.length).x;
                        }
                })
                     .attr("cy", function(d, i){
                        if (ducks[i].isFlying){
                        return h/2 + flyPathEl.getPointAtLength(flyPathLen*i/ducks.length).y;
                        } else {
                        return h/2 + flyPathElRemainder.getPointAtLength(flyPathLenRemainder*i/ducks.length).y;
                        }
                }) 
                     .style("opacity", function(d,i){
                            if (displayAge){
                            if(ducks[i].isFlying){
                                    return ageScale(d.age)/22-0.2;
                            } else {
                                return 0;
                            }
                        } else {
                            if(ducks[i].isFlying){
                                return sizeScale(d.size)/20-0.2;
                            } else {
                                return 0;
                            }
                        }

                         });
                     text.transition()
                            .text("" + flyingDucks + "");
                    smallText.transition()
                            .text("ducks flying,");

                    displaySwim = false;
                } else {
                    flyswimButton.transition()
                    .attr("x","24");
                     littleCircles.transition()
                     .attr("fill", "rgb(200,15,50)")
                    .attr("cx", function(d, i){
                        if (ducks[i].isSwimming){
                        return w/2 + swimPathEl.getPointAtLength(swimPathLen*i/ducks.length).x;
                        } else {
                        return w/2 + swimPathElRemainder.getPointAtLength(swimPathLenRemainder*i/ducks.length).x;
                        }
                })
                     .attr("cy", function(d, i){
                        if (ducks[i].isSwimming){
                        return h/2 + swimPathEl.getPointAtLength(swimPathLen*i/ducks.length).y;
                        } else {
                        return h/2 + swimPathElRemainder.getPointAtLength(swimPathLenRemainder*i/ducks.length).y;
                        }
                })
                     .style("opacity", function(d,i){
                            if (displayAge){
                            if(ducks[i].isSwimming){
                                    return ageScale(d.age)/22-0.2;
                            } else {
                                return 0;
                            }
                        } else {
                            if(ducks[i].isSwimming){
                                return sizeScale(d.size)/20-0.2;
                            } else {
                                return 0;
                            }
                        }

                         });
                                          text.transition()
                            .text("" + swimmingDucks + "");
                                                smallText.transition()
                            .text("ducks swimming,");

                    displaySwim = true;
                };
    });

 var agetext = svg.append("text")
        .text("age")
        .attr("x", "47")
        .attr("y", "90")
        .attr("class", "buttonText");

 var sizetext = svg.append("text")
        .text("weight")
        .attr("x", "97")
        .attr("y", "90")
        .attr("class", "buttonText");

 var swimmingtext = svg.append("text")
        .text("swim")
        .attr("x", "48")
        .attr("y", "125")
        .attr("class", "buttonText");

 var flyingtext = svg.append("text")
        .text("fly")
        .attr("x", "97")
        .attr("y", "125")
        .attr("class", "buttonText");

Comments