Задача такая: необходимо сделать вывод на каждой странице гистограммы с оценками. Всего 5 баллов, за каждый балл есть определенное количество голосов. Нужно вывести гистограмму в процентном соотношении голосов за каждую оценку.
Пример реализации ниже:
Вариант 1 — Простой JS
Используем такой html:
<div class="rating-histogram"> <div class="rating-bar-container five"> <span class="bar-label"> 5 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container four"> <span class="bar-label"> 4 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container three"> <span class="bar-label"> 3 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container two"> <span class="bar-label"> 2 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container one"> <span class="bar-label"> 1 </span> <span class="bar"></span> <span class="bar-number"></span> </div> </div><!-- /rating-histogram --> <div class="hidden"><!-- needs for jquery calculations --> <form> <input type="text" class="reviews_1star" value="5"> <input type="text" class="reviews_2star" value="4"> <input type="text" class="reviews_3star" value="2"> <input type="text" class="reviews_4star" value="6"> <input type="text" class="reviews_5star" value="3"> </form> </div><!-- /hidden -->
В блоке div.hidden
мы выводим количество голосов за каждую оценку, например,
1 балл — 5 голосов,
2 балла — 4 голоса,
3 балла — 2 голоса,
4 балла — 6 голосов,
5 баллов — 3 голоса.
Для WordPress мы можем эти оценки выводить через кастомные поля <?php the_field('reviews_1star'); ?>
и т.д., а в HTML это могут быть статические данные, но они обязательно должны быть, потому что используются для подсчета и построения гистограммы.
Используем такой JS:
<script> $(function() { var reviews_1star = parseInt($('.reviews_1star').val()); var reviews_2star = parseInt($('.reviews_2star').val()); var reviews_3star = parseInt($('.reviews_3star').val()); var reviews_4star = parseInt($('.reviews_4star').val()); var reviews_5star = parseInt($('.reviews_5star').val()); var sum = reviews_1star + reviews_2star + reviews_3star + reviews_4star + reviews_5star; var width_1star = (reviews_1star / sum * 100).toFixed(0); var width_2star = (reviews_2star / sum * 100).toFixed(0); var width_3star = (reviews_3star / sum * 100).toFixed(0); var width_4star = (reviews_4star / sum * 100).toFixed(0); var width_5star = (reviews_5star / sum * 100).toFixed(0); $('.rating-bar-container.one .bar').css('width', width_1star+'%' ); $('.rating-bar-container.two .bar').css('width', width_2star+'%' ) $('.rating-bar-container.three .bar').css('width', width_3star+'%' ); $('.rating-bar-container.four .bar').css('width', width_4star+'%' ); $('.rating-bar-container.five .bar').css('width', width_5star+'%' ); if (sum > 0) { $(".rating-bar-container.one .bar-number").html(width_1star+'%'); $(".rating-bar-container.two .bar-number").html(width_2star+'%'); $(".rating-bar-container.three .bar-number").html(width_3star+'%'); $(".rating-bar-container.four .bar-number").html(width_4star+'%'); $(".rating-bar-container.five .bar-number").html(width_5star+'%'); } else{ $(".rating-bar-container .bar-number").html('0%') } }); </script>
В head
подключаем jquery, если он не подключен:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
Используем Такой CSS:
<style> .rating-histogram { padding: 5px 5px 5px 44px; text-align: left; width: 100%; } .rating-histogram .rating-bar-container { position: relative; margin-bottom: 5px; } .rating-histogram .bar-label { margin-right: 10px; position: absolute; left: -44px; top: 2px; } .rating-histogram .bar-label:before { content: "\f005"; font-family: FontAwesome; font-size: 16px; line-height: 16px; height: 16px; width: 16px; color: #ccc; display: inline-block; margin-right: 5px; } .rating-histogram .bar { background-color: #8e70af; background-image: -webkit-linear-gradient(left, #8e70af, #48bfed); background-image: linear-gradient(to right,#8e70af, #48bfed); -webkit-transition: width 2s ease; -moz-transition: width 2s ease; transition: width 2s ease; opacity: .8; display: inline-block; vertical-align: middle; width: 1%; height: 15px; margin-right: 3px; } .rating-histogram .bar-number { font-size: 14px; line-height: 1; vertical-align: middle; } .hidden{ display: none; } </style>
В CSS используется шрифт иконок FontAwesome, он у вас должен быть подключен.
Вариант 2 — Более профессиональный, оптимизирован JS
Меняем HTML на такой формат:
<div class="rating-histogram"> <div class="rating-bar-container five" data-id="5"> <span class="bar-label"> 5 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container four" data-id="4"> <span class="bar-label"> 4 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container three" data-id="3"> <span class="bar-label"> 3 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container two" data-id="2"> <span class="bar-label"> 2 </span> <span class="bar"></span> <span class="bar-number"></span> </div> <div class="rating-bar-container one" data-id="1"> <span class="bar-label"> 1 </span> <span class="bar"></span> <span class="bar-number"></span> </div> </div><!-- /rating-histogram --> <div class="hidden"><!-- needs for jquery calculations --> <form> <input type="text" class="reviews_1star" value="5"> <input type="text" class="reviews_2star" value="4"> <input type="text" class="reviews_3star" value="2"> <input type="text" class="reviews_4star" value="6"> <input type="text" class="reviews_5star" value="3"> </form> </div><!-- /hidden -->
Добавился только параметр data-id
для div.rating-bar-container
А JS меняем на такой оптимизированный код:
<script> $(function() { var stars = new Array(); var sum = 0; var width = new Array(); for ( var i = 1; i < 6; i++ ) { stars.push(parseInt($('.reviews_'+i+'star').val())); } for ( var i = 0; i < stars.length; i++ ) { sum += stars[i]; } for ( var i = 0; i < stars.length; i++ ) { w = ((stars[i]) / sum * 100).toFixed(0); width.push(w); $('.rating-bar-container[data-id='+(i+1)+'] .bar').css('width', w+'%' ); } if (sum > 0) { for ( var i = 0; i < stars.length; i++ ) { $('.rating-bar-container[data-id='+(i+1)+'] .bar-number').html(width[i]+'%'); } } else{ $(".rating-bar-container .bar-number").html('0%') } }); </script>
CSS остается прежним.
Код на CodePen
See the Pen Animated Rating Histogram by Denis (@deniscreative) on CodePen.
За помощь спасибо Algiz.