0

I need to create a graph with a custom shape. For eg: to represent the population, I need to create a human shape inside which I would show the statistics and data. Is there any javascript library that would help me do this? would D3 js help me?

Any help is appreciated.

Thank you.

4 Answers 4

1

You can even try using this approach of using two images and overlaying each other.

Let's say you want a human fontawesome icon as a chart, convert the icon to .png image using http://fa2png.io/ and then use that in the below code.

http://codepen.io/FDfranklin/pen/yGbCK

<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

<div class="container">
    <div class="bw"></div>
    <div class="show"></div>
    <div id="bar" data-total="100">
        <div class="text">Currently at <br/><span>70</span><br><i>Click To Give</div>
    </div>
</div>

@import url(http://fonts.googleapis.com/css?family=Concert+One);

html, body {
  margin: 0 auto;
}

.container {
  width:450px;
  height:328px;
  position:relative;
  display:inline-block;
  vertical-align:top;
  background-clip:content-box;
}
.bw {
  width:100%;
  height:100%;
  position:absolute;
  bottom:0; background:url(http://fdfranklin.com/usf-bull-bw.png) fixed left top;
  background-clip:content-box;
}
.show {
  width:100%;
  height:0%;
  position:absolute;
  bottom:0; background:url(http://fdfranklin.com/usf-bull.png) fixed left top;
  background-clip:content-box;
}

#bar {
  width: 100%;
  height: 0%;
  position: absolute;
  bottom: 0;
  border-top: 1px dashed black;

  .load {
      opacity: 1;
    }


  div {
    position: absolute;
    line-height: 22px;
    width: 110px;
    top: -40px;
    right: -113px;
    font-family: arial, sans-serif;
    font-size: 16px;
    text-align: center;
    color: white;
    cursor: pointer;
    border: 1px solid #ccc;
    border-radius: 8px;
    background: #2f574b;
    transition: background 700ms ease-in-out;
    opacity: 0;
    -webkit-transition: opacity 3s ease-in, background 700ms ease-in-out;
    -moz-transition: opacity 3s ease-in, background 700ms ease-in-out;
    -o-transition: opacity 3s ease-in, background 700ms ease-in-out;
    -ms-transition: opacity 3s ease-in, background 700ms ease-in-out;
    transition: opacity 3s ease-in, background 700ms ease-in-out;

      &:hover {
      background: #B1A875;
    }

    span {
      font-family: 'Concert One', sans-serif;
      line-height: 30px;
      font-size: 34px;
      color: #white;;
    }
  }
}

<script>
percent = $('#bar div span').html();
total = $('#bar').attr('data-total');
percentStart = 0;

setInterval(function() {
  $('.show').css('height',percentStart/total*100+'%');
  $('#bar').css('height',percentStart/total*100+'%');
  $('#bar div span').html('%'+percentStart);
  if(percentStart<percent) {percentStart=percentStart+1;}
},35);

$("#bar div").addClass("load");

</script>
Sign up to request clarification or add additional context in comments.

Comments

0

I don't know about the "human-shape" thing and I don't think there is any tool out there that does so.

However, the best and closest resource I have come across is Highcharts It has all sorts of pie, spline, bar, etc. you will need to plot your data interactively.

I also recommend taking a look at Google Charts. One thing Highcharts does not provide is map based data plotting. Google has something known as GeoMap for data plotting information with locations as specific as a small town around the globe

Comments

0

Alternatively, a simple way of doing this is setting a repeating background image and altering DIV width/heights based on your counts. Benefit is that there is virtually no performance hit in any browser, since DIV heights and repeating image backgrounds are fairly optimized.

two divs: uninterrupted and partial

Idea is to pick a tile size (ex: 25 x 11) and break it up into two DIVs. In image above, the first DIV is visually accountable for two rows, since they're not broken up (maximum width). The second DIV displays the last row, since its width represents a partial number.

function draw_guys( num, row_width ) {
    var whole = Math.floor( num / row_width ) * row_width;
    var rows = whole / row_width;
    var remainder = num - whole;

    // at this point, first div height should be 11 * rows,
    // and second div width should be remainder * 25
    // $("div1").css( ... etc.
}

For a working example, see this Facebook IPO calculator: http://www.voanews.com/content/how-long-would-it-take-you-to-earn-as-much-as-facebook-shareholders/667093.html

Comments

0

There are any number of javascript libraries that could be used to code such a thing, but I would be amazed if you found any "population graphs" that would behave as you describe out of the box.

I've done a lot of work in RaphaelJS recently, and depending on your use case you could code a simple graph from scratch with very little work. Consider this:

var figurePath = "m67.55634,478.32968c-8.13657,-2.48874 -14.5806,-8.08679 -16.4212,-14.26556c-0.73347,-2.46204 -1.08294,-52.8298 -1.08687,-156.62885l-0.00574,-152.99986l-4.12245,0l-4.12245,0l0,57.75455c0,56.61781 -0.04195,57.82326 -2.13101,61.24794c-2.70588,4.43591 -5.74459,6.5144 -11.69161,7.99719c-8.79226,2.19217 -18.40762,-1.9938 -21.86059,-9.51678c-2.22165,-4.84039 -2.07695,-133.9393 0.15908,-141.94215c5.04025,-18.03902 21.36259,-32.81751 40.39913,-36.578c10.0279,-1.98091 102.7426,-2.00536 112.74093,-0.02971c10.18434,2.01237 18.93166,6.56422 26.67169,13.87918c7.96135,7.52412 11.67772,13.62765 14.44972,23.73145c1.93217,7.04254 2.03873,10.81412 2.03873,72.15891c0,56.07582 -0.21188,65.2007 -1.58522,68.26476c-2.13536,4.76425 -4.33276,6.9068 -9.23622,9.00589c-8.13713,3.48325 -18.47925,1.24234 -23.2908,-5.04663l-2.47462,-3.23438l-0.28067,-58.8461l-0.2807,-58.84612l-4.09941,0l-4.09944,0l0,153.75127c0,168.54004 0.40904,157.34918 -5.98071,163.62524c-5.04742,4.95758 -10.19456,6.83295 -18.75407,6.83295c-8.55949,0 -13.70664,-1.87537 -18.75407,-6.83295c-6.26537,-6.1539 -5.98071,-1.38409 -5.98071,-100.21561l0,-90.34155l-4.12245,0l-4.12248,0l0,90.34155c0,73.62247 -0.25719,90.91376 -1.38974,93.4332c-2.07629,4.61884 -6.59314,9.17279 -11.33463,11.42776c-4.56992,2.17331 -14.94501,3.1835 -19.23141,1.87241zm23.18207,-395.70253c-12.45886,-4.14828 -20.1591,-10.54255 -25.6095,-21.26616c-3.01675,-5.93541 -3.23429,-7.07562 -3.23429,-16.95192c0,-9.99342 0.18727,-10.94311 3.33264,-16.8991c15.71025,-29.74877 61.06589,-29.82171 76.74945,-0.12342c3.24734,6.14913 3.39783,6.92425 3.39783,17.50292c0,10.17379 -0.23299,11.51108 -2.88087,16.53765c-4.4481,8.44392 -11.01797,14.60091 -19.99178,18.73535c-6.96733,3.21001 -8.73656,3.60972 -17.18201,3.8817c-7.08677,0.2282 -10.69254,-0.12219 -14.58147,-1.41702z";

var figure = canvas.path( figurePath )
    .attr( { fill: 'red', stroke: 'black', 'stroke-width': 3, transform: 'S0.86,0.85 0,0 T0,0', 'fill-opacity': 0, 'stroke-opacity': .5 } )
    .animate( { 'fill-opacity': 0.5, 'stroke-opacity': 1.0, transform: 'S1,1 0,0' }, 1000, '>', function()
        {
            var text = canvas.text( 100, 150, "Population:\n10,250" )
                            .attr( { 'font-size': 16, fill: 'black', stroke: 'none', 'font-weight': 400, 'font-family': 'Arial,Helvetica,sans-serif', 'fill-opacity': 0 } )
                            .animate( { 'fill-opacity': 1.0 }, 1000 );
        } );

var figure2 = canvas.path( figurePath )
    .attr( { fill: 'blue', stroke: 'black', 'stroke-width': 3, transform: 'S0.43,0.43 0,0 T250,125', 'fill-opacity': 0, 'stroke-opacity': .5 } )
    .animate( { 'fill-opacity': 0.5, 'stroke-opacity': 1.0, transform: 'S0.6,0.6 0,0 T250,100' }, 1000, '>', function()
        {
            var text = canvas.text( 312, 190, "Population:\n6,632" )
                            .attr( { 'font-size': 12, fill: 'black', stroke: 'none', 'font-weight': 400, 'font-family': 'Arial,Helvetica,sans-serif', 'fill-opacity': 0 } )
                            .animate( { 'fill-opacity': 1.0 }, 1000 );
        } );        

Or, check out the fiddles:

- http://jsfiddle.net/kevindivdbyzero/McSzB/
- http://jsfiddle.net/kevindivdbyzero/mSX8e/2/

7 Comments

Hi, your example looks great to me... but What i need is a single figure inside which there are different shades of data. Eg: in one human structure, we can show in form of stacked chart. So there will be different shades of color in one human structure which would differentiate the various figures
How did you come up with the figurepath? I mean how did you know exactly the values of how to create a human figure? What if I want to show two different values with two different colors in the same human figure?
As for the path: I found a public domain svg and then used svg-edit to scale it down to the proportions you see here (svg-edit is great for simple editing tasks, by the way).
As for the segregation of data... let me revise my fiddle slightly.
It's not ideal, but you can essentially reuse the same path and apply a clip-rect to the fragment that corresponds to the current region. That might be enough to do what you want, though.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.