Динамически генерировать гистограмму: JS, Jquery, CSS

#javascript #jquery #html #css

#javascript #jquery #HTML #css

Вопрос:

У меня есть некоторый код, который работает не полностью… В настоящее время он генерирует гистограмму из массива, но я не могу понять, как передавать уникальные значения высоты. Если я передам одно значение для высоты, все столбцы будут одинаковой высоты. Если я передаю массив для значений высоты, это не работает.

У меня есть репозиторий git, если это поможет.

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%; }
}
  

Комментарии:

1. $(‘.bar’).css(‘height’, ‘value’); // Это не работает — я полагаю, опечатка? поскольку ‘значение’ не должно быть в кавычках. Вероятно, это должен быть css (‘height’, (value ‘px’) или что-то в этом роде

2. Да, но даже когда я убираю кавычки, это все равно не работает. Должен ли каждый класс bar быть уникальным?

3. Я понимаю, что класс bar фактически принимает последнее значение в массиве (1) в качестве своего значения, поэтому столбцы не имеют своего собственного уникального значения.

4. Если у вас есть несколько элементов одного и того же класса, которые вы хотите обрабатывать по-разному с помощью jquery, используйте eq() как таковой: $('.bar').eq(key).css('height', (charValues[key] '%')); в этой строке также отсутствовала закрывающая скобка. в остальном приведенный ниже ответ @BarbaraLaird выглядит неплохо.

Ответ №1:

Здесь возникает пара проблем. Во-первых, каждый столбец относится к классу bar, и это $('.bar').css('height', 'value'); изменяет каждый элемент класса bar на высоту, которая value равна. Во-вторых, у вас есть дополнительные кавычки в этой строке: var value = "'" charValues[key] '%' "'"; . Измените его на var value = charValues[key] '%'; . И, в-третьих, вы пытаетесь получить доступ к элементам, прежде чем добавлять их в dom. Они не добавляются до этого утверждения:

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

Следующий код похож на тот, что есть у вас, но работает. https://jsfiddle.net/8f6Lcv8e Но есть гораздо более чистое решение.

         <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); 

    }      

});
  

Измените свой шаблон handlebar, чтобы он принимал массив объектов

 <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>
  

И ваш javascript становится:

 $(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/

Комментарии:

1. Гораздо более элегантное и чистое решение!

2. Можете ли вы сказать мне, почему мой div-обертка-панель не отображается внутри моего div-обертки-графика? Вы можете увидеть это по своей ссылке jsfiddle — у меня есть граница на графической оболочке.

3. Вы устанавливаете атрибуты контейнера flexbox для элементов flexbox. Смотрите css-tricks.com/snippets/css/a-guide-to-flexbox за хороший отзыв об использовании flexbox

4. Когда я добавляю div над панелью для метки «y», столбцы анимируются вниз, а не вверх. Кажется, я не могу определить, что меняет направление анимации: jsfiddle.net/agm9e31o/2