使用D3.js怎么构建一个实时图形

今天就跟大家聊聊有关使用D3.js怎么构建一个实时图形,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

D3.js是一个JavaScript库,用于使用SVG,HTML和CSS在Web浏览器中生成动态的交互式数据可视化。

D3 提供了各种简单易用的函数,大大简化了 JavaScript 操作数据的难度。由于它本质上是 JavaScript ,所以用 JavaScript 也是可以实现所有功能的,但它能大大减小你的工作量,尤其是在数据可视化方面,D3 已经将生成可视化的复杂步骤精简到了几个简单的函数,你只需要输入几个简单的数据,就能够转换为各种绚丽的图形。有过 JavaScript 基础的朋友一定很容易理解它。

在本教程中,我们将探讨如何使用D3.js和Pusher Channels构建实时图形。如果您在阅读本教程时想要使用代码,请查看此GitHub存储库,其中包含代码的最终版本。

准备

要完成本教程,您需要安装Node.js和npm。我在创建本教程时使用的版本如下:

  • Node.js v10.4.1

  • npm v6.3.0

您还需要在计算机上安装http-server。它可以通过运行以下命令通过npm安装:npm install http-server。

虽然不需要Pusher知识,但如果熟悉它后,对学习JavaScript和D3.js会很有帮助。

开始

首先,为我们要构建的应用程序创建一个新目录。将其称为实时图形或任何您喜欢的图形。在新创建的目录中,创建一个新的index.html文件并粘贴以下代码:

//index.html

<!DOCTYPEhtml>
<hmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width,initial-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<linkrel="stylesheet"href="style.css"rel="externalnofollow">
<title>RealtimeD3Chart</title>
</head>
<body>

<scriptsrc="https://js.pusher.com/4.2/pusher.min.js"></script>
<scriptsrc="https://d3js.org/d3.v5.min.js"></script>
<scriptsrc="app.js"></script>
</body>
</html>

如您所见,HTML文件只是提取构建图形所需的样式和脚本。我们正在利用D3.js来构建图表,并使用Pusher来添加实时功能。app.js文件是应用程序前端代码的写入位置。

在我们开始实现图表之前,让我们在style.css中添加应用程序的样式:

//style.css

html{
height:100%;
box-sizing:border-box;
padding:0;
margin:0;
}

*,*::before,*::after{
box-sizing:inherit;
}

