qunee 破解怎么得到node所有坐标

Qunee for HTML5与ECharts对比 - 推酷
Qunee for HTML5与ECharts对比
ECharts是百度公司支持的开源产品,定位于Chart,Qunee for HTML5是上海酷利软件的商业软件,定位于拓扑图,两者都是前端技术,同属于数据可视化类库,但差异也很明显,本文将从大的方面对比两者特点
ECharts Qunee for HTML5
图表 - 饼图、柱状图、雷达图、地图等
拓扑图 - 组织图、流程图、地铁图等
标题,图例,数据过滤等
工具栏 - 框选,缩放,搜索等
典型驱动方式
数据驱动,配置
API驱动,二次开发
echarts.js - 350kb, echarts-all.js - 921kb
qunee-min.js - 333kb
浏览器支持
IE6+, chrome, safari, firefox ...
IE9+, chrome, safari, firefox ...
ECharts:图表 - 折线图、柱状图、散点图、K线图、饼图、雷达图、地图、和弦图、力导向布局图、仪表盘以及漏斗图
Qunee for HTML5:拓扑图 - 拓扑图 - 社交网络图、网络管理图;地图 - 地铁图、统计地图;其他 - 组织图、思维导图、流程图
ECharts: 标题,图例,数据过滤,数据视图等
Qunee for HTML5: 工具栏:缩放、框选、搜索等
ECharts: 数据驱动,chart.setOption({series, legend …})
Qunee for HTML5: API驱动,graph.createNode(..), graph.createEdge(…)
Hello ECharts
echarts定位于图表,用户配置特定的数据,echarts解析显示,非开发者也可以使用
&div id=&main& style=&height:400px&&&/div&
&script src=&/build/dist/echarts-all.js&&&/script&
&script type=&text/javascript&&
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {show: true},
legend: {data: ['销量']},
xAxis: [{type: 'category', data: [&衬衫&, &羊毛衫&, &雪纺衫&, &裤子&, &高跟鞋&, &袜子&]}],
yAxis: [{type: 'value'}],
series: [{&name&: &销量&, &type&: &bar&, &data&: [5, 20, 40, 10, 10, 20]}]
myChart.setOption(option);
运行效果:
Hello Qunee
qunee定位于拓扑图二次开发包,通常都需要编写代码,面向高级开发者
&div style=&height: 500& id=&canvas&/&
&script src=&/lib/qunee-min.js&&&/script&
var graph = new Q.Graph('canvas');
var hello = graph.createNode(&Hello&, -100, -50);
hello.image = Q.Graphs.
var qunee = graph.createNode(&Qunee&, 100, 50);
var edge = graph.createEdge(&Hello\nQunee&, hello, qunee);
运行效果:
ECharts - 展示地图上的统计数据
Qunee for HTML5 - 展示地图背景拓扑图
ECharts Qunee for HTML5
地图数据统计
地图拓扑图
没看到地图 + 拓扑图的示例
专注于拓扑图
官方示例数据量并不大,性能却不高,炫光特效的几个例子略卡
从世界地图到地市级别,再加上万节点连线,交互依旧流畅
地图数据比较粗糙,广东省和海南岛居然是连在一起的,不确定echarts能提供从世界地图放大到地市的方案
可以提供从世界地图到国内县市,各种精度的地图输出
官方示例中地图只有颜色填充,成图效果不佳
支持颜色、渐变、阴影、边线样式等效果,更好的展示效果
支持与定制
地图拓扑并非echarts的重点,不确定如何从百度公司获得官方支持和定制服务
商业软件,专注于拓扑,提供官方技术支持,特殊需求可以定制
ECharts 地图截图
Qunee 地图截图
两者定位不同,ECharts专注于大众的图表,Qunee专注于专业的拓扑图,图表用户群体比较广,通常配置一下数据就可以显示,而Qunee面向专业开发人员,通常需要编写代码才能实现业务需求
关于地图,ECharts可以显示地图统计数据,而Qunee则支持地图与拓扑图的结合展示
性能方面,Qunee(商业授权)支持上万图元,交互流畅,从官方示例看,ECharts在性能和体验方面还有很大的改善空间
总的来说,两者可以互补,Qunee目前没有图表,ECharts拓扑图弱,此外Chart方面的优秀组件很多,比如highcharts,也有map,效果体验更好
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致基于HTML5的拓扑图编辑器 - Graph.Editor - 有乐窝
摘要: Graph.Editor是一款基于HTML5技术的拓补图编辑器,采用jquery插件的形式,是Qunee图形组件的扩展项目,旨在提供可供扩展的拓扑图编辑工具, 拓扑图展示、编辑、导出、保存等功能,此外本项目也是学习HTML5开发,构建 ...
拓扑图编辑器介绍
拓扑图编辑器项目 - Graph.Editor 正式发布到github了,欢迎访问、提取和贡献代码
项目地址:
在线演示:
Graph.Editor是一款基于HTML5技术的拓补图编辑器,采用jquery插件的形式,是Qunee图形组件的扩展项目,旨在提供可供扩展的拓扑图编辑工具, 拓扑图展示、编辑、导出、保存等功能,此外本项目也是学习HTML5开发,构建WebAPP项目的参考实例。
数据可视化是一件有趣的工作,冰冷的数据变成美观的图形,如同命令行之于Mac OS X图形界面的,传统的图形组件以图表(Chart)居多,不少优秀的开源或者商业的作品, 比如d3js, echarts, highcharts,而拓扑图、流程图组件相对少一些,知名的有yfiles,本项目则基于Qunee图形组件,是Qunee的扩展项目,旨在为客户提供可供扩展的拓扑图编辑工具, 提供拓扑图展示、编辑、导出、保存等功能,此外本项目也是学习HTML5开发,构建WebAPP项目的参考实例。
注意:本项目内核使用Qunee for HTML5,Qunee本身是一个商业产品,默认仅限本机(localhost)使用,非商业用途可以申请免费授权,商业用途请购买相应授权,官网:
在线演示:
请访问此地址查看效果:
Hello Graph.Editor
&!DOCTYPE html&
&meta charset=&UTF-8&&
&title&Hello Qunee&/title&
&link rel=stylesheet href=/editor/libs/bootstrap/css/bootstrap.css&
&link rel=stylesheet href=/editor/libs/graph.editor/graph.editor.css&
&body class=&layout&&
&div id=&editor& data-options=&region:&center&&&&/div&
&script class="lazy-load" data-original=&/editor/libs/js.js&&&/script&
&script class="lazy-load" data-original=&/lib/qunee-min.js?v=1.8&&&/script&
&script class="lazy-load" data-original=&/editor/libs/graph.editor/graph.editor.js&&&/script&
$(&#editor&).graphEditor({callback: function(editor){
var graph = editor.
var hello = graph.createNode(&Hello&, -100, -50);
hello.image = Q.Graphs.
var qunee = graph.createNode(&Qunee&, 100, 50);
var edge = graph.createEdge(&Hello\nQunee&, hello, qunee);
graph.moveToCenter();
编辑器的基本示例相比Hello Qunee要复杂些,除了
类库外,还用到了一些第三方组件:jquery,
此外就是Graph.Editor自身的类库,这里我们引用在线的js和css
实际代码部分,采用了jquery的写法,如下:
$(&#editor&).graphEditor({
callback: 回调函数,
data: json数据地址,
images: 拖拽图标信息
本例中,通过回调函数获取editor.graph对象,并创建了两个节点和一条连线
更多用法请查看其他demo和代码
项目用到nodejs,使用bower包管理,用到Gulp相关的插件打包和发布
本项目使用以下工具:
安装nodejs
安装bower - 包管理
安装Gulp - 任务自动管理工具
开始开发环境
切换到项目目录,然后运行下面的命令,完成开发环境的安装
npm install
前端第三方包
用到jquery, bootstrap, layout.border,使用bower下载这些包到bower_components目录
bower install
项目主要代码在app目录,其中脚本代码在app/class="lazy-load" data-original/内,
--class="lazy-load" data-original/
编辑器扩展插件
--Exportpane.js 图片导出模块
--JSONSerializer.js
数据序列化模块
--PopupMenu.js
右键菜单模块
--Toolbar.js
工具栏模块
--graph.editor.js
拓扑图编辑器插件
--graph.editor.css
--scripts/
--index.html
编辑器主页面
--demo.html
编辑器插件示例
dist/ 输出目录
bower_components/ bower第三方包目录,运行bower install 后自动生成
node_modules/ 开发环境相关包目录,运行npm install后自动生成
输出目录结构
bootstrap/
第三方类库bootstrap样式和资源目录
graph.editor/
graph.editor类库
graph.editor.css
graph.editor.js
第三方类库(jquery, bootstrap, layout.border)
index.html
编辑器主要的类库文件位于libs/graph.editor/, 第三方类库(jquery, bootstrap, layout.border)位于libs/js.js,bootstrap样式和资源目录位于libs/bootstrap/
转自:http://www.html5cn.org/article-7585-1.html
你还未登录,请先&&或者,注册使用Qunee组件显示水文观测站点 - Web前端当前位置:& &&&使用Qunee组件显示水文观测站点使用Qunee组件显示水文观测站点&&网友分享于:&&浏览:0次使用Qunee组件展示水文观测站点
中科院的某个客户遇到这样的需求:将区域内所有水文观测站信息按层次结构展现出来。原来用的是mxGraph组件,遇到几个问题:布局难以定制、节点样式难定制、交互有问题,后来改用Qunee组件,顺利解决问题。 这是一种典型应用,主要用到Qunee的布局类TreeLayouter,以及UI和交互的简单定制,下面以示例来做介绍
按水文观测站区域与级别分五个等级,最顶层的是主站点,下面分区站点,再往下子站点,最后是实际观测点或者设备,因为站点总数量几千上万,为了便于查看,采用动态加载方式,点击站点节点的加号,动态加载子站点,并执行自动布局 最终的效果类似下面截图
初始化图形组件
这里将Graph组件直接嵌入到document.body,并设置body尺寸布满整个窗口
var graph, canvas, root,
function init() {
canvas = document.
function updateGraphSize() {
canvas.style.width = window.innerWidth + "px";
canvas.style.height = window.innerHeight + "px";
if (graph) {
graph.moveToCenter();
window.onresize = updateGraphS
updateGraphSize();
graph = new Q.Graph(canvas);
Q.addEventListener(window, "load", init);
考虑到子站点数据较多,利用屏幕宽度大于高度的特点,选择从左向右分布
function init() {
layouter = new Q.TreeLayouter(graph);
layouter.parentChildrenDirection = Q.Consts.DIRECTION_RIGHT;
layouter.hGap = 50;
layouter.vGap = 40;
设置孩子布局方式与方向
因为第二层节点的孩子数量较多,所以采用两侧布局,其后的节点方向也保持从左向右
if (level == 1) {//设置第二层孩子布局方式
node.layoutType = Q.Consts.LAYOUT_TYPE_TWO_SIDE;
} else if (level == 2) {//设置第三层布局方向与连线类型
node.parentChildrenDirection = Q.Consts.DIRECTION_RIGHT;
edge.edgeType = Q.Consts.EDGE_TYPE_HORIZONTAL_VERTICAL;
两侧布局效果
定制节点效果
根据应用需要,通过Q.Node#addUI(...)方法,对节点添加不同的图标,放置在不同位置,并关联相关属性
function createGraphNode(name, icon, canAdd, showDetail) {
var node = graph.createNode(name);
node.setStyle(Q.Styles.BACKGROUND_COLOR, Q.toColor(0xEEDDDDDD));
node.setStyle(Q.Styles.PADDING, new Q.Insets(2, 5));
node.setStyle(Q.Styles.BACKGROUND_GRADIENT, backgroundGradient);
node.setStyle(Q.Styles.BORDER, 1);
node.setStyle(Q.Styles.BORDER_COLOR, Q.toColor(0x555555));
if (icon) {
node.image =
node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.RIGHT_MIDDLE);
node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_MIDDLE);
node.image = "./empty.png";
node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_TOP);
node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.CENTER_BOTTOM);
if (canAdd) {
var ui = new Q.ImageUI("./add.png");
ui.name = "add";
ui.position = Q.Position.CENTER_BOTTOM;
if (showDetail) {
ui.anchorPosition = Q.Position.LEFT_TOP;
ui.offsetX = 10;
ui.anchorPosition = Q.Position.CENTER_TOP;
ui.showPointer =
node.addUI(ui, {
property: "icon1",
propertyType: Q.Consts.PROPERTY_TYPE_CLIENT,
bindingProperty: "data"
node.set("icon1", "./add.png");
if (showDetail) {
var ui = new Q.ImageUI("./detail.png");
ui.name = "showDetail";
ui.position = Q.Position.CENTER_BOTTOM;
ui.anchorPosition = Q.Position.CENTER_TOP;
if (canAdd) {
ui.anchorPosition = Q.Position.RIGHT_TOP;
ui.offsetX = -10;
ui.anchorPosition = Q.Position.CENTER_TOP;
ui.showPointer =
node.addUI(ui);
呈现效果如下
创建连线,并指定连线类型为正交类型
function createGraphEdge(from, to) {
var edge = graph.createEdge(from, to);
edge.edgeType = Q.Consts.EDGE_TYPE_ORTHOGONAL_HORIZONTAL;
edge.setStyle(Q.Styles.EDGE_SPLIT_BY_PERCENT, false);
edge.setStyle(Q.Styles.EDGE_SPLIT_VALUE, 15);
根据点击位置,执行不同动作
graph.onclick = function (evt) {
var target = graph.hitTest(evt);
if (!target || target instanceof Q.ElementUI) {
if (target.name == "add") {
var ui = target.
if (ui && ui.data instanceof Q.Node && !ui.data.userData.isEnd) {
loadChildren(onDataLoad, ui.data);
} else if (target.name == "showDetail") {
var ui = target.
if (ui && ui.data instanceof Q.Node) {
alert(ui.data.userData.fld_name);
graph.ondblclick = function (evt) {
var ui = graph.getUIByMouseEvent(evt);
if (!ui || !(ui.data instanceof Q.Node)) {
layouter.doLayout();
graph.zoomToOverview();
var node = ui.
if (node.userData.isEnd) {
loadChildren(onDataLoad, node);
/waterwsn/
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有结合OpenLayers实现地图背景的拓扑图_html5_ThinkSAAS
结合OpenLayers实现地图背景的拓扑图
结合OpenLayers实现地图背景的拓扑图
地图应用分三种级别:示意地图(Map Chart),地图(Map),地理信息系统(GIS),第一种通常使用相对坐标系,后两种则为真实的地理坐标,其中第二种以谷歌地图为代表,日常生活中普遍使用,后一种则为专业的GIS,专业领域做拓扑分析、流域分析时用到,示意地图我们已经有很多例子,比如、等,今天介绍第二种地图的应用,结合OpenLayers和谷歌地图实现地图的拓扑图应用:
OpenLayers是开源地理基金会作(OSGeo.org)支持的项目之一,是一种通用的地理客户端平台,支持谷歌地图,Bing地图,WMS,GML等多种地图在线服务,这里用到的是谷歌地图,需要引入OpenLayers和google map的js类库和css文件 引入相关类库
&link rel="stylesheet"href="OpenLayers/theme/default/style.css"type="text/css"&
&script src="/get//maps/api/js?v=3&sensor=false"&&/script&
&script src="OpenLayers/OpenLayers.js"&&/script&
初始化地图
参照OpenLayers官方示例,完成地图初始化工作
function initMap(canvas, lon, lat){
map = new OpenLayers.Map(canvas, {
projection: 'EPSG:3857',
new OpenLayers.Layer.Google(
"Google Streets", // the default
{numZoomLevels: 20}
new OpenLayers.Layer.Google(
"Google Physical",
{type: google.maps.MapTypeId.TERRAIN}
new OpenLayers.Layer.Google(
"Google Hybrid",
{type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}
new OpenLayers.Layer.Google(
"Google Satellite",
{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
center: new OpenLayers.LonLat(lon, lat).transform('EPSG:4326', 'EPSG:3857'),
map.addControl(new OpenLayers.Control.LayerSwitcher());
左边是缩放按钮,右边可以选择地图图层
地图与拓扑图的结合
OpenLayers与Qunee是两套不同的组件库,有着各自的交互系统和坐标系,需要实现组件叠加,以及坐标和交互的同步
OpenLayers结构复杂,具有多个HTML图层,而Qunee相对简单,所以最终决定将Qunee插入到OpenLayers的viewportDiv中
var canvas = document.createElement('div');
canvas.style.width = '100%';
canvas.style.height = '100%';
canvas.style.position = 'absolute';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.zIndex = 999;
map.viewPortDiv.insertBefore(canvas, map.viewPortDiv.firstChild);
Q.doSuperConstructor(this, MapGraph, [canvas]);
Qunee使用的是屏幕坐标,与地图坐标系完全不同,需要做转换
经纬度转换成屏幕坐标
需要两步,首先将经纬度转换成当前地图的投影坐标,使用的是OpenLayers提供的OpenLayers.LonLat#transform(原始投影, 目标投影)方法
toLonLat: function(lon, lat){
var l = new OpenLayers.LonLat(lon, lat);
l.transform('EPSG:4326', graph.map.getProjectionObject());
然后将转换后的坐标转换成屏幕坐标
getPixelFromLonLat: function(lonLat){
return this.map.getPixelFromLonLat(lonLat);
根据经纬度创建节点
createNodeByLonLat: function(name, lon, lat){
var l = this.toLonLat(lon, lat);
var p = this.getPixelFromLonLat(l);
var node = graph.createNode(name, p.x, p.y);
node.lonLat =
屏幕坐标转换成地理坐标
同理,在节点移动后,需要将屏幕坐标转换成地理坐标 也需要两步,首先将qunee的逻辑坐标转换成屏幕坐标,然后再用OpenLayers的getLonLatFromPixel方法,转换成地理坐标
var pixel = this.toCanvas(data.location.x, data.location.y);
data.lonLat = this.map.getLonLatFromPixel(new OpenLayers.Pixel(pixel.x, pixel.y));
在节点移动后都需要做这些转换,监听节点拖拽完成事件,进行坐标的同步
this.interactionDispatcher.addListener(function(evt){
if(evt.kind == Q.InteractionEvent.ELEMENT_MOVE_END){
var datas = evt.
Q.forEach(datas, function(data){
var pixel = this.toCanvas(data.location.x, data.location.y);
data.lonLat = this.map.getLonLatFromPixel(new OpenLayers.Pixel(pixel.x, pixel.y));
OpenLayers和Qunee的交互是冲突的,比如拖拽操作,qunee响应了,OpenLayers就没法响应,这里我们在Qunee交互的基础之上实现地图的漫游缩放操作
通过重写Q.Graph的translate方法,实现两者的同步,是不是挺简单
translate: function (tx, ty) {
Q.doSuper(this, MapGraph,"translate", arguments);
this.map.moveByPx(-tx, -ty);
OpenLayers默认的通过双击、鼠标滚轮实现缩放,这些事件默认会被Qunee所拦截,所以需要自己添加和派发
this.html.ondblclick = createEventFunction(this, function(evt){
if(this.getElementByMouseEvent(evt)){
Q.stopEvent(evt);
this.onmousewheel = function(evt){
if (this._scaling) {
this._scaling =
Q.callLater(function() {
delete this._
}, this, 200);
this.map.zoomTo(this.map.zoom + (evt.delta & 0 ? 1 : -1), this.globalToLocal(evt));
缩放后的坐标同步 Qunee也有默认的缩放机制,但在地图应用中不太适用,所以需要屏蔽掉
this.enableWheelZoom =
this.enableDoubleClickToOverview =
然后监听地图的缩放事件
this.map.events.register('zoomend', this, function(){this.updateNodes(true)});
实现对节点的坐标同步
updateNodes: function(updateLocation){
if(updateLocation === true){
this.forEach(function(d){
if(d instanceof Q.Node){
var l = d.lonL
var p = this.getPixelFromLonLat(l);
d.location =
this.translateTo(0, 0);
this.translateTo(this.map.layerContainerOriginPx.x, this.map.layerContainerOriginPx.y);
最终的运行效果
在线演示:
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信

我要回帖

更多关于 qunee 的文章

 

随机推荐