项目中需要用到仪器仪表的界面来显示实时的采集信息值,于是便遍地寻找,参考了fusionchart和anychart之后,发现都是收费的,破解的又没有这些功能,只好作罢。之后又找遍了JQuery的插件,也没有找到,于是在灰心之时,Dojo的demo界面让我欣喜若狂:Graphics, Charting and Vizualization 看罢之后,就决定采用Dojo了。
基础知识概览
这篇文章,主要讲解如何利用Dojo原生的仪器仪表界面(Dojo有很强大的绘图功能,后期如果有机会,会分享自绘的仪器仪表界面),来通过Ajax实现采集的数据实时传送给仪表显示。
首先,开始编码之前,需要的东西就是DOJO包:Dojo Toolkit Release,下载之后解压出来,拷贝到项目中即可。项目文件很多,你不需要的功能可以自己去掉。这次我们使用的东西在Dojox包下面。
这里简单介绍下每个目录中的不同内容(如果有误,还请纠正):
dojo目录下的是支撑运行的基础类库定义。
dijit目录下则是众多的插件。
dojox目录下则是第三方自行开发的插件。
而这次我们得东西则是放在了dojox/dgauges目录下面,下面开始进入编码阶段。
操作步骤
首先,我们需要引入dojo.js:
<script src="Dojo/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: true, async:true"></script>
引入的时候,我加入了parseOnLoad和async两个config节点,对于前者,能够自动引入相关的js文件,无需一个一个的添加。对于后者则是开启异步模块加载。
然后,我们可以利用require关键字引入需要的资源文件:
require(["dojo/ready", "dojo/dom", "dojox/dgauges/components/default/CircularLinearGauge", "dojox/dgauges/GaugeBase"])
再之后,我们就可以在画板上画出这个圆形仪表:
function(ready, dom, CircularLinearGauge, GaugeBase) {
linearGauge = new CircularLinearGauge({value:publicVariable, animationDuration:1200}, dom.byId("CircularGauge"));
}
所需要的html代码仅仅是一个div而已:
<div id="CircularGauge" style="width:200px;height:200px" ></div>
这样,当我们画出来的时候,就会出现如图所示的效果:
看上去是不是很容易呢?
但是,如何和Asp.net后台通过Ajax交互呢?
由于我比较喜欢Jquery,所以这里我决定采用Jquery的Ajax方式和Asp.net后台进行交互,请看代码:
var TriggerBackendData=function(){
$.ajax({
url:'Ajax/GaugeManager.asmx/ReturnBusinessData',
type:'post',
contentType: "application/json", //from backend
dataType: "json", // send to backend
data:'{}',
success:function(result){
linearGauge.set("value", result.d);
linearGauge.refreshRendering();
},
error:function(data){
alert('Request Data Failure.');
}
});
}
由于是测试,所以在后台,我就简简单单返回来一个随机数字:
using System;
using System.ComponentModel;
using System.Web.Services; namespace DojoDaemon.Ajax
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class GaugeManager : System.Web.Services.WebService
{
[WebMethod]
public int ReturnBusinessData()
{
Random ran = new Random();
return ran.Next(0, 100);
}
}
}
这样,在前台,当我们设定为3s更新一次界面的时候,我们就可以看到仪表忽左忽右的随着获取的数据动态的转动了,下面是完整的代码部分:
require(["dojo/ready", "dojo/dom", "dojox/dgauges/components/default/CircularLinearGauge", "dojox/dgauges/GaugeBase"],
function(ready, dom, CircularLinearGauge, GaugeBase) {
linearGauge = new CircularLinearGauge({value:publicVariable, animationDuration:1200}, dom.byId("CircularGauge"));
setInterval(TriggerBackendData, 3000);
});
更多图形
当然,系统中还自带了其他三种图形,我都一并列举到下面:
半圆形仪表:
require(["dojo/ready", "dojo/dom", "dojox/dgauges/components/classic/SemiCircularLinearGauge", "dojox/dgauges/GaugeBase"],
function(ready, dom, SemiCircularLinearGauge, GaugeBase) {
semiGauge = new SemiCircularLinearGauge({value:publicVariable, animationDuration:1200}, dom.byId("CircularGauge2")); setInterval(function() {
var randomValue = Math.floor((Math.random() * 100) + 1);
semiGauge.set("value", randomValue);
semiGauge.refreshRendering();
}, 1000);
});
横向刻度尺:
require(["dojo/ready", "dojo/dom", "dojox/dgauges/components/classic/HorizontalLinearGauge", "dojox/dgauges/GaugeBase"],
function(ready, dom, HorizontalLinearGauge, GaugeBase) {
horizontalGauge = new HorizontalLinearGauge({value:publicVariable,Maximum:120,Minimum:0,animationDuration:1200}, dom.byId("HGauge3")); setInterval(function() {
var randomValue = Math.floor((Math.random() * 100) + 1);
horizontalGauge.set("value", randomValue);
horizontalGauge.refreshRendering();
}, 1000);
});
纵向刻度尺:
require(["dojo/ready", "dojo/dom", "dojox/dgauges/components/default/VerticalLinearGauge", "dojox/dgauges/GaugeBase"],
function(ready, dom, VerticalLinearGauge, GaugeBase) {
verticalGauge = new VerticalLinearGauge({value:publicVariable,Maximum:120,Minimum:0,animationDuration:1200}, dom.byId("VGauge4")); setInterval(function() {
var randomValue = Math.floor((Math.random() * 100) + 1);
verticalGauge.set("value", randomValue);
verticalGauge.refreshRendering();
}, 1000);
});
源码下载
Prolog学习:基本概念
上一篇对Prolog有了一个感性的认识,今天介绍下Prolog中一些基本概念,想要用Prolog解决一些实际问题之前必须要先了解它们。这些概念在《七周七语言》这本书中都有介绍,我简单提炼汇总下,就当给这门小众语言做个宣传吧。
变量/规则/知识库
在Prolog中变量的命名是有特殊要求的,如果一个词以小写字母开头,它就是一个原子(atom),类似于其他语言中的符号(symbol),如果一个词以大写或下划线开头,那么它就是一个变量,和其他语言一样变量值可以改变,可以赋值(不过更灵活)。
符号组成一些事实:
likes(zhangsan,lisi).
likes(wangwu,lisi).
likes(chenliu,maqi).
符号和变量在一起可以用来定义规则:
friend(X,Y):- \+(X = Y),likes(X,Z),likes(Y,Z).
事实是我们对这个世界直接观察的结果。规则是关于现实世界的逻辑推论。
事实 + 规则 = 知识库。
上面的规则可以叫做friend/2因为它有两个参数(类似C#方法中的形参),:-读作“如果”,“如果”后面是由一系列“子目标”组成,子目标之间可以是且的关系,用“,”分割,也可以是或者的关系,用“.”表示。Prolog就是通过验证规则来回到我们yes或no的,如果参数能满足所有子目标就是yes。
合一(unification)
合一是Prolog中一个非常重要的概念。简单的来说合一就相当于其它语言中的赋值:
cat(lion).
cat(tiger). dorothy(X,Y,Z) :- X = lion,Y = tiger,Z = bear.
twin_cast(X,Y) :- cat(X),cat(Y).
合一的意思是:找出那些使规则匹配的值。
所以执行dorothy(lion,tiger,bear).这句,Prolog会返回yes:
dorothy/3规则的右侧,Prolog将lion赋值给X,tiger赋值给Y,bear赋值给Z,就像在命令式语言中这样:
var X = lion;
var Y = tiger;
var Z = bear;
这些值和左侧(也就是dorothy(lion,tiger,bear))对应的值相匹配,所以合一成功。
不过真正让合一发挥作用的是因为它在规则的两侧都能工作,在GNU Prolog中执行下面的语句:
dorothy(One,Two,Three).
会得到这样的结果:
在规则右侧Prolog还是分别将X,Y,Z和lion,tiger,bear进行绑定,而在规则的右侧,Prolog是的One,Two,Three分别和X,Y,Z进行合一了:
One = X = lion;
Two = Y = tiger;
Three = Z = bear;
并且合一的情况有时候不是唯一的,我们如下执行上面的twin_cast规则:
twin_cast(One,Two).
可以通过“;”来进行追问,有时候我们可能不满足于一个答案。
怎么样你是不是已经预见到合一在Prolog中发挥的至关重要的作用了:输出。
列表/元组
只要是语言都会有数据结构,因为程序 = 算法 + 数据结构。
Prolog中有两个非常重要的数据结构:列表和元祖。列表是变长的容器:像[1,2,3]这样表示,元组是定长的容器,像(1,2,3)这样表示。两个数据结构非常简单,但是和合一配合起来的时候会十分强大。
| ?- (1,2,3) = (1,2,3). yes
| ?- [A,B,C] = [A,B,C].
yes
如果两个元组拥有的元素数量相同并且每个元素可以合一 ,则它们整体就是合一的。
加入变量会更有趣:
| ?- [A,B,C] = [1,2,3]. A = 1
B = 2
C = 3 yes
并且变量在哪一侧无所谓,只要Prolog认为它们可以相同,那么就可以合一:
| ?- [A,2,C] = [1,B,3]. A = 1 B = 2 C = 3 (16 ms) yes |
这让我想到小时候玩的一种扑克牌游戏了,当抓到大王或小王的时候,我可以把它看做是任何一张牌。
另外列表拥有一个元组不拥有的功能,这个功能在后面介绍的递归中会被广泛使用。 那就是通过[Head|Tail]解析列表,很简单看个例子就明白了:
| ?- [Head|Tail] = [1,2,3,4]. Head = 1
Tail = [2,3,4] yes
Head绑定到1,Tail绑定到剩下的元素,Tail仍然是一个列表。因为Prolog的变量是没有数据类型之分的,所以它可以很容易的绑定为列表或元组,这点有点动态语言的性质,Prolog中也有匿名变量:
| ?- [a,b,c,d,e]=[_,_|[Head|_]]. Head = c yes
这样我们就能指定提取列表中某一个元素了。
递归
我们趁热打铁看看Prolog中递归是怎么发挥作用的,留心它和命令式语言中的不同。
我们就以经典的斐波那契数列做例子吧,我们先来看下命令式语言是如何实现,这个再熟悉不过了:
static void Main(string[] args)
{
Console.WriteLine(Fibonacci(8)); Console.ReadKey();
}
static int Fibonacci(int n)
{
if (n == 1) return 0;
if (n == 2) return 1;
return Fibonacci(n - 2) + Fibonacci(n - 1);
}
在看Prolog是如何实现之前,我们先来描述一下关于斐波那契数列的既定事实和规则,因为Prolog正是基于事实和规则的一门语言:
- 第一个数是0;
- 第二个数是1;
- 从第三个数开始等它前面两个数之和。
好了和上面对应的Prolog的代码也是三行:
fibonacci(1,0).
fibonacci(2,1).
fibonacci(N,V) :- N > 2, N1 is N -1, N2 is N -2, fibonacci(N1,V1),fibonacci(N2,V2), V is V1 + V2.
注:is是Prolog中内置的一个谓词。
比较起来你可能觉得和C#代码差不多,都很简洁,Prolog有什么特别的或者说优势呢?其中区别各位自己体会吧,我也在慢慢体会,这个区别就是声明式语言和命令式语言之间的区别。
这个例子太简单不能很好体现Prolog的优势,下一篇文章我们看下用Prolog是如何解决数独和八皇后问题的。我们来看下《七周七语言》这本书中几个递归的例子,也许你能感兴趣不妨试试:
count(0,[]).
count(Count,[Head|Tail]):- count(TailCount,Tail),Count is TailCount + 1. sum(0,[]).
sum(Total,[Head|Tail]):- sum(Sum,Tail),Total is Sum + Head. average(Average,List):- sum(Sum,List),count(Count,List),Average is Sum/Count.
count是求列表元素的个数,sum是求和,average是求平均值。
内置谓词
所谓内置的谓词,可以简单理解为Prolog提供的一些基本“功能”,就像.net中的一些类库一样。上面提到的is就是。
length:获取列表的长度:
| ?- length([1,2,3],L). L = 3 yes
append:可以用来合并两个列表,当然还有很多其他功能:
| ?- append([1],[2],What). What = [1,2] yes
用于列表的减法:
| ?- append([1],What,[1,2,3]). What = [2,3] yes
排列组合:
| ?- append(One,Two,[1,2,3,4]). One = []
Two = [1,2,3,4] ? ; One = [1]
Two = [2,3,4] ? ; One = [1,2]
Two = [3,4] ? ; One = [1,2,3]
Two = [4] ? ; One = [1,2,3,4]
Two = [] (15 ms) yes
fd_domain:验证值是否在一个范围之内:
| ?- fd_domain(1,1,4). yes | ?- fd_domain([1,2,3,4],1,4). yes | ?- fd_domain([1,2,3,5],1,4). no
fd_all_different:检查列表中是否有重复元素:
| ?- fd_all_different([1,2,3]). yes
| ?- fd_all_different([1,2,1]). no
member:检查某一个值是否在一个列表内:
| ?- member(1,[1,2]). true ? yes
| ?- member(3,[1,2]). no
好了关于Prolog的基本概念就介绍到这,下一篇文章我们会看下通过这些基本概念Prolog是如何解决一些复杂问题的。想了解更多推荐大家去看看这本书。
Prolog学习:基本概念 and Asp.net与Dojo交互:仪器仪表实现的更多相关文章
-
Asp.net与Dojo交互:仪器仪表实现
项目中需要用到仪器仪表的界面来显示实时的采集信息值,于是便遍地寻找,参考了fusionchart和anychart之后,发现都是收费的,破解的又没有这些功能,只好作罢.之后又找遍了JQuery的插件, ...
-
Prolog学习:基本概念
上一篇对Prolog有了一个感性的认识,今天介绍下Prolog中一些基本概念,想要用Prolog解决一些实际问题之前必须要先了解它们.这些概念在<七周七语言>这本书中都有介绍,我简单提炼汇 ...
-
MongoDB实战开发 【零基础学习,附完整Asp.net示例】
MongoDB实战开发 [零基础学习,附完整Asp.net示例] 阅读目录 开始 下载MongoDB,并启动它 在C#使用MongoDB 重构(简化)代码 使用MongoDB的客户端查看数据 使用Mo ...
-
分布式强化学习基础概念(Distributional RL )
分布式强化学习基础概念(Distributional RL) from: https://mtomassoli.github.io/2017/12/08/distributional_rl/ 1. Q ...
-
C#学习基础概念二十五问
C#学习基础概念二十五问 1.静态变量和非静态变量的区别?2.const 和 static readonly 区别?3.extern 是什么意思?4.abstract 是什么意思?5.internal ...
-
SpringBoot学习笔记(4):与前端交互的日期格式
SpringBoot学习笔记(4):与前端交互的日期格式 后端模型Date字段解析String 我们从前端传回来表单的数据,当涉及时间.日期等值时,后端的模型需将其转换为对应的Date类型等. 我们可 ...
-
js面向对象学习 - 对象概念及创建对象
原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...
-
通过Redux源码学习基础概念一:简单例子入门
最近公司有个项目使用react+redux来做前端部分的实现,正好有机会学习一下redux,也和小伙伴们分享一下学习的经验. 首先声明一下,这篇文章讲的是Redux的基本概念和实现,不包括react- ...
-
SQL Server数据库学习笔记-概念数据模型
概念数据模型(Conceptual Data Model)也称为信息模型.它是对客观事物及其联系的抽象,用于信息世界的建模,是现实世界到信息世界的第一层抽象,是数据库设计人员进行数据库设计的有力工具. ...
随机推荐
-
One Time Auth
One Time Auth One-time authentication (shortened as OTA) is a new experimental feature designed to i ...
-
hdu - 1829 A Bug&#39;s Life (并查集)&;&;poj - 2492 A Bug&#39;s Life &;&; poj 1703 Find them, Catch them
http://acm.hdu.edu.cn/showproblem.php?pid=1829 http://poj.org/problem?id=2492 臭虫有两种性别,并且只有异性相吸,给定n条臭 ...
-
iOS开源项目推荐|下拉刷新
MJRefresh - 仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能.可以自定义上下拉刷新的文字说明. CBStoreHouseRefresh ...
-
cdh4.1.2 hadoop和oozie集成问题
1.异常信息例如以下: Caused by: com.google.protobuf.ServiceException: java.net.ConnectException: Call From sl ...
-
[Python]打开文件的模式
Python中以sys.open()方法打开文件 import sys file = open("D:\\file.txt") 其中可在第二个参数的位置指定打开文件的模式 impo ...
-
PHP 安装与配置(WIN10)
需要在本地搭个PHP的测试环境,顺手将过程写了下来. 由于不是生产环境,我这里直接选择了最新的PHP版本用来测试. 本地坏境为:windows 10 Pro 1709 PHP版本:php-7.2.3- ...
-
Dapper批量更新
本次示例项目使用Dappe1.50.5和Dapper.Contrib1.50.5 数据库执行的脚本检测工具是SQL Server Prifiler 1.使用Where In 实现批量更新 1.1代码如 ...
-
一篇自己都看不懂的点分治&;点分树学习笔记
淀粉质点分治可真是个好东西 Part A.点分治 众所周知,树上分治算法有$3$种:点分治.边分治.链分治(最后一个似乎就是树链剖分),它们名字的不同是由于分治方式的不同的.点分治,顾名思义,每一次选 ...
-
教你phpstudy如何搭建本地多站点
经常做多个网站同时开发,如何才能在本地能使部署多个站点,今天就来分享一下如何用PHPstudy搭建本地多站点. 点击上图中的 其它选项菜单 ,就会弹出下面的对话框,然后点击 站点域名管理 然后在 网站 ...
-
快速开方法(c语言)译文
人们最早就在Quake3源代码中发现了类似如下的C代码,它可以快速的求1/sqrt(x),在3D图形向量计算方面应用很广. float invSqrt(float x) { float xhalf = ...