How can I create custom shaped graphs? - javascript
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.
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>
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
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.
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
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/
Related
Animate dot after dot from an image using CSS3 or jQuery
I want to animate dot after dot from the below image but my problem is with the curved section of the image (bottom of the image). At the start, all dots should be hidden and then one by one each dot should be animated into view. I have the below code: <div id="dots1"></div> #dots1 { -moz-transition: height 1s linear; -o-transition: height 1s linear; -webkit-transition: height 1s linear; transition: height 1s linear; position: absolute; left: 50%; z-index: 1; margin: 0 0 0 -1px; width: 3px; height: 0; background: url(image/pic.png) 0 0 no-repeat; }
You can achieve this effect using two SVG path elements like in the below snippet. Two paths in the form of the curved line that you need is created. One path (which is at the bottom) has the dot pattern for the stroke (black colored) and another duplicate path which is on top. The duplicate path stroke is set such that for one full length of the path it is white in color and for another length it is transparent. An animation is added on the duplicate path to animate stroke's offset. As offset is animated, the white portion of the stroke slowly moves out of view and the transparent portion starts coming into view. As the white portion starts going out of view, the black dots below it start getting revealed. It is a bit complex to understand at start but once you get familiar with path, stroke-dasharray and stroke-dashoffset it will look simple. svg { height: 400px; } path { fill: none; } path.dot { stroke: black; stroke-dasharray: 0.1 4; stroke-linecap: round; } path.top { stroke: white; stroke-width: 2; stroke-dasharray: 250; stroke-linecap: round; animation: dash 15s linear forwards; } #keyframes dash { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -250; } } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg viewBox='0 0 100 100'> <path d='M1,1 1,45 C1,60 30,60 30,75 C30,90 1,90 1,100' class='dot' /> <path d='M1,1 1,45 C1,60 30,60 30,75 C30,90 1,90 1,100' class='top' /> </svg>
Try the following: HTML <div id="dots"> <img src="http://i.stack.imgur.com/oxUh8.png"> </div> jQuery $("#dots").css("height", "514px"); CSS #dots{ overflow: hidden; height: 10px; transition: all 3s cubic-bezier(.5, 1, 0, .5); } See: https://jsfiddle.net/brezkryx/
Is it possible to fade in radially using jQuery?
I am trying to make a logo fade in on the page load using jQuery. You can normally accomplish it on page load by just using: $(document).ready(function() { $("div").fadeIn(800); }); I am wondering if you could either manipulate the event .fadeIn(); or any jQuery to have the image fade in a circular motion. I am trying to go for a single circular motion, not multiple fade in motions. I know there are ways to manipulate the linear direction of an object fading in using top, left, right, or down. I haven't found a way to make it fade in ( or fade out ) to a webpage using a circular direction. In words: First, the image from the angles 0 to 90 degrees will fade in, in order. Next, the image from the angles 90 to 180 will fade in, in order. Then, the image from the angles 180 to 270 will fade in, in order. Finally, you'll be able to see the image from 270 to the full image. If you couldn't follow the words, here is a visual example of what I am trying to accomplish, but it isn't as smooth as I am going for. So far I have tried having it fade down from the top but then maybe rotate it but that wasn't what I was looking for. I'm not very knowledgeable on how to fix problems in jQuery, but I am asking how do I accomplish this, not specifically my code. If this can't be accomplished using jQuery, then can it be accomplished using either CSS or some sort of jQuery plugin? If it is possible, is there a way to fade the div out the same way?
If I understand you right you can try something like this: example: http://jsfiddle.net/hju3dyot/ if you want it to appear more like a scroller you can simple reduce time in the setTimeout function like this HTML: <div id="container"> <div class="img" id="left-top"></div> <div class="img" id="right-top"></div> <div class="img" id="left-bottom"></div> <div class="img" id="right-bottom"></div> </div> CSS: #container { height: 900px; width: 450px; margin: 2% auto; border: 1px solid #5970bb; border-radius: 3px; box-shadow: 10px 10px 20px rgba(35, 35, 35, 0.50); padding: 5px; } .img { background: url(http://s14.postimg.org/cdkclcbep/cat.jpg) no-repeat; height: 250px; width: 200px; display: inline-block; opacity: 0; -moz-transition: opacity 1s; -o-transition: opacity 1s; -webkit-transition: opacity 1s; transition: opacity 1s; } #left-top { background-position: -34px 0; } #right-top { background-position: -199px -10px; } #left-bottom { background-position: -25px -210px; } #right-bottom { background-position: -208px -207px; } .visible { opacity: 1; -moz-transition: opacity 1s; -o-transition: opacity 1s; -webkit-transition: opacity 1s; transition: opacity 1s; } SCRIPT: var arr = ["#left-top", "#right-top", "#right-bottom", "#left-bottom"]; var counter = 0; $(document).ready(function () { function makeItVisible() { if (counter < arr.length) { $(".img").removeClass("visible"); $(arr[counter++]).addClass("visible"); } else { counter = 0; return; } }; setInterval(makeItVisible, 2000); });
How do I change the colour of an SVG shape using jQuery?
Hi, folks! New here! Hoping to contribute a fair amount to the community in the future. But first, I need a hand with something I imagine to be fairly simple! I've always been all about the design aspect of the web, so mainly concentrated on HTML and CSS. I've only recently started looking in to learning JavaScript/jQuery, so bear with me, haha! I'm having a little trouble with changing the colour of an SVG shape using jQuery. The basic idea is that when the user scrolls down the page, certain elements will change colour. The HTML elements change as expected, but the SVG properties don't. I've read something about SVG DOM being different to HTML DOM, but can't really make much sense of it? A small explanation along with any help wouldn't be ignored! Here is my HTML: <header> <div id="headercontainer"> <object id="logo" type="image/svg+xml" data="images/kennyheardlogo.svg"></object> <nav><a id="homelink" href="index.html">HOME</a> | <a id="aboutlink" href="index.html">ABOUT</a> | <a id="worklink" href="index.html">WORK</a> | <a id="sociallink" href="index.html">SOCIAL</a></nav> </div> </header> Here is my CSS: header { position: fixed; z-index: 1; width: 100%; height: 150px; background-color: #ffffff; -webkit-box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.5); -moz-box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.5); box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.5); opacity: 0.8; -webkit-transition: background-color 0.5s ease; -moz-transition: background-color 0.5s ease; transition: background-color 0.5s ease; } .headerfade { background-color: #000000; } nav { position: absolute; top: 65px; right: 40px; width: 480px; height: auto; color: #000000; text-align: center; letter-spacing: 10px; font-size: 10px; } nav, nav a { -webkit-transition: color 0.5s ease; -moz-transition: color 0.5s ease; transition: color 0.5s ease; } .navfade { color: #ffffff !important; } #icon { fill: #000000; } .iconfade { fill: #ffffff; } #letterk, #letterh { fill: #ffffff; } #text path { fill: #000000; } Here is my jQuery: $(window).scroll(function() { var scroll = $(window).scrollTop(); if (scroll >= 350) { $("header").addClass("headerfade"); $("nav, nav a").addClass("navfade"); $("#icon").addClass("iconfade"); } else { $("header").removeClass("headerfade"); $("nav, nav a").removeClass("navfade"); $("#icon").removeClass("iconfade"); } }); The initial colour of "#icon" is black, but when the user scrolls 350px from the top of the page, I want the colour to change to white. That is what I have done with the "header" and "nav" elements, which worked perfectly. So, any ideas? I'm hoping I've not missed something embarrassingly obvious, haha! Thanks for any help you can provide, guys!
There are two things wrong here. You can't directly access the contents of an <object> like that. You need to get the contentDocument and access it that way. CSS doesn't work across document boundaries. Even once you add the iconfade class to #icon, it won't be able to see it because the CSS is in a different document. What you can do is inline the SVG file in your HTML. It should work then.
How to zoom out a div using animations?
I have a DIV that is covering the whole page (height and width are 100%). I am trying to use CSS (and possibly JavaScript) to create a zoom out animation effect so the DIV is smaller (making everything inside the div - its children - smaller as well) to a specific point on the page (middle of the page) and to a specific width and height (let's say 100 * 100px for example). I am starting with the following code: <div id="toBeZoomedOut"> <div>something</div> <div><img src="background.jpg"></div> </div> #toBeZoomedOut { background-color: black; border: 1px solid #AAAAAA; color: white; width: 300px; height: 300px; margin-left: auto; margin-right: auto; -webkit-transition: 1s ease-in-out; -moz-transition: 1s ease-in-out; transition: 1s ease-in-out; } #toBeZoomedOut img { height: 250px; width: 250px; } #toBeZoomedOut:hover { zoom: 0.5; } The issue with this code is that it zooms out on component down (the parent div) and immediately zooms out what's inside it then goes back to zoom in the components. Basically it is a little buggy. Any helpful fixes to make it zoom out everything together? It would be great if I can zoom out everything together to a specific location on the page and to a specific width/height (for example, zoom everything out to left: 100px, top: 100px and the parent div should be: 100px * 100px and everything else is relative in size). I understand this might be easier with JavaScript? Any help? One final note, if you notice the animation is not really reflecting a zoom animation. Although this would be an additional plus, the actual zoom animation would be great. JSFiddle link to make it easier: http://jsfiddle.net/HU46s/
I am using the universal selector to target everything inside of the parent container to have the css transitions applied to it. The next thing I did was changed the inside contents width to a % for ease of scaling. Here is the css: #toBeZoomedOut * { -webkit-transition: all 1s ease; -moz-transition: 1s ease; transition: 1s ease; } Finally, a fiddle: Demo
To make all images and div backgrounds zoom at the same time you have to use percentage size for #zoomer-inside elements and set a specific font-sizes... However is not smooth, if you want a smoother result, I suggest you use a jQuery in combination with some animation() method or plugin. Fiddle: http://jsfiddle.net/HU46s/1/ Code: #toBeZoomedOut { background-color: black; border: 1px solid #AAAAAA; color: white; width: 300px; height: 300px; margin-left: auto; margin-right: auto; -webkit-transition: all 1s ease-in-out; -moz-transition: all 1s ease-in-out; transition: all 1s ease-in-out; } #toBeZoomedOut div, #toBeZoomedOut img { width: 90%; font-size: 20px; } #toBeZoomedOut img { height: 90%; width: 90%; } #toBeZoomedOut:hover { zoom: 0.5; } smoother by jQuery: Fiddle: http://jsfiddle.net/HU46s/5/ Code: jQuery - smoother solution (even less CSS): $('#toBeZoomedOut').hover( /* change the animation speed as you want :) */ function(){ $(this).animate({ 'zoom': 0.5}, 400); //animation speed 400=0.4s ! }, function(){ $(this).animate({ 'zoom': 1}, 400); //animation speed 400=0.4s ! } ); ...with this only CSS you need is: #toBeZoomedOut { background-color: black; border: 1px solid #AAAAAA; color: white; width: 300px; height: 300px; margin-left: auto; margin-right: auto; } #toBeZoomedOut img { width: 250px; }
Advice about how to animate the background of a list item
I was wondering if you can offer me a better way of achieving the effect Ive created in this fiddle: http://jsfiddle.net/YLuKh/1/ Basically I would like to animate the background colour of the anchor tag revealing an image which I've done by positioning an anchor tag on top of a span on top of an image and then on hover animate the width of the span. Can anyone suggest a more straight forward way of doing this? HTML <ul id="test"> <li> This is the link <span class="bg"></span> <img src="http://www.ritaxxii.org/wp-content/uploads/Luxury-Bedroom-Furniture-1.jpg" /> </li> </ul> JS $(document).ready(function() { var li_width = $('#test').find('li').width(); console.log(li_width); $('#test').find('li').on('mouseover', function() { $(this).find('.bg').stop().animate({ width: '0' }, 200); }).on('mouseout', function() { $(this).find('.bg').stop().animate({ width: li_width }, 200); }); });
As I mentioned in the comments you can use the background position to do the animation. Here's a simple one using only background image positioning ( http://jsfiddle.net/3PESX/ ) $('a').mouseenter(function() { $(this).stop().animate({ 'background-position-x': '-700px'}, 300); }); $('a').mouseleave(function() { $(this).stop().animate({ 'background-position-x': '0'}, 300); }); a { display: inline-block; height: 50px; width: 300px; background: transparent url(http://jtrujillo.net/digital-photo-tutorials/8vs16bit/dgr1.jpg) 0 top no-repeat; color: grey; text-decoration: none; line-height: 50px; } This is a link text Beware that the background-position property is a composition of the x and y version. You cannot animate composite properties, you'll need to animate the X and Y version seperately. Alternatively you can use a css hook plugin that makes it possible. You can find those here: https://github.com/brandonaaron/jquery-cssHooks
You can get a referance from this : http://snook.ca/archives/javascript/jquery-bg-image-animations
May I suggest a CSS3-only means of achieving what I think you're trying to do: li { border: 1px solid #f90; width: 504px; /* width of the image, adjust to taste */ overflow: hidden; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; box-sizing: border-box; } li a { display: block; position: relative; width: 100%; height: 2em; line-height: 2em; color: #fff; background-color: #000; -webkit-transition: width 1s linear; -moz-transition: width 1s linear; -o-transition: width 1s linear; -ms-transition: width 1s linear; transition: width 1s linear; } li:hover a { width: 0; -webkit-transition: width 1s linear; } li a::after { content: url(http://www.ritaxxii.org/wp-content/uploads/Luxury-Bedroom-Furniture-1.jpg); position: absolute; top: 0; right: 0; left: 100%; bottom: 0; } JS Fiddle demo.
If you're going to have a lot of list items, you might want to consider event delegation to the #test element so you dont have to attach a bunch of different event listeners to each li tag //attach one event listener for 'mouseover' and one for 'mouseout' on the test element $('#test').on('mouseover', 'li', function(){ //'this' is still the li element console.log( $(this)); $(this).find('.bg').stop().animate({width: '0'},200); }).on('mouseout', 'li', function(){ $(this).find('.bg').stop().animate({width: li_width},200); });