Add diff graph

This commit is contained in:
Jackson Tian 2012-10-28 06:12:37 +08:00
parent 5cc1abb3f5
commit 1ec6b6b28a
3 changed files with 245 additions and 0 deletions

55
example/diff/data.txt Normal file
View File

@ -0,0 +1,55 @@
exports.process = function (folder, ignoresList, callback) {
if (!callback) {
callback = ignoresList;
ignoresList = ignores;
}
var list = [];
var walker = new Walker();
var ignoresReg = new RegExp('\/(' + ignoresList.join('|') + ')\/', "ig");
walker.on('file', function (filename) {
if (ignoresReg.test(filename)) {
return;
}
if (path.extname(filename) === '.js') {
list = list.concat(exports.parse(filename));
}
});
walker.on('error', function (err) {
walker.removeAllListeners('error');
callback(err);
});
walker.on('end', function () {
callback(null, list);
});
walker.walk(folder);
};
exports.version = require('../package.json').version;
_________________
exports.process = function (folder, ignoresList, callback) {
if (!callback) {
callback = ignoresList;
ignoresList = ignores;
}
var list = [];
var walker = new Walker();
var ignoresReg = new RegExp('\/(' + ignoresList.join('|') + ')\/', "ig");
walker.on('file', function (filename) {
if (filename.match(ignoresReg)) {
return;
}
if (path.extname(filename) === '.js') {
list = list.concat(exports.parse(filename));
}
});
walker.on('error', function (err) {
walker.removeAllListeners('error');
callback(err);
});
walker.on('end', function () {
callback(null, list);
});
walker.walk(folder);
};
exports.version = require('../package.json').version;

79
example/diff/diff.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Diff Graph</title>
<script src="../../deps/compatible.js"> </script>
<script src="../../deps/d3.js"></script>
<script src="../../deps/d3.csv.js"></script>
<script src="../../deps/d3.layout.js"></script>
<script src="../../deps/raphael.js"></script>
<script src="../../deps/eventproxy.js"></script>
<script src="../../deps/underscore-1.4.2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<!-- chord -->
<script src="../../deps/seajs/sea.js"></script>
<script type="text/javascript">
seajs.config({
alias: {
'DataV': '/lib/datav.js',
'Diff': '/lib/charts/diff.js'
}
});
</script>
<style type="text/css">
#chart {
border-top: 1px dashed #F00;
border-bottom: 1px dashed #F00;
padding-left: 20px;
}
</style>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
seajs.use(["Diff", "DataV"], function (Diff, DataV) {
// DataV.changeTheme("datav");
// var a = [1, 2, 3, 4, 5, 6, 7, 8, 99, 10];
// var b = [7, 5, 6, 30, 8, 9, 10, 11, 12, 13];
var a = [ ' 3211617953 ',
' 18090332173 ',
' 1392823209 ',
' 12937446809 ',
' 15789190002 ',
' 2444376327 ',
' 17009143172 ',
' 12478136878 ',
' 1277304359 ',
' 15662173046 ' ].map(function (item) {
return item.trim();
});
var b = [ ' 15789190002 ',
' 18090332173 ',
' 3211617953 ',
' 17009143172 ',
' 12478136878 ',
' 15662173046 ',
' 1392823209 ',
' 19639284542 ',
' 12937446809 ',
' 2444376327 ' ].map(function (item) {
return item.trim();
});
$.get('data.txt', function (text) {
var data = text.split('_________________').map(function (block) {
return block.split(/\n/ig);
});
var diff = new Diff("chart");
diff.setSource(data[0], data[1]);
diff.render();
});
});
</script>
</body>
</html>

111
lib/charts/diff.js Normal file
View File

@ -0,0 +1,111 @@
/*global Raphael, d3, $, define */
/*!
* Diff的兼容性定义
*/
;(function (name, definition) {
if (typeof define === 'function') { // Module
define(definition);
} else { // Assign to common namespaces or simply the global object (window)
this[name] = definition(function (id) {
return this[id];
});
}
})('Diff', function (require) {
var DataV = require('DataV');
/**
* 构造函数
* @param {Object} node 表示在html的哪个容器中绘制该组件
* @param {Object} options 为用户自定义的组件的属性比如画布大小
*/
var Diff = DataV.extend(DataV.Chart, {
type: "Diff",
initialize: function (node, options) {
this.node = this.checkContainer(node);
//图的大小设置
this.defaults.width = 900;
this.defaults.height = 800;
//设置用户指定的属性
this.setOptions(options);
//创建画布
this.createCanvas();
}
});
/**
* 创建画布
*/
Diff.prototype.createCanvas = function () {
this.canvas = new Raphael(this.node, this.defaults.width, this.defaults.height);
};
/**
* 绘制弦图
*/
Diff.prototype.render = function () {
this.layout();
};
// 计算顺序的相似度
var diffMap = function (list1, list2) {
var map = [];
var hit = 0;
var lastIndex = -1;
for (var i = 0; i < list1.length; i++) {
var index = _.indexOf(list2, list1[i]);
if (index === -1) {
continue;
} else {
if (index > lastIndex) {
lastIndex = index;
map.push([i, index]);
}
hit++;
}
}
console.log(map);
console.log(map.length / list1.length);
console.log(hit / list1.length);
return map;
};
/**
*对原始数据进行处理
* @param {Array} table 将要被绘制成饼图的二维表数据
*/
Diff.prototype.setSource = function (table1, table2) {
this.rawData = [table1, table2];
this.diffMap = diffMap(table1, table2);
};
/**
*创建chord布局
*/
Diff.prototype.layout = function () {
var that = this;
var canvas = that.canvas;
var paddingLeft = 10;
var paddingTop = 10;
var height = 20;
var distance = 50;
var width = (this.defaults.width - 2 * paddingLeft - distance) / 2;
for (var j = 0, k = this.rawData.length; j < k; j++) {
var maped = _.pluck(this.diffMap, j);
for (var i = 0, l = this.rawData[j].length; i < l; i++) {
canvas.rect(paddingLeft + j * (width + distance), paddingTop + height * i, width, height).attr({fill: _.indexOf(maped, i) !== -1 ? "#00ff00" : "#ff0000"});
canvas.text(paddingLeft + j * (width + distance), paddingTop + height * i + height / 2, this.rawData[j][i]).attr({'text-anchor': 'start'});
}
}
for (var i = 0, l = this.diffMap.length; i < l; i++) {
var line = this.diffMap[i];
canvas.path("M" + (paddingLeft + width) + ' ' + (paddingTop + height * line[0] + height / 2) + "L" + (paddingLeft + width + distance) + " " + (paddingTop + height * line[1] + height / 2)).attr({stroke: '#00ff00'});
}
};
return Diff;
});