?
Solved

Moving Image Graph

Posted on 2013-10-31
15
Medium Priority
?
845 Views
Last Modified: 2013-11-04
I'm trying to take the below image and make it so that depending on the data fed to it by the database it can rotate around to the correct %.

I have no idea how to do this, with CSS or many images?  Would prefer if the moving if the bar were animated, but again no idea where to start.
rotating-image.jpg
0
Comment
Question by:Nathan Riley
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
15 Comments
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 2000 total points
ID: 39616167
I've been playing around with this for a bit. I was sure a CSS3 expert would come up with some nice and easy pure CSS solution but since that hasn't happened (yet) I want to share my javascript solution with you. It uses 360 rotated divs, I used small parts of the image you posted, and I put some extra work in it to make it kind of like a plugin. You can test it straight away on my website: http://schutt.nl/ee/Q_28282364/ or download the attached files and test them locally or on your own website. I'm sure there are tons of improvements that could be made but I wanted to share this with you if only to let you know your question has not gone unnoticed...
index.html
rotimg0.png
rotimg1.png
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39616904
Robert,

There is no neat CSS solution because it is a processing indicator and the processing would require scripting no matter what.  

If it was just a hover effect it would be a simple transform(rotate... effect with a transition to handle the timing, but CSS is event driven and does not have the capacity to do any of looping or conditional processing other than the ability to change some properties in response to changes in the state of elements.

That is a nice piece of code you have written.


Cd&
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39616932
Robert, that works great!

I'm looking through the code trying to understand exactly how it works. So if I want to have 2 graphs on the page and use 2 different colors in each I would need to replicate your above code in index.html then change the css (this is how I've currently done it) or is there an easier way without having to duplicate all the code?
0
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39616984
Cd&
Thanks, coming from you that's meaningful, the conclusion about CSS and the praise!

Gallitin
the colors are determined by the 2 images I took from your example image. If you can describe what color you want to change exactly (like blue to pink for a female version maybe? or get rid of the images and use any color?), then I could try to extend the parameters for that. I also started on a canvas version but that was nowhere near as nice as just using your already nicely shaded image.
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39617067
Just to show a possible extended functionality with a minor change here:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Rotating divs</title>
    <style type="text/css">
      .rotdiv { position: absolute; left: 200px; top:  50px; width: 160px; height: 160px; background-color: white; border: 1px solid silver; }
      .rotsub { position: absolute; left:  20px; top:  30px; width: 120px; height: 120px; background-position: right center; background-repeat: no-repeat; }
      .rotim0 { background-image: url('rotimg0.png'); }
      .rotim1 { background-image: url('rotimg1.png'); }
      .rotim2 { background-image: url('rotimg2.png'); }
      .rotprc { position: absolute; left:  60px; top: 100px; width:  40px; height:  20px; text-align: center; font-size: 15pt; color: gray; }
      .inprng { position: absolute; left:  20px; top:   0px; width: 120px; }
    </style>
    <script type="text/javascript">

      var ri1, ri2, ri3;

      var rotatingImage = function(prm) {

        var that = this, a, d;

        // init main <div>
        that.rotdiv = document.createElement('DIV');
        that.rotdiv.className = 'rotdiv';
        that.rotdiv.style.top = prm.y + 'px';
        that.rotdiv.style.left = prm.x + 'px';
        document.body.appendChild(that.rotdiv);

        that.currentValue = 0;
        that.showLabel = prm.showLabel;
        that.showSlider = prm.showSlider;
        that.setImageNumber = prm.setImageNumber || 1;

        that.tmr = null;
        that.prcspan = null;

        // init child <div>s
        for (a=0; a<360; a++) {
          d = document.createElement('DIV');
          d.className = 'rotsub rotim0';
          d.style.transform = d.style.MozTransform = d.style.webkitTransform = 'rotate(' + a + 'deg)';
          that.rotdiv.appendChild(d);
        }

        // init slider if necessary
        if (that.showSlider) {
          that.inprng = document.createElement('INPUT');
          that.inprng.className = 'inprng';
          that.inprng.type = 'range';
          that.inprng.min = 0;
          that.inprng.max = 100;
          that.inprng.value = 0;
          that.inprng.onchange = function() {
            that.draw(this.value);
          };
          that.rotdiv.appendChild(that.inprng);
        }

        // init percentage span if necessary
        if (that.showLabel) {
          that.prcspan = document.createElement('SPAN');
          that.prcspan.className = 'rotprc';
          that.rotdiv.appendChild(that.prcspan);
        }

        // animate towards the target value
        that.incValue = function() {
          that.currentValue++;
          if (that.currentValue >= that.targetValue ) {
            clearInterval(that.tmr);
            that.tmr = null;
          }
          that.draw();
        };

        that.draw = function(prc) {
          var a;
          if (prc) {
            that.targetValue = prc;
            that.currentValue = prc;
          }
          for (a=0; a<360; a++) {
            that.rotdiv.childNodes[a].className = 'rotsub rotim' + (a / 3.6 >= that.currentValue ? 0 : that.setImageNumber);
          }
          if (that.showLabel) {
            that.prcspan.textContent = that.currentValue + '%';
          }
          if (that.showSlider) {
            that.inprng.value = that.currentValue;
          }
        };

        that.anim = function(prc, ms) {
          that.targetValue = prc;
          that.tmr = setInterval(that.incValue, ms);
        };

        // show value direct or animated
        if (prm.animDelay) {
          that.anim(prm.value, prm.animDelay);
        } else {
          that.draw(prm.value);
        }
      }

      document.addEventListener("DOMContentLoaded", init, false);
      function init() {
        ri1 = new rotatingImage( { x: 100, y: 100, value: 25, showLabel: false, showSlider: true, animDelay: 50 } );
        ri2 = new rotatingImage( { x: 300, y: 100, value: 50, showLabel: true, showSlider: false, animDelay: 50 } );
        ri3 = new rotatingImage( { x: 500, y: 100, value: 75, showLabel: true, showSlider: true, setImageNumber: 2 } );
      }

    </script>
  </head>
  <body>
  </body>
