提交 4e1be3eb 编写于 作者: L lang

Force加入force-directed tree example, node collapsible example

上级 a4a11c3b
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ECharts</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="ECharts">
<meta name="author" content="linzhifeng@baidu.com">
<script src="../asset/js/esl/esl.js"></script>
<script src="../asset/js/codemirror.js"></script>
<script src="../asset/js/javascript.js"></script>
<link href="../asset/css/bootstrap.css" rel="stylesheet">
<link href="../asset/css/bootstrap-responsive.css" rel="stylesheet">
<link href="../asset/css/codemirror.css" rel="stylesheet">
<link href="../asset/css/monokai.css" rel="stylesheet">
<link href="../asset/css/echartsHome.css" rel="stylesheet">
<link rel="shortcut icon" href="../asset/ico/favicon.png">
</head>
<body>
<!-- NAVBAR
================================================== -->
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="../../index.html">ECharts</a>
<div class="nav-collapse collapse">
<a id="forkme_banner" href="https://github.com/ecomfe/echarts">View on GitHub</a>
<ul class="nav">
<li><a href="../../index.html"><i class="icon-home icon-white"></i> Home</a></li>
<li class="active"><a href="../example.html" class="active">Example</a></li>
<li><a href="../doc.html" >API &amp; Doc</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-download-alt icon-white"></i>Download <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a id="last-release-link" href=""> </a></li>
<li><a href="https://github.com/ecomfe/echarts/archive/master.zip">ZIP (Latest)</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Link <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://github.com/ecomfe" target="_blank">Ecom-FE</a></li>
<li><a href="http://fe.baidu.com/doc/ecom/tech/topic/dv/index.html" target="_blank">Data Visualization</a></li>
<li class="divider"></li>
<!--li class="nav-header">Library</li-->
<li><a href="http://ecomfe.github.io/zrender/index.html" target="_blank">ZRender</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!-- /.container -->
</div><!-- /.navbar-inner -->
</div><!-- /.navbar-wrapper -->
<div class="container-fluid">
<div class="row-fluid">
<div id="sidebar-code" class="span4">
<div class="well sidebar-nav">
<div class="nav-header"><a href="#" onclick="autoResize()" class="icon-resize-full" id ="icon-resize" ></a>option</div>
<textarea id="code" name="code">
var nodes = [];
var links = [];
var constMaxDepth = 2;
var constMaxChildren = 7;
var constMinChildren = 4;
var constMaxRadius = 10;
var constMinRadius = 2;
function rangeRandom(min, max) {
return Math.random() * (max - min) + min;
}
function createRandomNode(depth) {
var node = {
name : 'NODE_' + nodes.length,
value : rangeRandom(constMinRadius, constMaxRadius),
// Custom properties
id : nodes.length,
depth : depth,
category : depth === constMaxDepth ? 0 : 1
}
nodes.push(node);
return node;
}
function forceMockThreeData() {
var depth = 0;
var rootNode = {
name : 'ROOT',
value : rangeRandom(constMinRadius, constMaxRadius),
// Custom properties
id : 0,
depth : 0,
category : 2
}
nodes.push(rootNode);
function mock(parentNode, depth) {
var nChildren = Math.round(rangeRandom(constMinChildren, constMaxChildren));
for (var i = 0; i < nChildren; i++) {
var childNode = createRandomNode(depth);
links.push({
source : parentNode.id,
target : childNode.id,
weight : 1
});
if (depth < constMaxDepth) {
mock(childNode, depth + 1);
}
}
}
mock(rootNode, 0);
}
forceMockThreeData();
option = {
title : {
text: 'Force',
subtext: 'Force-directed tree',
x:'right',
y:'bottom'
},
tooltip : {
trigger: 'item',
formatter: '{a} : {b}'
},
legend: {
x: 'left',
data:['叶子节点','非叶子节点', '根节点']
},
series : [
{
type:'force',
name : "Force tree",
categories : [
{
name: '叶子节点',
itemStyle: {
normal: {
color : '#ff7f50'
}
}
},
{
name: '非叶子节点',
itemStyle: {
normal: {
color : '#6f57bc'
}
}
},
{
name: '根节点',
itemStyle: {
normal: {
color : '#af0000'
}
}
},
],
itemStyle: {
normal: {
label: {
show: false
},
nodeStyle : {
brushType : 'both',
strokeColor : 'rgba(255,215,0,0.6)',
lineWidth : 1
}
}
},
minRadius : constMinRadius,
maxRadius : constMaxRadius,
density : 1,
attractiveness: 1.2,
nodes : nodes,
links : links
}
]
};
</textarea>
</div><!--/.well -->
</div><!--/span-->
<div id="graphic" class="span8">
<div id="main" class="main"></div>
<div>
<button onclick="refresh(true)">Refresh ~</button>
<span id='wrong-message' style="color:red"></span>
</div>
</div><!--/span-->
</div><!--/row-->
<hr>
<!-- FOOTER -->
<footer>
<p class="pull-right"><a href="#">Back to top</a></p>
<p>&copy; 2014 <a href="http://efe.baidu.com" target="_blank">EFE</a> &middot; <a href="https://github.com/ecomfe/echarts/blob/master/LICENSE.txt" target="_blank">License</a> &middot; <a href="../changelog.html" target="_blank">Changelog</a></p>
</footer>
</div><!--/.fluid-container-->
<script src="../asset/js/jquery.js"></script>
<script src="../asset/js/bootstrap-transition.js"></script>
<script src="../asset/js/bootstrap-alert.js"></script>
<script src="../asset/js/bootstrap-modal.js"></script>
<script src="../asset/js/bootstrap-dropdown.js"></script>
<script src="../asset/js/bootstrap-scrollspy.js"></script>
<script src="../asset/js/bootstrap-tab.js"></script>
<script src="../asset/js/bootstrap-tooltip.js"></script>
<script src="../asset/js/bootstrap-popover.js"></script>
<script src="../asset/js/bootstrap-button.js"></script>
<script src="../asset/js/bootstrap-collapse.js"></script>
<script src="../asset/js/bootstrap-carousel.js"></script>
<script src="../asset/js/bootstrap-typeahead.js"></script>
<script src="../asset/js/echartsExample.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ECharts</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="ECharts">
<meta name="author" content="linzhifeng@baidu.com">
<script src="../asset/js/esl/esl.js"></script>
<script src="../asset/js/codemirror.js"></script>
<script src="../asset/js/javascript.js"></script>
<link href="../asset/css/bootstrap.css" rel="stylesheet">
<link href="../asset/css/bootstrap-responsive.css" rel="stylesheet">
<link href="../asset/css/codemirror.css" rel="stylesheet">
<link href="../asset/css/monokai.css" rel="stylesheet">
<link href="../asset/css/echartsHome.css" rel="stylesheet">
<link rel="shortcut icon" href="../asset/ico/favicon.png">
</head>
<body>
<!-- NAVBAR
================================================== -->
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="../../index.html">ECharts</a>
<div class="nav-collapse collapse">
<a id="forkme_banner" href="https://github.com/ecomfe/echarts">View on GitHub</a>
<ul class="nav">
<li><a href="../../index.html"><i class="icon-home icon-white"></i> Home</a></li>
<li class="active"><a href="../example.html" class="active">Example</a></li>
<li><a href="../doc.html" >API &amp; Doc</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-download-alt icon-white"></i>Download <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a id="last-release-link" href=""> </a></li>
<li><a href="https://github.com/ecomfe/echarts/archive/master.zip">ZIP (Latest)</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Link <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://github.com/ecomfe" target="_blank">Ecom-FE</a></li>
<li><a href="http://fe.baidu.com/doc/ecom/tech/topic/dv/index.html" target="_blank">Data Visualization</a></li>
<li class="divider"></li>
<!--li class="nav-header">Library</li-->
<li><a href="http://ecomfe.github.io/zrender/index.html" target="_blank">ZRender</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!-- /.container -->
</div><!-- /.navbar-inner -->
</div><!-- /.navbar-wrapper -->
<div class="container-fluid">
<div class="row-fluid">
<div id="sidebar-code" class="span4">
<div class="well sidebar-nav">
<div class="nav-header"><a href="#" onclick="autoResize()" class="icon-resize-full" id ="icon-resize" ></a>option</div>
<textarea id="code" name="code">
var nodes = [];
var links = [];
var constMaxDepth = 2;
var constMaxChildren = 7;
var constMinChildren = 4;
var constMaxRadius = 10;
var constMinRadius = 2;
function rangeRandom(min, max) {
return Math.random() * (max - min) + min;
}
function createRandomNode(depth, parentNode) {
var node = {
name : 'NODE_' + nodes.length,
value : rangeRandom(constMinRadius, constMaxRadius),
// Custom properties
id : nodes.length,
depth : depth,
category : depth === constMaxDepth ? 0 : 1,
__parentNode__ : parentNode ? parentNode.id : -1,
__children__ : [],
__collapsed__ : false
}
nodes.push(node);
return node;
}
function forceMockThreeData() {
var depth = 0;
var rootNode = createRandomNode(0);
rootNode.name = 'ROOT';
rootNode.category = 2;
function mock(parentNode, depth) {
var nChildren = Math.round(rangeRandom(constMinChildren, constMaxChildren));
for (var i = 0; i < nChildren; i++) {
var childNode = createRandomNode(depth, parentNode);
links.push({
source : parentNode.id,
target : childNode.id,
weight : 1
});
parentNode.__children__.push(childNode.id);
if (depth < constMaxDepth) {
mock(childNode, depth + 1);
}
}
}
mock(rootNode, 0);
}
forceMockThreeData();
option = {
title : {
text: 'Force',
subtext: 'Node collapse example',
x:'right',
y:'bottom'
},
tooltip : {
trigger: 'item',
formatter: '{a} : {b}'
},
legend: {
x: 'left',
data:['叶子节点','非叶子节点', '根节点']
},
series : [
{
type:'force',
name : "Force tree",
categories : [
{
name: '叶子节点',
itemStyle: {
normal: {
color : '#ff7f50'
}
}
},
{
name: '非叶子节点',
itemStyle: {
normal: {
color : '#6f57bc'
}
}
},
{
name: '根节点',
itemStyle: {
normal: {
color : '#af0000'
}
}
},
],
itemStyle: {
normal: {
label: {
show: false
},
nodeStyle : {
brushType : 'both',
strokeColor : 'rgba(255,215,0,0.6)',
lineWidth : 1
}
}
},
minRadius : constMinRadius,
maxRadius : constMaxRadius,
density : 1,
attractiveness: 1.2,
nodes : nodes,
links : links
}
]
};
function isAscendant(node1, node2) {
var parent = nodes[node2.__parentNode__];
while(parent) {
if (parent.id === node1.id) {
return true;
}
parent = nodes[parent.__parentNode__];
}
return false;
}
function addChildrenToChart(node) {
for (var i = 0; i < node.__children__.length; i++) {
var childNode = nodes[node.__children__[i]];
childNode.ignore = false;
addChildrenToChart(childNode);
}
}
var ecConfig = require('echarts/config');
function focus(param) {
var data = param.data;
if (
data.source !== undefined
&& data.target !== undefined
) {
} else { // 点击的是点
var targetNode = nodes[data.id];
if (!targetNode.__collapsed__) {
option.series[0].nodes = nodes.map(function(node) {
node.ignore = isAscendant(data, node);
return node;
});
} else {
addChildrenToChart(targetNode);
}
targetNode.__collapsed__ = ! targetNode.__collapsed__;
myChart.setOption(option, true);
}
}
myChart.on(ecConfig.EVENT.CLICK, focus);
</textarea>
</div><!--/.well -->
</div><!--/span-->
<div id="graphic" class="span8">
<div id="main" class="main"></div>
<div>
<button onclick="refresh(true)">Refresh ~</button>
<span id='wrong-message' style="color:red"></span>
</div>
</div><!--/span-->
</div><!--/row-->
<hr>
<!-- FOOTER -->
<footer>
<p class="pull-right"><a href="#">Back to top</a></p>
<p>&copy; 2014 <a href="http://efe.baidu.com" target="_blank">EFE</a> &middot; <a href="https://github.com/ecomfe/echarts/blob/master/LICENSE.txt" target="_blank">License</a> &middot; <a href="../changelog.html" target="_blank">Changelog</a></p>
</footer>
</div><!--/.fluid-container-->
<script src="../asset/js/jquery.js"></script>
<script src="../asset/js/bootstrap-transition.js"></script>
<script src="../asset/js/bootstrap-alert.js"></script>
<script src="../asset/js/bootstrap-modal.js"></script>
<script src="../asset/js/bootstrap-dropdown.js"></script>
<script src="../asset/js/bootstrap-scrollspy.js"></script>
<script src="../asset/js/bootstrap-tab.js"></script>
<script src="../asset/js/bootstrap-tooltip.js"></script>
<script src="../asset/js/bootstrap-popover.js"></script>
<script src="../asset/js/bootstrap-button.js"></script>
<script src="../asset/js/bootstrap-collapse.js"></script>
<script src="../asset/js/bootstrap-carousel.js"></script>
<script src="../asset/js/bootstrap-typeahead.js"></script>
<script src="../asset/js/echartsExample.js"></script>
</body>
</html>
\ No newline at end of file
......@@ -89,19 +89,24 @@ option = {
x : 'left'
},
series : (function(){
//webkitDepData has been required and defined in webkit-dep.js
webkitDepData.minRadius = 5;
webkitDepData.maxRadius = 8;
webkitDepData.density = 1.1;
webkitDepData.attractiveness = 1.1;
webkitDepData.itemStyle = {
normal : {
linkStyle : {
opacity : 0.5
// If data have been loaded
if (webkitDepData) {
//webkitDepData has been required and defined in webkit-dep.js
webkitDepData.minRadius = 5;
webkitDepData.maxRadius = 8;
webkitDepData.density = 1.1;
webkitDepData.attractiveness = 1.1;
webkitDepData.itemStyle = {
normal : {
linkStyle : {
opacity : 0.5
}
}
}
return [webkitDepData];
} else {
return [];
}
return [webkitDepData];
})()
};
</textarea>
......@@ -140,6 +145,22 @@ option = {
var webkitDepData;
require(['webkit-dep'], function(wd) {
webkitDepData = wd;
//webkitDepData has been required and defined in webkit-dep.js
webkitDepData.minRadius = 5;
webkitDepData.maxRadius = 8;
webkitDepData.density = 1.1;
webkitDepData.attractiveness = 1.1;
webkitDepData.itemStyle = {
normal : {
linkStyle : {
opacity : 0.5
}
}
}
// Echarts have been loaded
if (typeof(echarts) !== 'undefined') {
refresh();
}
})
</script>
<script src="../asset/js/echartsExample.js"></script>
......
......@@ -13,6 +13,10 @@ define(function(require) {
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame
|| function(func){setTimeout(func, 16);};
// 保存节点的位置,改变数据时能够有更好的动画效果
var nodeInitialPos = {};
/**
* 构造函数
* @param {Object} messageCenter echart消息中心
......@@ -199,6 +203,9 @@ define(function(require) {
if (!node) {
return;
}
if (node.ignore) {
return;
}
if (self.selectedMap[node.category]) {
filteredNodeMap[idx] = cursor++;
return true;
......@@ -256,15 +263,18 @@ define(function(require) {
var x, y;
var r = radius[i];
var random = _randomInSquare(
viewportWidth/2, viewportHeight/2, initSize
);
x = typeof(node.initial) === 'undefined'
? random.x
: node.initial[0];
y = typeof(node.initial) === 'undefined'
? random.y
: node.initial[1];
var initPos;
if (node.initial !== undefined) {
initPos = node.initial;
} else if (nodeInitialPos[node.name] !== undefined) {
initPos = nodeInitialPos[node.name];
} else {
initPos = _randomInSquare(
viewportWidth/2, viewportHeight/2, initSize
);
}
var x = initPos[0];
var y = initPos[1];
// 初始化位置
nodePositions[i] = vec2.create(x, y);
nodePrePositions[i] = vec2.create(x, y);
......@@ -572,12 +582,18 @@ define(function(require) {
var velocity = [];
// 计算位置(verlet积分)
for (var i = 0, l = nodePositions.length; i < l; i++) {
var name = filteredNodes[i].name;
if (filteredNodes[i].fixed) {
// 拖拽同步
vec2.set(nodePositions[i], mouseX, mouseY);
vec2.set(nodePrePositions[i], mouseX, mouseY);
vec2.set(nodeShapes[i].position, mouseX, mouseY);
vec2.set(filteredNodes[i].initial, mouseX, mouseY);
if (filteredNodes[i].initial !== undefined) {
vec2.set(filteredNodes[i].initial, mouseX, mouseY);
}
if (nodeInitialPos[name] !== undefined) {
vec2.set(nodeInitialPos[name], mouseX, mouseY);
}
continue;
}
var p = nodePositions[i];
......@@ -599,10 +615,17 @@ define(function(require) {
vec2.add(p, p, velocity);
vec2.copy(nodeShapes[i].position, p);
if (filteredNodes[i].initial === undefined) {
filteredNodes[i].initial = vec2.create();
if (name) {
if (nodeInitialPos[name] === undefined) {
nodeInitialPos[name] = vec2.create();
}
vec2.copy(nodeInitialPos[name], p);
} else {
if (filteredNodes[i].initial === undefined) {
filteredNodes[i].initial = vec2.create();
}
vec2.copy(filteredNodes[i].initial, p);
}
vec2.copy(filteredNodes[i].initial, p);
// if(isNaN(p[0]) || isNaN(p[1])){
// throw new Error('NaN');
......@@ -744,18 +767,18 @@ define(function(require) {
function _randomInCircle(x, y, radius) {
var theta = Math.random() * Math.PI * 2;
var r = radius * Math.random();
return {
x : Math.cos(theta) * r + x,
y : Math.sin(theta) * r + y
};
return [
Math.cos(theta) * r + x,
Math.sin(theta) * r + y
];
}
*/
function _randomInSquare(x, y, size) {
return {
x : (Math.random() - 0.5) * size + x,
y : (Math.random() - 0.5) * size + y
};
return [
(Math.random() - 0.5) * size + x,
(Math.random() - 0.5) * size + y
];
}
function _filter(array, callback){
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册