D3和Kendo UI只是在web应用程序中创建图表的两种方式,选项范围从简单地在屏幕上绘制图形到使用复杂的图表组件。D3和Kendo UI都很受欢迎,两者都能完成工作。然而,相似之处到此为止,这两种方法代表了非常不同的方法,具有非常不同的特性。
D3
D3代表数据驱动文档,是一个用于创建动态和交互式数据可视化的JavaScript库。它于2011年首次发布,包含一组非常灵活和强大的特性,可以帮助您构建各种图形数据可视化。
Kendo UI
Kendo UI是一组JavaScript库,它包含大量组件,从数据网格和图表到调度器、下拉菜单,甚至是按钮。Kendo UI是由Telerik公司开发,Kendo UI是一个商业库,有一些版本支持Angular、React和Vue框架以及基本的jQuery环境。Kendo UI图表组件包括许多流行的图表类型,包括条形图、饼图、线条图和其他图表。
准备开始
我在这里的目标是使用这两个工具来实现同一个图表,使用这两个库。
我想要实现的图表(在Excel中绘制,以保持中立)是:
此外,为了展示如何做一些基本的动画,我们还添加了一些工具提示,以便在鼠标滑过其中一个栏时,可以看到该栏显示的值。
这意味着我们需要做三件基本的事情:
- 绘制反映单个数据值的基本栏。
- 绘制X轴和Y轴并显示标签。
- 为图表创建工具提示。
我们先不详细描述这两个库,看一下大体的样式。
文件引用
我们需要做的第一件事是包含这两个库。为了简单性和可移植性,我将从网上加载所有内容,而不是假设您已经下载了库。我们将从添加两个CSS库开始,Kendo UI库将使用这两个CSS库。接下来,我们添加了Kendo UI也使用的jQuery库。然后我们链接到实际的Kendo UI库。最后,我们包含了一个到D3库的链接。
代码语言:javascript复制<!-- stylesheets for the Kendo UI library -->
代码语言:javascript复制<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.common-bootstrap.min.css">
代码语言:javascript复制<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.bootstrap.min.css">
代码语言:javascript复制<!-- jQuery library -->
代码语言:javascript复制<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
代码语言:javascript复制<!-- the Kendo UI library -->
代码语言:javascript复制<script src="https://kendo.cdn.telerik.com/2018.2.620/js/kendo.all.min.js"></script>
代码语言:javascript复制<!-- the d3 library -->
代码语言:javascript复制<script src="https://d3js.org/d3.v4.min.js"></script>
我们还会对两个图表使用相同的数据集,即:
代码语言:javascript复制var data = [454, 660, 721, 746, 808, 704, 775, 756, 688, 733, 693, 564, 537, 628, 630, 611, 600, 640,694, 708 ];
The Markup
在HTML中,除了为每个图表放置占位符并指定图表区域的大小之外,我们几乎不需要做什么。
代码语言:javascript复制<h2>D3 Chart</h2>
代码语言:javascript复制<svg id="chart1" width="600" height="300"></svg>
代码语言:javascript复制<hr />
代码语言:javascript复制<h2>Kendo UI Chart</h2>
代码语言:javascript复制<div id="chart2" style="width:600px;height:300px"></div>
创建一个基本的D3图表
现在是有趣的部分,我们先从D3表开始。我们需要做几件事。除了确定将图表放置在何处之外,我们还需要定义x和y刻度,对大小和位置进行一些整理,然后将数据添加到图表区域。
这是它的代码。
代码语言:javascript复制function drawDChart() {
代码语言:javascript复制 var svg = d3.select("#chart1");
代码语言:javascript复制 var margin = 5;
代码语言:javascript复制 var width = svg.attr("width") - 30;
代码语言:javascript复制 var height = svg.attr("height") - margin - 40;
代码语言:javascript复制 var y = d3.scaleLinear()
代码语言:javascript复制 .domain([0, 800])
代码语言:javascript复制 .range([height, 0]);
代码语言:javascript复制 var x = d3.scaleLinear()
代码语言:javascript复制 .domain([0, data.length])
代码语言:javascript复制 .range([0, width - 20]);
代码语言:javascript复制 var g = svg.append("g")
代码语言:javascript复制 .attr("transform", "translate( 0, " margin " )");
代码语言:javascript复制 g.append("g")
代码语言:javascript复制 .attr("transform", "translate( 55, 0 )")
代码语言:javascript复制 .selectAll("rect")
代码语言:javascript复制 .data(data)
代码语言:javascript复制 .enter().append("rect")
代码语言:javascript复制 .attr("width", (width / data.length - 15))
代码语言:javascript复制 .attr("height", function (d) { return height - y(d); })
代码语言:javascript复制 .attr("x", function (d, i) { return x(i) 5; })
代码语言:javascript复制 .attr("y", function (d) { return y(d); })
代码语言:javascript复制 .attr("fill", function (d, i) { return "steelblue" });
代码语言:javascript复制};
在第一行中,我们选择id为“chart1”的图表。接下来的几行将根据HTML代码中指定的尺寸确定图表的高度和宽度,减去一些空白,并为坐标轴留出空间。
接下来的两部分建立了这两个轴的刻度。这些将用于将实际数据值转换为图表上的坐标。我硬编码“800”作为Y刻度的上限。在实际使用中,我们希望找到要显示的数据的最大值,然后四舍五入。在这种情况下,最大值是775我四舍五入到800因为我们不希望我们的图表停留在775因为这看起来很奇怪。X轴是根据数据集中的值的数量进行缩放的。在下一节中,我们将在显示区域略微移动图表。
现在我们开始讲D3部分的内容。在这里,我们告诉D3我们将使用哪些数据,并指定图表中每个条形图的基本元素。我们告诉它每个条的宽度,我们告诉它条的高度(获取数据值并缩放它)。我们告诉它应该将每个bar放在哪里,使用前面指定的刻度指定X和Y值。最后,我让它用“钢蓝色”给每一根条涂上颜色,因为我喜欢蓝色。
注意在中间我们“输入”了新信息。这是D3的基本概念的一部分。使用图表可以做三件事:进入、更新和退出。输入获取新的数据并将其添加到现有的图表中—它向图表中添加新的条形图。更新更改现有条的值。退出从图表中删除元素(条)。我们不需要在这里详细讨论,但只要知道如果你要用D3做任何复杂的事情,你需要熟悉这个概念。
使用我们到目前为止指定的代码,我们得到:
注意,这里没有坐标轴,因为我们还没有指定,它只是一组条。
Kendo UI Chart
现在我们来用Kendo UI绘制同样的图表。这真的很复杂(我开玩笑)。基本上我们要做的就是告诉它什么类型的图表和数据是什么。代码是:
代码语言:javascript复制function drawKChart() {
代码语言:javascript复制 $("#chart2").kendoChart({
代码语言:javascript复制 seriesDefaults: {
代码语言:javascript复制 type: "column"
代码语言:javascript复制 },
代码语言:javascript复制 series: [{
代码语言:javascript复制 data: data,
代码语言:javascript复制 color: "steelblue"
代码语言:javascript复制 }]
代码语言:javascript复制 });
代码语言:javascript复制}
这里就不多说了。这给了我们图表:
您马上就会看到一些差异。注意,我们不需要告诉Kendo UI图表我们的最大Y轴应该是多少。它查看数据,四舍五入,并选择一个合理的使用范围。同样地,我们没有告诉它关于X轴的任何东西——它只是计算数据点的数量并相应地缩放。虽然它没有画出带有标签的X轴,因为我们没有给它,但它至少画出了坐标轴。它还使用了我指定的“steelblue”,并添加了一些阴影使它看起来更有趣。
最后,它添加了网格线。这是两个库之间不同方法的一个很好的例子。D3只做“我说的”。它假设如果我想要网格线,我会告诉它使用网格线。Kendo UI假设我想绘制一个有用的和令人愉快的图表。它假设了我想要什么。我可以关闭网格线,但默认情况下,我可能需要它们,所以不需要添加它们(D3),我必须禁用它们。这是不同的方法。
使它工作
因为我总是讨厌别人给我一些我不能运行的部分例子,我也会列出我的程序的最后一部分我需要运行这两个函数,也就是:
代码语言:javascript复制$(document).ready(function () {
代码语言:javascript复制 drawDChart();
代码语言:javascript复制 drawKChart();
代码语言:javascript复制});
这只是等待,直到文档准备好,然后运行这两个图表函数。
下一个步骤
让我们更进一步,首先,关闭那些网格线,使我们的两个图表匹配。通过向kendoChart中添加两个部分,在Kendo UI代码中很容易做到这一点。这将关闭水平和垂直网格线以匹配D3图表,并迫使Y轴使用800作为其最大值,而不是它选择的900。这也和我们告诉D3图的相匹配。
代码语言:javascript复制categoryAxis: {
代码语言:javascript复制 majorGridLines: {
代码语言:javascript复制 visible: false
代码语言:javascript复制 }
代码语言:javascript复制},
代码语言:javascript复制valueAxis: {
代码语言:javascript复制 max: 800,
代码语言:javascript复制 majorGridLines: {
代码语言:javascript复制 visible: false
代码语言:javascript复制 }
代码语言:javascript复制}
添加坐标轴
接下来缺少的是D3图上的Y轴。我们不需要告诉Kendo UI添加Y轴,它是自动完成的。同样,Kendo UI做它认为我们需要在图表中,D3只做我们告诉它的。在这个过程中,我们在两个图表上都加一个X轴。为了在D3图上添加两个轴,我们只需要添加代码:
代码语言:javascript复制// create the y axis
代码语言:javascript复制g.append("g)
代码语言:javascript复制 .attr("transform", "translate( 40, 0 )")
代码语言:javascript复制 .call(d3.axisLeft(y));
代码语言:javascript复制// create the x axis
代码语言:javascript复制g.append("g")
代码语言:javascript复制 .attr("transform", "translate( 40," height " )")
代码语言:javascript复制 .call(d3.axisBottom(x));
这是非常简单的。我们只告诉D3我们想把它放在平移的位置,然后告诉它添加坐标轴并给它数据。
在Kendo UI方面,我们已经有了Y轴和X轴的线,我们只需要标签。为此,我们只需要向之前输入的CategoryAxis部分添加一些数据即可:
代码语言:javascript复制categoryAxis: {
代码语言:javascript复制 categories: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
代码语言:javascript复制 majorGridLines: {
代码语言:javascript复制 visible: false
代码语言:javascript复制 }
代码语言:javascript复制}
这给了我们两个非常接近的图表。有一些小细节我可以调整使他们完全一样,但这是足够接近。
Tool Tips
最后一件事,我将添加到两个图表是一组工具提示给我们数据细节,当我们悬停在任何条。这将突出显示我们如何添加动画。
对于Kendo UI图表,我们需要做的就是在图表代码中添加以下部分:
代码语言:javascript复制tooltip: {
代码语言:javascript复制 visible: true,
代码语言:javascript复制 template: "Data: #= value #"
代码语言:javascript复制}
我们看到了下图:
在D3方面,当然,我们需要更多的信息。首先,我们需要添加一个部分来精确定义工具提示的外观。这是通过代码完成的:
代码语言:javascript复制// define the tooltips parameters
代码语言:javascript复制var ttip = d3.select("body")
代码语言:javascript复制 .append("div")
代码语言:javascript复制 .style("position", "absolute")
代码语言:javascript复制 .style("z-index", "10")
代码语言:javascript复制 .style("visibility", "hidden")
代码语言:javascript复制 .style("background", "white")
然后我们需要添加动作到图表部分通过添加
代码语言:javascript复制// set the tooltip
代码语言:javascript复制.on("mouseover", function (d, i) {
代码语言:javascript复制 .ttip.style("visibility", "visible" )
代码语言:javascript复制 .style("left",(d3.event.pageX) "px")
代码语言:javascript复制 .style("top",(d3.event.pageY) "px")
代码语言:javascript复制 .html("Data: " d)
代码语言:javascript复制});
代码语言:javascript复制.on("mouseout", function() { ttip.style("visibility", "hidden" ) });
这两个都很简单。这段代码表示,当我们鼠标滑过一个列时,我们会在一个特定的位置显示工具提示。该部分的最后一行与Kendo UI端上的一行类似,在那里,我们有机会提供一个模板来显示工具提示中的内容。对于D3图,我们得到:
结论
您马上就会看到一些差异。注意,我们不需要告诉Kendo UI图表我们的最大Y轴应该是多少。它查看数据,四舍五入,并选择一个合理的使用范围。同样地,我们没有告诉它关于X轴的任何东西——它只是计算数据点的数量并相应地缩放。虽然它没有画一个带有标签的X轴,因为我们没有给它任何东西,D3和Kendo UI都被广泛使用,说一个比另一个好是不公平的。它们处于不同的抽象层次,服务于不同的目的。D3允许您对可视化的每个方面进行详细控制。Kendo UI还允许您控制许多参数,但对您想要看到的内容做了许多假设。你可以让D3做Kendo UI自动做的所有事情,但是你需要明确地告诉它去做每一件事情。D3需要为每个新特性做一些编程,对于Kendo UI这些只是额外的参数,你可以设置。
如果你需要完成一项工作并按时交付一个web应用程序,并且你需要在遇到问题或出现问题时得到支持,那么像Kendo UI这样的商业库就是你最好的选择。如果您正在做一些非常不寻常的事情,需要进行极端的定制,或者正在处理一个类项目,或者其他非商业应用程序,并且您喜欢玩代码,那么D3就是一个很好的选择。这两个选项肯定比绘制单个矩形更好!它至少画出了坐标轴。它还使用了我指定的“steelblue”,并添加了一些阴影使它看起来更有趣。
最后,它添加了网格线。这是两个库之间不同方法的一个很好的例子。D3只做我说的,只做我说的。它假设如果我想要网格线,我会告诉它使用网格线。剑道UI假设我想绘制一个有用的和令人愉快的图表。它假设了我想要什么。我可以关闭网格线,但默认情况下,我可能需要它们,所以不需要添加它们(D3),我必须禁用它们。不同的方法。