</html>

Open in new window

Where I added "setImageNumber: 2" at the end of the code, make sure the class exists (.rotim2) and the new image as well ('rotimg2.png'), then you can vary the colors as needed. If you need more freedom, let me know, I may have some more options.
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39617083
Ah makes sense, that works perfectly.  Thanks for taking the time!
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39617637
Had another question on your code robert, created a new question for it:
http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Jquery/Q_28283333.html

Thanks!
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39617714
That new question is incomplete but I have reproduced your problem and will answer you here. I think it would be better to delete that new question?
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39617718
Ok will do, thanks.
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39617725
The problem is caused by the anim function calling the increment function once even when value = 0. This can be solved in a number of ways, easiest probably (around line 100 in my last posted code):
        // show value direct or animated
        if (prm.animDelay && prm.value > 0) {

Open in new window

0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39617759
Got it thanks again!
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39621805
It seems the graph always is inserted into the page after the last <div> even if I have it within a div on the page.  Is there a way to modify so it will populate within the <div> I put it?
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39621823
I'm not sure but I think this line may have something to do with it?

document.body.appendChild(that.rotdiv);

I've tried different syntax, but haven't got it done.  I want it to reside within the "leftportion" div, but can't quite get it there.
0
 
LVL 12

Author Comment

by:Nathan Riley
ID: 39621941
Well took a bit but fixed by replacing that line with:
 document.getElementById("leftportion").appendChild(that.rotdiv1);

Open in new window

0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39622051
ah, well good you found a solution. If you wanted to generalise that, you could add a parameter something like
ri1 = new rotatingImage( { x: 100, y: 100, /* ..., */ parentId: "leftportion" } );

Open in new window

then use something along the lines of (untested):
that.parentElement = prm.parentId ? document.getElementById(prm.parentId) : document.body;
that.parentElement.appendChild(that.rotdiv);

Open in new window

instead of
document.body.appendChild(that.rotdiv);

Open in new window

0

Featured Post

WordPress Tutorial 2: Terminology

An important part of learning any new piece of software is understanding the terminology it uses. Thankfully WordPress uses fairly simple names for everything that make it easy to start using the software.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Color can increase conversions, create feelings of warmth or even incite people to get behind a cause. If you want your website to really impact site visitors, then it is vital to consider the impact color has on them.
Although a lot of people devote their energy toward marketing for specific industries, there are some basic principles that can be applied to any sector imaginable. We’ll look at four steps to take and examine how those steps were put into action fo…
In this tutorial viewers will learn how to style rounded corners for elements in CSS using the border-radius property Begin with a normal styled element such as a div: To style all four corners of the div to be the same degree of roundness, use the …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question