Проектирование гибкий, поддерживаемого круговые диаграммы с помощью CSS и SVG

Когда дело доходит до методов CSS, никто не является более упрямым и достаточно умны, чтобы найти решения любых проблем, чем Lea Verou.
Недавно Ли написал, разработан и опубликован CSS Secrets 1 , действительно фантастическая книга на маленькие хитрости CSS и techniques для решения повседневных проблем.Если вы думали, что вы знаете, CSS достаточно хорошо, подумайте еще раз: вы будете удивлены.В этой статье мы публикуем несколько самородков из книги, которые также были представлены в Lea’ Недавнее разговор в SmashingConf Новый York __12 | 2 — по проектированию простых круговых диаграмм, с помощью CSS.Пожалуйста, обратите внимание, что некоторые демки не может работать, как ожидалось из-за ограниченной поддержки в браузерах.Ред .

Пирог charts, даже в простейшем двухцветной форме, традиционно было ничего, кроме просто создать с веб-технологий, несмотря на то, невероятно общей для информации, начиная от простых статистике на показатели прогресса и таймеры.Реализации обычно участвуют либо с помощью внешнего графического редактора для создания нескольких изображений для нескольких values круговой диаграммы или крупных структур JavaScript, предназначенных для гораздо более сложные диаграммы .

Хотя подвиг не как невозможно, как это было раньше, нет до сих пор нет простой вкладыш к нему.Тем не менее, есть много лучше, больше поддерживаемого пути ее достижения today .

Transform основе Solution

Это решение является лучшим в плане разметки: это нужно только один элемент и все остальное будет сделано с псевдо-элементов, преобразований и CSS градиентов.Давайте начнем с простого элемента:

<div class="pie"></div>

Сейчас давайте предположим, что мы хотим круговую диаграмму, отображающую процентное жестко 20% .Мы будем работать над тем, чтобы гибкая позже.Давайте первый стиль элемент в виде круга, который будет нашим фоном (рисунок 1):

Рисунок 1: Наша отправная точка (или, круговая диаграмма показывает 0%)
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: yellowgreen;
}

Наша круговая диаграмма будет зеленой (в частности, yellowgreen) с коричневым (#655), показывающий процент.Мы могли бы попытаться использовать косые преобразования для процентного части, но, как показывает эксперимент немного, они окажутся очень грязный раствор.Вместо этого, мы будем цвет левые и правые части нашего круга в нашей | двух colors__9, и использовать вращающийся псевдо-элемент, чтобы раскрыть только процент мы need .

Для цвета правую часть нашего круга коричневый, мы будем использовать простой линейный градиент:

background-image:
  linear-gradient(to right, transparent 50%, #655 0);
Рисунок 2: раскраска правую часть нашего круга коричневый, с простой линейной gradient

КакВы можете видеть на рисунке 2, это все, что нужно.Теперь мы можем приступить к укладке псевдо-элемент, который будет выступать в качестве маски:

.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
}
Рисунок 3: Псевдо-элемент, который будет выступать в качестве маски показано здесь пунктирной lines

Вы можете увидеть на рисунке 3, где наша псевдо-элемент в настоящее время находится по отношению к круговой элемент.В настоящее время, это не стиль, а он ничего не покрыть.Это всего лишь невидимый прямоугольник.Для начала укладки, давайте сделаем несколько замечаний:

  • Потому что мы хотим, чтобы он покрытия коричневый часть нашего circle, мы должны применить зеленый фон с ней, используя background-color: inherit, чтобы избежать дублирования, а мы хотим, чтобы иметь тот же цвет фона, как его родитель.
  • Мы хотим, чтобы вращаются вокруг center, который находится на середине левой стороны псевдо-элемента, таким образом, мы должны применить transform-origin из 0 50% к нему, или просто left .
  • Мы не хотим, чтобы это было прямоугольник, как это делает его истекать кровью за края круговой диаграммы, так что мы должны либо применить overflow: hidden к .pie, или соответствующее border-radius, чтобы сделать егополукруг .

Собираем все вместе, CSS Наш псевдо-элемент будет выглядеть следующим образом:

.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
}
Рисунок 4: Наша псевдо-элемент (здесь с пунктирной линией), после мы закончили укладки it

Примечание: Будьте осторожны, чтобы не использовать background: inherit;, а background-color: inherit;, в противном случае градиент будет наследоваться слишком

Наша круговая диаграмма в настоящее время выглядит как на рисунке 4. Это где начинается веселье!Мы можем начать вращая псевдо-element, применяя rotate() преобразования.Для 20% мы пытались достичь, мы можем использовать значение 72deg (0,2 × 360 = 72), или .2turn, который является гораздо более удобным для чтения.Вы можете увидеть, как это выглядит на несколько других ценностей, а также, на рисунке 5 .

Рисунок 5: Наш простой пирог диаграмма, показывающая различные проценты;сверху вниз: 10% (~ 46 или ~ | 47 |), 20% (72deg 45 ~ или |), 40% (~ 50 ~ | или 51 |)

Мы могли бы быть склонны думать, что мы сделали, но, к сожалению, это не так просто.Наша круговая диаграмма работает отлично подходит для отображения процент от 0 до 50%, но если мы попытаемся изобразить вращение на 60% (с применением .6turn), Рисунок 6 происходит.Не теряем надежды, все же, хотя, как мы можем — и мы будем — это исправить

