带CSS的简单水平分段条形图
条形图是显示不同数据项之间关系的强大方法。如果要显示的数据是离散的,那么一个简单的水平分段条形图是个好主意。您可以轻松地将数字集合更改为一组相关的属性。
要显示此条形图,您不需要大型的JavaScript库或后端图表系统,只需要几行标记和某些样式即可。这是生成条形图所需的所有标记。它由包装元素和构成条形图数据的四个内部元素组成。请注意,每个元素的宽度已预先计算为25%。我将在后面的文章中讨论涉及到的数学问题。
该条形图中涉及的样式并不多,实际上,大多数样式都与设置图表元素的颜色有关。我们需要做的是设置包装纸的宽度,然后将元素向左浮动。每个元素的宽度总计不到100%,意味着该图表非常适合单行。.start和.end类使图表的两端圆整。
.chart { height: 2rem; width: 30rem; } .chart div { height: 100%; float: left; } .chart .start { border-radius: 2rem 0 0 2rem; } .chart .end { border-radius: 0 2rem 2rem 0; } .chart .red { background-color: red; } .chart .blue { background-color: blue; } .chart .green { background-color: green; } .chart .cyan { background-color: cyan; }
将它们放在一起将产生以下条形图。
计算宽度
我们如何计算元素的宽度?这需要一些数学运算才能将元素映射到外部包装的范围(即100%)。为此,我们将所有元素加在一起,并找出0到100范围内每个项目的映射。在上面的示例中,我们将四个相等的值映射到条形图,因此如果我们假设数据是四个值分别为100,则数学计算如下。
100 + 100 + 100 + 100 = 400 0 + (400 - 0) * ((100 - 0) / (0 - 100)) The mapped value is: 25
之前,我已经写过有关在PHP中创建映射函数的文章,并且还在此站点上创建了一个工具,该工具可让您使用映射函数本身。这是以前用PHP编写的map函数的JavaScript版本。
function map(value, valueRangeStart, valueRangeEnd, newRangeStart, newRangeEnd) { return newRangeStart + (newRangeEnd - newRangeStart) * ((value - valueRangeStart) / (valueRangeEnd - valueRangeStart)); }
通过此功能,我们可以开始着眼于动态调整图表的大小。
动态调整图表大小
虽然在页面中添加宽度会创建一个完美可用的图表,但这确实意味着我们需要在渲染页面之前计算出尺寸。我们可以通过在每个图表项目中添加一个额外的类来解决此问题。如果我们向每个图表项添加递增的类值,则可以使用简单的循环对图表中的每个项进行寻址。这是新的标记。
使用width函数,我们可以开始使图表的宽度更容易计算。如果我们将元素的宽度分别保持为25%,那么我们可以在页面中使用一些JavaScript代码,以在加载页面时自动将元素的大小调整为所需的宽度。以下JavaScript代码采用四个值300、80、270、90,并计算出它们的相对宽度。然后,使用其新的递增类名称将这些宽度直接应用于图表项目。
function map(value, valueRangeStart, valueRangeEnd, newRangeStart, newRangeEnd) { return newRangeStart + (newRangeEnd - newRangeStart) * ((value - valueRangeStart) / (valueRangeEnd - valueRangeStart)); } var chart = document.getElementsByClassName('chart')[0]; var items = [300, 80, 270, 90]; var total = 0; for (var i = 0; i < items.length; i++) { total += items[i]; } for (var i = 0; i < items.length; i++) { let value = Math.floor(map(items[i], 0, total, 0, 100)); let item = chart.getElementsByClassName('item' + (i + 1))[0]; item.style.width = value + '%'; }
尽管这可行,但确实会在将新宽度应用于元素后导致图表闪烁。为了使过渡更加方便用户,我们可以向CSS添加一些新样式,以使过渡具有动画效果。
.chart div { height: 100%; float: left; transition-property: width; transition-duration: 0.5s; }
如果您想看到此代码的实际效果,那么我已经创建了一个Codepen项目,其中包含您需要的所有内容。
使其完全动态
更进一步,可以通过添加更多行JavaScript来创建完全动态的图表。这意味着我们可以添加所需数量的项目,而不是限制为四个项目。我们需要做的第一件事是删除内部标记,以便我们可以添加所需的图表项目。
当我们将使用所有需要的样式生成图表的内部组件时,我们可以删除图表的许多现有样式。图表CSS现在只是一些规则。
.chart { height: 2rem; width: 30rem; } .chart div { height: 100%; float: left; transition-property: width; transition-duration: 0.5s; } .chart .start { border-radius: 2rem 0 0 2rem; } .chart .end { border-radius: 0 2rem 2rem 0; }
新的JavaScript代码只需要遍历我们提供的数据并在制定映射时创建每个项目。然后将该项目以及所需的样式添加到图表中,以设置颜色和正确的宽度。几个if语句还用于为图表中的开始和结束项目添加额外的类。
function map(value, valueRangeStart, valueRangeEnd, newRangeStart, newRangeEnd) { return newRangeStart + (newRangeEnd - newRangeStart) * ((value - valueRangeStart) / (valueRangeEnd - valueRangeStart)); } var chart = document.getElementsByClassName('chart')[0]; var items = [300, 80, 270, 90, 100, 20, 160, 100]; var colours = ['red', 'green', 'blue', 'yellow', 'cyan', 'orange', 'darkgreen', 'grey']; var total = 0; for (var i = 0; i < items.length; i++) { total += items[i]; } for (var i = 0; i < items.length; i++) { let value = Math.floor(map(items[i], 0, total, 0, 100)); const item = document.createElement('div'); item.style.width = value + '%'; item.style.backgroundColor = colours[i]; if (i == 0) { item.classList.add('start'); } if (i ==items.length- 1) { item.classList.add('end'); } chart.append(item); }
此代码生成以下条形图。唯一的限制是颜色数组中颜色的数量,因为它当前决定了可以显示的数据项的长度。您可以增加颜色的数量,也可以在到达颜色列表的末尾时仅循环到颜色列表的开始。
如果您想查看运行中的JavaScript生成的条形图,那么我也为此创建了一个Codepen项目。随意在您自己的项目中使用它。
上述示例缺少的是条形图的实际数字和某种表示颜色的标签。这是图表的重要组成部分,因为它将显示哪些数字属于什么颜色。我将作为练习留给读者,因为它所需要的只是一张表或一个应用了一些背景颜色的有序列表。