body{
height:100%;
font-family:-apple-system,BlinkMacSystemFont,"SegoeUI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"HelveticaNeue",sans-serif;
overflow:hidden;
background:linear-gradient(135deg,#ffffff0%,#e8f1f5100%);
}

.container{
position:absolute;
padding:20px;
top:50%;
left:50%;
background-color:white;
border-radius:4px;
transform:translate(-50%,-50%);
box-shadow:0px50px100px0pxrgba(0,0,102,0.1);
text-align:center;
}

.containerh2{
color:#333;
}

.bar{
fill:#6875ff;
border-radius:2px;
}

.bar:hover{
fill:#1edede;
}

.tooltip{
opacity:0;
background-color:rgb(170,204,247);
padding:5px;
border-radius:4px;
transition:opacity0.2sease;
}

安装服务器依赖项

假设您安装了Node和npm,请运行以下命令来安装应用程序的服务器组件所需的所有依赖项:

npminstallexpressdotenvcorspusher

Pusher 设置

前往Pusher网站并注册一个免费帐户。选择侧栏上的Channels apps,然后点击Create Channels app以创建新应用。

创建应用程序后,从API Keys选项卡中检索凭据,然后在项目目录根目录中创建一个variables.env文件,将以下内容添加到这个文件中。

//variables.env

PUSHER_APP_ID=<yourappid>
PUSHER_APP_KEY=<yourappkey>
PUSHER_APP_SECRET=<yourappsecret>
PUSHER_APP_CLUSTER=<yourappcluster>

设置服务器

现在我们已经安装了相关的依赖项并且已经设置了我们的Pusher帐户,我们可以开始构建服务器。

在项目目录的根目录中创建一个名为server.js的新文件,并粘贴以下代码:

//server.js

require('dotenv').config({path:'variables.env'});
constexpress=require('express');
constcors=require('cors');

constpoll=[
{
name:'Chelsea',
votes:100,
},
{
name:'Arsenal',
votes:70,
},
{
name:'Liverpool',
votes:250,
},
{
name:'ManchesterCity',
votes:689,
},
{
name:'ManchesterUnited',
votes:150,
},
];

constapp=express();
app.use(cors());

app.get('/poll',(req,res)=>{
res.json(poll);
});

app.set('port',process.env.PORT||4000);
constserver=app.listen(app.get('port'),()=>{
console.log(Expressrunning→PORT${server.address().port});
});

保存文件并从项目目录的根目录运行节点server.js以启动服务器。

设置前端应用程序

应用程序的前端将写在我们之前引用的app.js文件中。在项目目录的根目录中创建此文件,并在其中粘贴以下代码:

//app.js

//setthedimensionsandmarginsofthegraph
constmargin={top:20,right:20,bottom:30,left:40};
constwidth=960-margin.left-margin.right;
constheight=500-margin.top-margin.bottom;

//settherangesforthegraph
constx=d3
.scaleBand()
.range([0,width])
.padding(0.1);

consty=d3.scaleLinear().range([height,0]);

//appendthecontainerforthegraphtothepage
constcontainer=d3
.select('body')
.append('div')
.attr('class','container');

container.append('h2').text('Whowillwinthe2018/19PremierLeagueSeason?');

//appendthesvgobjecttothebodyofthepage
//appenda'group'elementto'svg'
//movesthe'group'elementtothetopleftmargin
constsvg=container
.append('svg')
.attr('width',width+margin.left+margin.right)
.attr('height',height+margin.top+margin.bottom)
.append('g')
.attr('transform','translate('+margin.left+','+margin.top+')');

//Createaskeletonstructureforatooltipandappendittothepage
consttip=d3
.select('body')
.append('div')
.attr('class','tooltip');

//Getthepolldatafromthe/pollendpoint
fetch('http://localhost:4000/poll')
.then(response=>response.json())
.then(poll=>{
//addthexAxis
svg
.append('g')
.attr('transform','translate(0,'+height+')')
.attr('class','x-axis')
.call(d3.axisBottom(x));

//addtheyAxis
svg
.append('g')
.attr('class','y-axis')
.call(d3.axisLeft(y));

update(poll);
});

functionupdate(poll){
//Scaletherangeofthedatainthexaxis
x.domain(
poll.map(d=>{
returnd.name;
})
);

//Scaletherangeofthedataintheyaxis
y.domain([
0,
d3.max(poll,d=>{
returnd.votes+200;
}),
]);

//Selectallbarsonthegraph,takethemout,andexitthepreviousdataset.
//Enterthenewdataandappendtherectanglesforeachobjectinthepollarray
svg
.selectAll('.bar')
.remove()
.exit()
.data(poll)
.enter()
.append('rect')
.attr('class','bar')
.attr('x',d=>{
returnx(d.name);
})
.attr('width',x.bandwidth())
.attr('y',d=>{
returny(d.votes);
})
.attr('height',d=>{
returnheight-y(d.votes);
})
.on('mousemove',d=>{
tip
.style('position','absolute')
.style('left',${d3.event.pageX+10}px)
.style('top',${d3.event.pageY+20}px)
.style('display','inline-block')
.style('opacity','0.9')
.html(
<div><strong>${d.name}</strong></div><span>${d.votes}votes</span>
);
})
.on('mouseout',()=>tip.style('display','none'));

//updatethex-axis
svg.select('.x-axis').call(d3.axisBottom(x));

//updatethey-axis
svg.select('.y-axis').call(d3.axisLeft(y));
}

在上面的代码块中,我们使用通过/ poll端点接收的初始数据创建了一个基本条形图。如果您熟悉D3的工作原理,那么您应该熟悉这些代码。我在代码的关键部分添加了注释,以指导您构建图表的方式。

在新终端中,启动开发服务器以提供index.html文件:

npxhttp-server

我在这里使用http-server,但你可以使用你想要的任何服务器。您甚至可以直接在浏览器中打开index.html。

此时,您的图表应如下所示:

使用D3.js怎么构建一个实时图形

使用Pusher实时更新图表

让我们确保轮询的更新可以通过Pusher Channels实时反映在应用程序的前端中。将以下代码粘贴到app.js文件的末尾。

//app.js

constpusher=newPusher('<yourappkey>',{
cluster:'<yourappcluster>',
encrypted:true,
});

constchannel=pusher.subscribe('poll-channel');
channel.bind('update-poll',data=>{
update(data.poll);
});

在这里,我们打开了与Channels的连接,并使用Pusher的subscribe()方法订阅了一个名为poll-channel的新频道。通过bind方法监听轮询更新,并在收到更新后使用最新数据调用update()函数,以便重新呈现图形。

不要忘记使用Pusher帐户信息中心中的相应详细信息替换占位符。

从服务器触发更新

我们将模拟每秒更新一次的轮询,并在数据发生变化时使用Pusher触发更新,以便轮询的订阅者(客户端)可以实时接收更新的数据。

在其他导入下面的server.js顶部添加以下代码:

constPusher=require('pusher');

constpusher=newPusher({
appId:process.env.PUSHER_APP_ID,
key:process.env.PUSHER_APP_KEY,
secret:process.env.PUSHER_APP_SECRET,
cluster:process.env.PUSHER_APP_CLUSTER,
encrypted:true,
});

functiongetRandomNumber(min,max){
returnMath.floor(Math.random()*(max-min)+min);
}

functionincrement(){
constnum=getRandomNumber(0,poll.length);
poll[num].votes+=20;
}

functionupdatePoll(){
setInterval(()=>{
increment();
pusher.trigger('poll-channel','update-poll',{
poll,
});
},1000);
}

然后将/ poll端点更改为如下所示:

app.get('/poll',(req,res)=>{
res.json(poll);
updatePoll();
});

/ poll路由将初始轮询数据发送到客户端并调用updatePoll()函数,该函数以三秒为间隔递增随机俱乐部的投票,并触发我们在最后一步中在客户端上创建的轮询频道的更新。

通过从项目目录的根目录运行节点server.js,终止服务器并重新启动它。此时,您应该有一个实时更新的条形图。

使用D3.js怎么构建一个实时图形

看完上述内容,你们对使用D3.js怎么构建一个实时图形有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注恰卡编程网行业资讯频道,感谢大家的支持。

发布于 2021-04-08 13:37:40
收藏
分享
海报
0 条评论
159
上一篇:怎么在Python中使用socket实现一个通信功能 下一篇:使用PHP怎么对Redis数据库进行操作
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码