0

I have some code that isn't completely working... Currently it generates a bar graph from an array but I can't figure out how to pass unique height values. If I pass one value for height all the bars are the same height. If I pass an array for height values it doesn't work.

I have a git repo if it helps.

HTML

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <link rel="stylesheet" href="style.css">
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
        <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
        <script src="main.js"></script>
    </head>
    <body>
        <div class="graph-wrapper">

            <script id="barGraph-template" type="text/x-handlebars-template">

                <div class="bar-wrapper">
                    <div class="bar"></div>
                    <div class="title">{{charCount}}</div>    
                </div>

            </script>

        </div> <!-- end graph-wrapper -->

    </body>
</html>

JS

$(document).ready(function(){

    var charArray = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
    var charValues = [10, 35, 90, 72, 50, 22, 16, 20, 10, 5, 2, 3, 1];

    var templateSource = $('#barGraph-template').html();
    var template = Handlebars.compile(templateSource);

    for (var key in charArray){ 
        // Bars are all the same height  
        // $('.bar').css('height','70%');

        // This sets all the bars to the same height w/the last value
        // in the array
        $('.bar').css('height', (charValues[key] + '%');

        var graph =  {
            charCount: charArray[key],
        }

        var readyTemplate = template(graph);
        $('body').append(readyTemplate);
    }      

});

CSS

.graph-wrapper {
    border: 1px solid #ccc;
    display: flex;
    padding: 10px;
}

.bar-wrapper {
    /*border: 1px solid #000;*/
    display: inline-flex;   /*Positions bars side by side*/
    flex-direction: column; /*Stacks bar and label*/
    justify-content: flex-end;  /*Grows bar from bottom*/
    align-items: center;    /*Aligns bar label and bar on center horizontally*/
    height: 200px;
    margin: 0px;
}
.title, .bar {

}

.bar {
    /*border: 1px solid #000;*/
    /*height: 70%;*/
    width: 30px;
    background: #00AEEF;
    bottom: 0px;
    -webkit-animation: animate-bar 1.25s 1 linear;
}

.title {

}

@-webkit-keyframes animate-bar {
    0% { height: 0%; }
}
4
  • $('.bar').css('height', 'value'); // This doesn't work - typo I assume? as 'value' shouldn't be in quotes. It should probably be css('height', (value + 'px') or something Commented Oct 21, 2016 at 23:50
  • Yes, but even when I take the quotes off it still doesn't work. Does each bar class have to be unique? Commented Oct 22, 2016 at 0:15
  • I'm realizing that the bar class is actually taking the last value in the array (1) as it's value so the bars don't have their own unique value. Commented Oct 22, 2016 at 0:26
  • 1
    Where you have multiple elements of the same class which you wish to treat differently with jquery use eq() as such: $('.bar').eq(key).css('height', (charValues[key] + '%')); this line was also missing a closing parenthesis. otherwise @BarbaraLaird 's answer below looks good. Commented Oct 22, 2016 at 0:39

1 Answer 1

2

You've got a couple problems going on here. First, each bar is of class bar and this $('.bar').css('height', 'value'); changes every element of class bar to a height of whatever value is. Second, you've got extra quotes in this string: var value = "'" + charValues[key] + '%' + "'";. Change it to var value = charValues[key] + '%';. And third, you are attempting to access the elements before you add them to the dom. They aren't added until this statement:

$('body').append(readyTemplate);

The following code is similar to what you have, but working. https://jsfiddle.net/8f6Lcv8e/ But, there is a much cleaner solution.

        <script id="barGraph-template" type="text/x-handlebars-template">

            <div class="bar-wrapper">
                <div class="bar bar{{charCount}}"></div>
                <div class="title">{{charCount}}</div>    
            </div>

        </script>

$(document).ready(function(){

    var charArray = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
    var charValues = [10, 35, 90, 72, 50, 22, 16, 20, 10, 5, 2, 3, 1];

    var templateSource = $('#barGraph-template').html();
    var template = Handlebars.compile(templateSource);

    for (var key in charArray){
        var value = charValues[key] + '%';

        var graph =  {
            charCount: charArray[key],
        }

        var readyTemplate = template(graph);
        $('body').append(readyTemplate);

        $('.bar'+charArray[key]).css('height',value); 

    }      

});

Change your handlebar template to accept an array of objects

<script id="barGraph-template" type="text/x-handlebars-template">
  {{#each .}}
  <div class="bar-wrapper">
    <div class="bar" style="height:{{y}}%"></div>
    <div class="title">{{x}}</div>
  </div>
  {{/each}}

</script>

And your javascript becomes:

$(document).ready(function(){

        var graph = [{x:2,y:10},{x:3,y:35},{x:4,y:90},{x:5,y:72},{x:6,y:50},{x:7,y:22},{x:8,y:16},
    {x:9,y:20},{x:10,y:10},{x:11,y:5},{x:12,y:2},{x:13,y:3},{x:14,y:1}];

    var templateSource = $('#barGraph-template').html();
    var template = Handlebars.compile(templateSource);

    var readyTemplate = template(graph);
    $('body').append(readyTemplate);

});

https://jsfiddle.net/agm9e31o/

Sign up to request clarification or add additional context in comments.

4 Comments

A much more elegant and cleaner solution!
Can you tell me why my bar-wrapper div doesn't display inside of my graph-wrapper div? You can see this on your jsfiddle link - I have a border on the graph-wrapper.
You're setting flexbox container attributes on the flexbox items. See css-tricks.com/snippets/css/a-guide-to-flexbox for a nice write up on using flexbox
When I add a div above the bar for a 'y' label the bars animate down instead of up. I can't seem to identify what is changing the direction of animation: jsfiddle.net/agm9e31o/2

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.