Рисунок 6: Наши пирог диаграмма перерывы для процентах больше чем на 50% (показано здесь: 60% )

Если мы думаем о 50% -100% процент в качестве отдельной проблемы, мы могли бы заметить, что мы можем использовать перевернутую версию предыдущей solution для них: коричневый псевдо-элемент, вращающийся с 0 к .5turn, соответственно.Таким образом, для 60% пирога, код псевдо-элемент будет выглядеть следующим образом:

.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background: #655;
  transform-origin: left;
  transform: rotate(.1turn);
}
Рисунок 7: Наша Теперь правильно 60% pie

Вы можете увидеть это в действии на рисунке 7. Потому что мы в настоящее время разработан способ изобразить любой процент, мы могли бы даже анимировать круговую диаграмму от 0% до 100% с CSS animations, создавая причудливую прогрессаИндикатор:

@keyframes spin {
  to { transform: rotate(.5turn); }
}

@keyframes bg {
  50% { background: #655; }
}

.pie::before {
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 3s linear infinite,
             bg 6s step-end infinite;
}

Анимированные Pie 3

Все это хорошо, но как мы стиль несколько статических круговых диаграмм с различными процентах, которая наиболее распространенным прецедент?В идеале, мы хотим, чтобы иметь возможность что-то вроде этого типа:

<div class="pie">20%</div>
<div class="pie">60%</div>

| __57 И получить два круговых диаграмм, один показывая 20%, а другой показывает 60%.Во-первых, мы рассмотрим, как мы можем сделать это с внутренних стилей, а затем мы всегда могли бы написать короткий скрипт для разбора текстового содержимого и добавить сказал встроенные стили, для кода элегантности, инкапсуляции, ремонтопригодности и, возможно, самое главное, доступность .

Вызов управления круговую диаграмму процент с внутренних стилей является то, что код CSS, который отвечает за установление процент устанавливается на псевдо-элемента.Как вы уже знаете, мы не можем установить встроенные стили на псевдо-elements, так мы должны быть inventive .

Примечание: Вы можете использовать ту же технику для других случаев, где вы хотите, чтобы использовать значения из spectrum без повторения и сложных расчетов, а также для отладки animations ступая через них. Просмотр простой, изолированный пример technique __33 | | 4__10 .

Решение приходит от одного из самых неожиданных местах.Мы собираемся использовать анимацию мы уже подарил, но это будет paused.Вместо того, чтобы его как обычный анимации, мы будем использовать отрицательные задержки анимации в шаг до любой точки в animation статически и остаться там.Смущенный?Да, отрицательный animation-delay не только разрешено спецификации, но очень полезно для случаев, как это:

Отрицательные задержки valid.Подобно задержкой ‘0s‘, это означает, что анимация выполняет сразу, а автоматически прогрессировала по абсолютной величине задержки, как если бы анимация начала в определенный момент времени в прошлом, и поэтому появляется начатьчастично посредством активного продолжительности .

CSS Анимации Уровень 1 5

Потому что наша анимация приостановлена, первый кадр из него (определяется наше негативное animation-delay), будет отображаться только один.Процент показано на круговой диаграмме будет процент общей продолжительности нашего animation-delay есть.Например, с текущей длительностииз 6s, мы должны были бы animation-delay 64 из ~ |, чтобы отобразить процент 20%.Для упрощения математику, мы будем устанавливать продолжительность 100s.Имейте в виду, что из-за анимации остановился навсегда, продолжительность мы указываем не имеет другого эффекта .

Существует один последний вопрос: анимация на псевдо-элемента, но мы хотим, чтобы установить встроенный стиль на .pie element.Тем не менее, потому что нет анимации на <div>, мы можем установить animation-delay на, что в качестве внутреннего стиля, а затем использовать animation-delay: inherit; на псевдо-элемента.Чтобы положить его вместе, наша разметка для 20% и 60% круговых диаграмм будет выглядеть следующим образом:

<div class="pie"
     style="animation-delay: -20s"></div>
<div class="pie"
     style="animation-delay: -60s"></div>

И УС код, который мы только что представил для этой анимации в настоящее время станет (не включая .pie правило, в том, что остается тот же):

@keyframes spin {
  to { transform: rotate(.5turn); }
}

@keyframes bg {
  50% { background: #655; }
}

.pie::before {
  /* [Rest of styling stays the same] */
  animation: spin 50s linear infinite,
             bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

На данный момент, мы можем преобразовать разметку использовать проценты как содержание, так как мы изначально предназначена для, и добавьте animation-delay встроенные стили с помощью простого скрипта:

$$('.pie').forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  pie.style.animationDelay = '-' + p + 's';
});

Обратите внимание, что мы оставили текст нетронутым, потому что мы должны его доступности и юзабилити причинам.В настоящее время, наши круговые диаграммы выглядеть как на рисунке 8. Мы должны скрыть текст, который мы можем сделать с помощью доступно color: transparent, так что он остается выбрать и printable.Как дополнительную ногтей, мы можем Центр процент пирога chart, так что это не в случайном месте, когда пользователь выбирает его.Чтобы сделать это, мы должны:

20%60%
Рисунок 8: Наш текст, прежде чем мы скрыть it

Comments are closed.