提交 966c9aa5 编写于 作者: J Jason Park

Merge branch 'temp' into gh-pages

const {
Array2D,
Array2DTracer
Array2D,
Array2DTracer
} = require('./array2d');
function Array1DTracer() {
return Array2DTracer.apply(this, arguments);
return Array2DTracer.apply(this, arguments);
}
Array1DTracer.prototype = $.extend(true, Object.create(Array2DTracer.prototype), {
constructor: Array1DTracer,
_notify: function(idx, v) {
Array2DTracer.prototype._notify.call(this, 0, idx, v);
return this;
},
_denotify: function(idx) {
Array2DTracer.prototype._denotify.call(this, 0, idx);
return this;
},
_select: function(s, e) {
if (e === undefined) {
Array2DTracer.prototype._select.call(this, 0, s);
} else {
Array2DTracer.prototype._selectRow.call(this, 0, s, e);
}
return this;
},
_deselect: function(s, e) {
if (e === undefined) {
Array2DTracer.prototype._deselect.call(this, 0, s);
} else {
Array2DTracer.prototype._deselectRow.call(this, 0, s, e);
}
return this;
},
setData: function(D) {
return Array2DTracer.prototype.setData.call(this, [D]);
constructor: Array1DTracer,
name: "Array1DTracer",
_notify: function (idx, v) {
Array2DTracer.prototype._notify.call(this, 0, idx, v);
return this;
},
_denotify: function (idx) {
Array2DTracer.prototype._denotify.call(this, 0, idx);
return this;
},
_select: function (s, e) {
if (e === undefined) {
Array2DTracer.prototype._select.call(this, 0, s);
} else {
Array2DTracer.prototype._selectRow.call(this, 0, s, e);
}
return this;
},
_deselect: function (s, e) {
if (e === undefined) {
Array2DTracer.prototype._deselect.call(this, 0, s);
} else {
Array2DTracer.prototype._deselectRow.call(this, 0, s, e);
}
return this;
},
setData: function (D) {
return Array2DTracer.prototype.setData.call(this, [D]);
}
});
var Array1D = {
random: function(N, min, max) {
return Array2D.random(1, N, min, max)[0];
},
randomSorted: function(N, min, max) {
return Array2D.randomSorted(1, N, min, max)[0];
}
random: function (N, min, max) {
return Array2D.random(1, N, min, max)[0];
},
randomSorted: function (N, min, max) {
return Array2D.randomSorted(1, N, min, max)[0];
}
};
module.exports = {
Array1D,
Array1DTracer
Array1D,
Array1DTracer
};
\ No newline at end of file
const Tracer = require('./tracer');
const {
refineByType
refineByType
} = require('../tracer_manager/util');
function Array2DTracer() {
if (Tracer.apply(this, arguments)) {
Array2DTracer.prototype.init.call(this);
return true;
}
return false;
if (Tracer.apply(this, arguments)) {
Array2DTracer.prototype.init.call(this);
return true;
}
return false;
}
Array2DTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
constructor: Array2DTracer,
init: function() {
this.$table = this.capsule.$table = $('<div class="mtbl-table">');
this.$container.append(this.$table);
},
_notify: function(x, y, v) {
this.manager.pushStep(this.capsule, {
type: 'notify',
x: x,
y: y,
v: v
});
return this;
},
_denotify: function(x, y) {
this.manager.pushStep(this.capsule, {
type: 'denotify',
x: x,
y: y
});
return this;
},
_select: function(sx, sy, ex, ey) {
this.pushSelectingStep('select', null, arguments);
return this;
},
_selectRow: function(x, sy, ey) {
this.pushSelectingStep('select', 'row', arguments);
return this;
},
_selectCol: function(y, sx, ex) {
this.pushSelectingStep('select', 'col', arguments);
return this;
},
_deselect: function(sx, sy, ex, ey) {
this.pushSelectingStep('deselect', null, arguments);
return this;
},
_deselectRow: function(x, sy, ey) {
this.pushSelectingStep('deselect', 'row', arguments);
return this;
},
_deselectCol: function(y, sx, ex) {
this.pushSelectingStep('deselect', 'col', arguments);
return this;
},
_separate: function(x, y) {
this.manager.pushStep(this.capsule, {
type: 'separate',
x: x,
y: y
});
return this;
},
_separateRow: function(x) {
this._separate(x, -1);
return this;
},
_separateCol: function(y) {
this._separate(-1, y);
return this;
},
_deseparate: function(x, y) {
this.manager.pushStep(this.capsule, {
type: 'deseparate',
x: x,
y: y
});
return this;
},
_deseparateRow: function(x) {
this._deseparate(x, -1);
return this;
},
_deseparateCol: function(y) {
this._deseparate(-1, y);
return this;
},
pushSelectingStep: function() {
var args = Array.prototype.slice.call(arguments);
var type = args.shift();
var mode = args.shift();
args = Array.prototype.slice.call(args.shift());
var coord;
switch (mode) {
case 'row':
coord = {
x: args[0],
sy: args[1],
ey: args[2]
};
break;
case 'col':
coord = {
y: args[0],
sx: args[1],
ex: args[2]
};
break;
default:
if (args[2] === undefined && args[3] === undefined) {
coord = {
x: args[0],
y: args[1]
};
} else {
coord = {
sx: args[0],
sy: args[1],
ex: args[2],
ey: args[3]
};
}
}
var step = {
type: type
constructor: Array2DTracer,
name: 'Array2DTracer',
init: function () {
this.$table = this.capsule.$table = $('<div class="mtbl-table">');
this.$container.append(this.$table);
},
_notify: function (x, y, v) {
this.manager.pushStep(this.capsule, {
type: 'notify',
x: x,
y: y,
v: v
});
return this;
},
_denotify: function (x, y) {
this.manager.pushStep(this.capsule, {
type: 'denotify',
x: x,
y: y
});
return this;
},
_select: function (sx, sy, ex, ey) {
this.pushSelectingStep('select', null, arguments);
return this;
},
_selectRow: function (x, sy, ey) {
this.pushSelectingStep('select', 'row', arguments);
return this;
},
_selectCol: function (y, sx, ex) {
this.pushSelectingStep('select', 'col', arguments);
return this;
},
_deselect: function (sx, sy, ex, ey) {
this.pushSelectingStep('deselect', null, arguments);
return this;
},
_deselectRow: function (x, sy, ey) {
this.pushSelectingStep('deselect', 'row', arguments);
return this;
},
_deselectCol: function (y, sx, ex) {
this.pushSelectingStep('deselect', 'col', arguments);
return this;
},
_separate: function (x, y) {
this.manager.pushStep(this.capsule, {
type: 'separate',
x: x,
y: y
});
return this;
},
_separateRow: function (x) {
this._separate(x, -1);
return this;
},
_separateCol: function (y) {
this._separate(-1, y);
return this;
},
_deseparate: function (x, y) {
this.manager.pushStep(this.capsule, {
type: 'deseparate',
x: x,
y: y
});
return this;
},
_deseparateRow: function (x) {
this._deseparate(x, -1);
return this;
},
_deseparateCol: function (y) {
this._deseparate(-1, y);
return this;
},
pushSelectingStep: function () {
var args = Array.prototype.slice.call(arguments);
var type = args.shift();
var mode = args.shift();
args = Array.prototype.slice.call(args.shift());
var coord;
switch (mode) {
case 'row':
coord = {
x: args[0],
sy: args[1],
ey: args[2]
};
$.extend(step, coord);
this.manager.pushStep(this.capsule, step);
},
processStep: function(step, options) {
switch (step.type) {
case 'notify':
if (step.v === 0 || step.v) {
var $row = this.$table.find('.mtbl-row').eq(step.x);
var $col = $row.find('.mtbl-col').eq(step.y);
$col.text(refineByType(step.v));
}
case 'denotify':
case 'select':
case 'deselect':
var colorClass = step.type == 'select' || step.type == 'deselect' ? this.colorClass.selected : this.colorClass.notified;
var addClass = step.type == 'select' || step.type == 'notify';
var sx = step.sx;
var sy = step.sy;
var ex = step.ex;
var ey = step.ey;
if (sx === undefined) sx = step.x;
if (sy === undefined) sy = step.y;
if (ex === undefined) ex = step.x;
if (ey === undefined) ey = step.y;
this.paintColor(sx, sy, ex, ey, colorClass, addClass);
break;
case 'separate':
this.deseparate(step.x, step.y);
this.separate(step.x, step.y);
break;
case 'deseparate':
this.deseparate(step.x, step.y);
break;
default:
Tracer.prototype.processStep.call(this, step, options);
break;
case 'col':
coord = {
y: args[0],
sx: args[1],
ex: args[2]
};
break;
default:
if (args[2] === undefined && args[3] === undefined) {
coord = {
x: args[0],
y: args[1]
};
} else {
coord = {
sx: args[0],
sy: args[1],
ex: args[2],
ey: args[3]
};
}
},
setData: function(D) {
this.viewX = this.viewY = 0;
this.paddingH = 6;
this.paddingV = 3;
this.fontSize = 16;
if (Tracer.prototype.setData.apply(this, arguments)) {
this.$table.find('.mtbl-row').each(function(i) {
$(this).find('.mtbl-col').each(function(j) {
$(this).text(refineByType(D[i][j]));
});
});
return true;
}
var step = {
type: type
};
$.extend(step, coord);
this.manager.pushStep(this.capsule, step);
},
processStep: function (step, options) {
switch (step.type) {
case 'notify':
if (step.v === 0 || step.v) {
var $row = this.$table.find('.mtbl-row').eq(step.x);
var $col = $row.find('.mtbl-col').eq(step.y);
$col.text(refineByType(step.v));
}
case 'denotify':
case 'select':
case 'deselect':
var colorClass = step.type == 'select' || step.type == 'deselect' ? this.colorClass.selected : this.colorClass.notified;
var addClass = step.type == 'select' || step.type == 'notify';
var sx = step.sx;
var sy = step.sy;
var ex = step.ex;
var ey = step.ey;
if (sx === undefined) sx = step.x;
if (sy === undefined) sy = step.y;
if (ex === undefined) ex = step.x;
if (ey === undefined) ey = step.y;
this.paintColor(sx, sy, ex, ey, colorClass, addClass);
break;
case 'separate':
this.deseparate(step.x, step.y);
this.separate(step.x, step.y);
break;
case 'deseparate':
this.deseparate(step.x, step.y);
break;
default:
Tracer.prototype.processStep.call(this, step, options);
}
},
setData: function (D) {
this.viewX = this.viewY = 0;
this.paddingH = 6;
this.paddingV = 3;
this.fontSize = 16;
this.$table.empty();
for (var i = 0; i < D.length; i++) {
var $row = $('<div class="mtbl-row">');
this.$table.append($row);
for (var j = 0; j < D[i].length; j++) {
var $col = $('<div class="mtbl-col">')
.css(this.getCellCss())
.text(refineByType(D[i][j]));
$row.append($col);
}
}
this.resize();
if (Tracer.prototype.setData.apply(this, arguments)) {
this.$table.find('.mtbl-row').each(function (i) {
$(this).find('.mtbl-col').each(function (j) {
$(this).text(refineByType(D[i][j]));
});
});
return true;
}
this.$table.empty();
for (var i = 0; i < D.length; i++) {
var $row = $('<div class="mtbl-row">');
this.$table.append($row);
for (var j = 0; j < D[i].length; j++) {
var $col = $('<div class="mtbl-col">')
.css(this.getCellCss())
.text(refineByType(D[i][j]));
$row.append($col);
}
}
this.resize();
return false;
},
resize: function() {
Tracer.prototype.resize.call(this);
return false;
},
resize: function () {
Tracer.prototype.resize.call(this);
this.refresh();
},
clear: function() {
Tracer.prototype.clear.call(this);
this.refresh();
},
clear: function () {
Tracer.prototype.clear.call(this);
this.clearColor();
this.deseparateAll();
},
getCellCss: function() {
return {
padding: this.paddingV.toFixed(1) + 'px ' + this.paddingH.toFixed(1) + 'px',
'font-size': this.fontSize.toFixed(1) + 'px'
};
},
refresh: function() {
Tracer.prototype.refresh.call(this);
this.clearColor();
this.deseparateAll();
},
getCellCss: function () {
return {
padding: this.paddingV.toFixed(1) + 'px ' + this.paddingH.toFixed(1) + 'px',
'font-size': this.fontSize.toFixed(1) + 'px'
};
},
refresh: function () {
Tracer.prototype.refresh.call(this);
var $parent = this.$table.parent();
var top = $parent.height() / 2 - this.$table.height() / 2 + this.viewY;
var left = $parent.width() / 2 - this.$table.width() / 2 + this.viewX;
this.$table.css('margin-top', top);
this.$table.css('margin-left', left);
},
mousedown: function(e) {
Tracer.prototype.mousedown.call(this, e);
var $parent = this.$table.parent();
var top = $parent.height() / 2 - this.$table.height() / 2 + this.viewY;
var left = $parent.width() / 2 - this.$table.width() / 2 + this.viewX;
this.$table.css('margin-top', top);
this.$table.css('margin-left', left);
},
mousedown: function (e) {
Tracer.prototype.mousedown.call(this, e);
this.dragX = e.pageX;
this.dragY = e.pageY;
this.dragging = true;
},
mousemove: function(e) {
Tracer.prototype.mousemove.call(this, e);
this.dragX = e.pageX;
this.dragY = e.pageY;
this.dragging = true;
},
mousemove: function (e) {
Tracer.prototype.mousemove.call(this, e);
if (this.dragging) {
this.viewX += e.pageX - this.dragX;
this.viewY += e.pageY - this.dragY;
this.dragX = e.pageX;
this.dragY = e.pageY;
this.refresh();
}
},
mouseup: function(e) {
Tracer.prototype.mouseup.call(this, e);
if (this.dragging) {
this.viewX += e.pageX - this.dragX;
this.viewY += e.pageY - this.dragY;
this.dragX = e.pageX;
this.dragY = e.pageY;
this.refresh();
}
},
mouseup: function (e) {
Tracer.prototype.mouseup.call(this, e);
this.dragging = false;
},
mousewheel: function(e) {
Tracer.prototype.mousewheel.call(this, e);
this.dragging = false;
},
mousewheel: function (e) {
Tracer.prototype.mousewheel.call(this, e);
e.preventDefault();
e = e.originalEvent;
var delta = (e.wheelDelta !== undefined && e.wheelDelta) ||
(e.detail !== undefined && -e.detail);
var weight = 1.01;
var ratio = delta > 0 ? 1 / weight : weight;
if (this.fontSize < 4 && ratio < 1) return;
if (this.fontSize > 40 && ratio > 1) return;
this.paddingV *= ratio;
this.paddingH *= ratio;
this.fontSize *= ratio;
this.$table.find('.mtbl-col').css(this.getCellCss());
this.refresh();
},
paintColor: function(sx, sy, ex, ey, colorClass, addClass) {
for (var i = sx; i <= ex; i++) {
var $row = this.$table.find('.mtbl-row').eq(i);
for (var j = sy; j <= ey; j++) {
var $col = $row.find('.mtbl-col').eq(j);
if (addClass) $col.addClass(colorClass);
else $col.removeClass(colorClass);
}
}
},
clearColor: function() {
this.$table.find('.mtbl-col').removeClass(Object.keys(this.colorClass).join(' '));
},
colorClass: {
selected: 'selected',
notified: 'notified'
},
separate: function(x, y) {
this.$table.find('.mtbl-row').each(function(i) {
var $row = $(this);
if (i == x) {
$row.after($('<div class="mtbl-empty-row">').attr('data-row', i))
}
$row.find('.mtbl-col').each(function(j) {
var $col = $(this);
if (j == y) {
$col.after($('<div class="mtbl-empty-col">').attr('data-col', j));
}
});
});
},
deseparate: function(x, y) {
this.$table.find('[data-row=' + x + ']').remove();
this.$table.find('[data-col=' + y + ']').remove();
},
deseparateAll: function() {
this.$table.find('.mtbl-empty-row, .mtbl-empty-col').remove();
e.preventDefault();
e = e.originalEvent;
var delta = (e.wheelDelta !== undefined && e.wheelDelta) ||
(e.detail !== undefined && -e.detail);
var weight = 1.01;
var ratio = delta > 0 ? 1 / weight : weight;
if (this.fontSize < 4 && ratio < 1) return;
if (this.fontSize > 40 && ratio > 1) return;
this.paddingV *= ratio;
this.paddingH *= ratio;
this.fontSize *= ratio;
this.$table.find('.mtbl-col').css(this.getCellCss());
this.refresh();
},
paintColor: function (sx, sy, ex, ey, colorClass, addClass) {
for (var i = sx; i <= ex; i++) {
var $row = this.$table.find('.mtbl-row').eq(i);
for (var j = sy; j <= ey; j++) {
var $col = $row.find('.mtbl-col').eq(j);
if (addClass) $col.addClass(colorClass);
else $col.removeClass(colorClass);
}
}
},
clearColor: function () {
this.$table.find('.mtbl-col').removeClass(Object.keys(this.colorClass).join(' '));
},
colorClass: {
selected: 'selected',
notified: 'notified'
},
separate: function (x, y) {
this.$table.find('.mtbl-row').each(function (i) {
var $row = $(this);
if (i == x) {
$row.after($('<div class="mtbl-empty-row">').attr('data-row', i))
}
$row.find('.mtbl-col').each(function (j) {
var $col = $(this);
if (j == y) {
$col.after($('<div class="mtbl-empty-col">').attr('data-col', j));
}
});
});
},
deseparate: function (x, y) {
this.$table.find('[data-row=' + x + ']').remove();
this.$table.find('[data-col=' + y + ']').remove();
},
deseparateAll: function () {
this.$table.find('.mtbl-empty-row, .mtbl-empty-col').remove();
}
});
var Array2D = {
random: function(N, M, min, max) {
if (!N) N = 10;
if (!M) M = 10;
if (min === undefined) min = 1;
if (max === undefined) max = 9;
var D = [];
for (var i = 0; i < N; i++) {
D.push([]);
for (var j = 0; j < M; j++) {
D[i].push((Math.random() * (max - min + 1) | 0) + min);
}
}
return D;
},
randomSorted: function(N, M, min, max) {
return this.random(N, M, min, max).map(function(arr) {
return arr.sort(function(a, b) {
return a - b;
});
});
random: function (N, M, min, max) {
if (!N) N = 10;
if (!M) M = 10;
if (min === undefined) min = 1;
if (max === undefined) max = 9;
var D = [];
for (var i = 0; i < N; i++) {
D.push([]);
for (var j = 0; j < M; j++) {
D[i].push((Math.random() * (max - min + 1) | 0) + min);
}
}
return D;
},
randomSorted: function (N, M, min, max) {
return this.random(N, M, min, max).map(function (arr) {
return arr.sort(function (a, b) {
return a - b;
});
});
}
};
module.exports = {
Array2D,
Array2DTracer
Array2D,
Array2DTracer
};
\ No newline at end of file
const Tracer = require('./tracer');
function ChartTracer() {
if (Tracer.apply(this, arguments)) {
ChartTracer.prototype.init.call(this, arguments);
return true;
}
return false;
if (Tracer.apply(this, arguments)) {
ChartTracer.prototype.init.call(this, arguments);
return true;
}
return false;
}
ChartTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
constructor: ChartTracer,
init: function() {
this.$wrapper = this.capsule.$wrapper = $('<canvas id="chart">');
this.$container.append(this.$wrapper);
},
setData: function(C) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
var tracer = this;
var color = [];
for (var i = 0; i < C.length; i++) color.push('rgba(136, 136, 136, 1)');
var data = {
type: 'bar',
data: {
labels: C.map(String),
datasets: [{
backgroundColor: color,
data: C
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
constructor: ChartTracer,
name: 'ChartTracer',
init: function () {
this.$wrapper = this.capsule.$wrapper = $('<canvas id="chart">');
this.$container.append(this.$wrapper);
},
setData: function (C) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
var tracer = this;
var color = [];
for (var i = 0; i < C.length; i++) color.push('rgba(136, 136, 136, 1)');
var data = {
type: 'bar',
data: {
labels: C.map(String),
datasets: [{
backgroundColor: color,
data: C
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
};
this.chart = this.capsule.chart = new Chart(this.$wrapper, data);
},
_notify: function(s, v) {
this.manager.pushStep(this.capsule, {
type: 'notify',
s: s,
v: v
});
return this;
},
_denotify: function(s) {
this.manager.pushStep(this.capsule, {
type: 'denotify',
s: s
});
return this;
},
_select: function(s, e) {
this.manager.pushStep(this.capsule, {
type: 'select',
s: s,
e: e
});
return this;
},
_deselect: function(s, e) {
this.manager.pushStep(this.capsule, {
type: 'deselect',
s: s,
e: e
});
return this;
},
processStep: function(step, options) {
switch (step.type) {
case 'notify':
if (step.v) {
this.chart.config.data.datasets[0].data[step.s] = step.v;
this.chart.config.data.labels[step.s] = step.v.toString();
}
case 'denotify':
case 'deselect':
var color = step.type == 'denotify' || step.type == 'deselect' ? 'rgba(136, 136, 136, 1)' : 'rgba(255, 0, 0, 1)';
case 'select':
if (color === undefined) var color = 'rgba(0, 0, 255, 1)';
if (step.e !== undefined)
for (var i = step.s; i <= step.e; i++)
this.chart.config.data.datasets[0].backgroundColor[i] = color;
else
this.chart.config.data.datasets[0].backgroundColor[step.s] = color;
this.chart.update();
break;
default:
Tracer.prototype.processStep.call(this, step, options);
}]
}
}
};
this.chart = this.capsule.chart = new Chart(this.$wrapper, data);
},
_notify: function (s, v) {
this.manager.pushStep(this.capsule, {
type: 'notify',
s: s,
v: v
});
return this;
},
_denotify: function (s) {
this.manager.pushStep(this.capsule, {
type: 'denotify',
s: s
});
return this;
},
_select: function (s, e) {
this.manager.pushStep(this.capsule, {
type: 'select',
s: s,
e: e
});
return this;
},
_deselect: function (s, e) {
this.manager.pushStep(this.capsule, {
type: 'deselect',
s: s,
e: e
});
return this;
},
processStep: function (step, options) {
switch (step.type) {
case 'notify':
if (step.v) {
this.chart.config.data.datasets[0].data[step.s] = step.v;
this.chart.config.data.labels[step.s] = step.v.toString();
}
},
case 'denotify':
case 'deselect':
var color = step.type == 'denotify' || step.type == 'deselect' ? 'rgba(136, 136, 136, 1)' : 'rgba(255, 0, 0, 1)';
case 'select':
if (color === undefined) var color = 'rgba(0, 0, 255, 1)';
if (step.e !== undefined)
for (var i = step.s; i <= step.e; i++)
this.chart.config.data.datasets[0].backgroundColor[i] = color;
else
this.chart.config.data.datasets[0].backgroundColor[step.s] = color;
this.chart.update();
break;
default:
Tracer.prototype.processStep.call(this, step, options);
}
}
});
module.exports = ChartTracer;
\ No newline at end of file
const {
DirectedGraph,
DirectedGraphTracer
DirectedGraph,
DirectedGraphTracer
} = require('./directed_graph');
function CoordinateSystemTracer() {
if (DirectedGraphTracer.apply(this, arguments)) {
CoordinateSystemTracer.prototype.init.call(this);
return true;
}
return false;
if (DirectedGraphTracer.apply(this, arguments)) {
CoordinateSystemTracer.prototype.init.call(this);
return true;
}
return false;
}
CoordinateSystemTracer.prototype = $.extend(true, Object.create(DirectedGraphTracer.prototype), {
constructor: CoordinateSystemTracer,
init: function () {
var tracer = this;
constructor: CoordinateSystemTracer,
name: 'CoordinateSystemTracer',
init: function () {
var tracer = this;
this.s.settings({
defaultEdgeType: 'def',
funcEdgesDef: function (edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawEdge(edge, source, target, color, context, settings);
}
});
},
setData: function (C) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.s.settings({
defaultEdgeType: 'def',
funcEdgesDef: function (edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawEdge(edge, source, target, color, context, settings);
}
});
},
setData: function (C) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.graph.clear();
var nodes = [];
var edges = [];
for (var i = 0; i < C.length; i++)
nodes.push({
id: this.n(i),
x: C[i][0],
y: C[i][1],
label: '' + i ,
size: 1,
color: this.color.default
});
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
this.graph.clear();
var nodes = [];
var edges = [];
for (var i = 0; i < C.length; i++)
nodes.push({
id: this.n(i),
x: C[i][0],
y: C[i][1],
label: '' + i,
size: 1,
color: this.color.default
});
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
return false;
},
processStep: function(step, options) {
switch (step.type) {
case 'visit':
case 'leave':
var visit = step.type == 'visit';
var targetNode = this.graph.nodes(this.n(step.target));
var color = visit ? this.color.visited : this.color.left;
targetNode.color = color;
if (step.source !== undefined) {
var edgeId = this.e(step.source, step.target);
if (this.graph.edges(edgeId)) {
var edge = this.graph.edges(edgeId);
edge.color = color;
this.graph.dropEdge(edgeId).addEdge(edge);
} else {
this.graph.addEdge({
id: this.e(step.target, step.source),
source: this.n(step.source),
target: this.n(step.target),
color: color,
size: 1
});
}
}
if (this.logTracer) {
var source = step.source;
if (source === undefined) source = '';
this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);
}
break;
default:
Tracer.prototype.processStep.call(this, step, options);
return false;
},
processStep: function (step, options) {
switch (step.type) {
case 'visit':
case 'leave':
var visit = step.type == 'visit';
var targetNode = this.graph.nodes(this.n(step.target));
var color = visit ? this.color.visited : this.color.left;
targetNode.color = color;
if (step.source !== undefined) {
var edgeId = this.e(step.source, step.target);
if (this.graph.edges(edgeId)) {
var edge = this.graph.edges(edgeId);
edge.color = color;
this.graph.dropEdge(edgeId).addEdge(edge);
} else {
this.graph.addEdge({
id: this.e(step.target, step.source),
source: this.n(step.source),
target: this.n(step.target),
color: color,
size: 1
});
}
}
},
e: function(v1, v2) {
if (v1 > v2) {
var temp = v1;
v1 = v2;
v2 = temp;
if (this.logTracer) {
var source = step.source;
if (source === undefined) source = '';
this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);
}
return 'e' + v1 + '_' + v2;
},
drawOnHover: function(node, context, settings, next) {
var tracer = this;
break;
default:
Tracer.prototype.processStep.call(this, step, options);
}
},
e: function (v1, v2) {
if (v1 > v2) {
var temp = v1;
v1 = v2;
v2 = temp;
}
return 'e' + v1 + '_' + v2;
},
drawOnHover: function (node, context, settings, next) {
var tracer = this;
context.setLineDash([5, 5]);
var nodeIdx = node.id.substring(1);
this.graph.edges().forEach(function(edge) {
var ends = edge.id.substring(1).split("_");
if (ends[0] == nodeIdx) {
var color = '#0ff';
var source = node;
var target = tracer.graph.nodes('n' + ends[1]);
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
} else if (ends[1] == nodeIdx) {
var color = '#0ff';
var source = tracer.graph.nodes('n' + ends[0]);
var target = node;
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
}
});
},
drawEdge: function(edge, source, target, color, context, settings) {
var prefix = settings('prefix') || '',
size = edge[prefix + 'size'] || 1;
context.setLineDash([5, 5]);
var nodeIdx = node.id.substring(1);
this.graph.edges().forEach(function (edge) {
var ends = edge.id.substring(1).split("_");
if (ends[0] == nodeIdx) {
var color = '#0ff';
var source = node;
var target = tracer.graph.nodes('n' + ends[1]);
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
} else if (ends[1] == nodeIdx) {
var color = '#0ff';
var source = tracer.graph.nodes('n' + ends[0]);
var target = node;
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
}
});
},
drawEdge: function (edge, source, target, color, context, settings) {
var prefix = settings('prefix') || '',
size = edge[prefix + 'size'] || 1;
context.strokeStyle = color;
context.lineWidth = size;
context.beginPath();
context.moveTo(
source[prefix + 'x'],
source[prefix + 'y']
);
context.lineTo(
target[prefix + 'x'],
target[prefix + 'y']
);
context.stroke();
}
context.strokeStyle = color;
context.lineWidth = size;
context.beginPath();
context.moveTo(
source[prefix + 'x'],
source[prefix + 'y']
);
context.lineTo(
target[prefix + 'x'],
target[prefix + 'y']
);
context.stroke();
}
});
var CoordinateSystem = {
random: function (N, min, max) {
if (!N) N = 7;
if (!min) min = 1;
if (!max) max = 10;
var C = new Array(N);
for (var i = 0; i < N; i++) C[i] = new Array(2);
for (var i = 0; i < N; i++)
for (var j = 0; j < C[i].length; j++)
C[i][j] = (Math.random() * (max - min + 1) | 0) + min;
return C;
}
random: function (N, min, max) {
if (!N) N = 7;
if (!min) min = 1;
if (!max) max = 10;
var C = new Array(N);
for (var i = 0; i < N; i++) C[i] = new Array(2);
for (var i = 0; i < N; i++)
for (var j = 0; j < C[i].length; j++)
C[i][j] = (Math.random() * (max - min + 1) | 0) + min;
return C;
}
};
module.exports = {
......
此差异已折叠。
const Tracer = require('./tracer');
function LogTracer() {
if (Tracer.apply(this, arguments)) {
LogTracer.prototype.init.call(this);
return true;
}
return false;
if (Tracer.apply(this, arguments)) {
LogTracer.prototype.init.call(this);
return true;
}
return false;
}
LogTracer.prototype = $.extend(true, Object.create(Tracer.prototype), {
constructor: LogTracer,
init: function() {
this.$wrapper = this.capsule.$wrapper = $('<div class="wrapper">');
this.$container.append(this.$wrapper);
},
_print: function(msg) {
this.manager.pushStep(this.capsule, {
type: 'print',
msg: msg
});
return this;
},
processStep: function(step, options) {
switch (step.type) {
case 'print':
this.print(step.msg);
break;
}
},
refresh: function() {
this.scrollToEnd(Math.min(50, this.interval));
},
clear: function() {
Tracer.prototype.clear.call(this);
this.$wrapper.empty();
},
print: function(message) {
this.$wrapper.append($('<span>').append(message + '<br/>'));
},
scrollToEnd: function(duration) {
this.$container.animate({
scrollTop: this.$container[0].scrollHeight
}, duration);
constructor: LogTracer,
name: 'LogTracer',
init: function () {
this.$wrapper = this.capsule.$wrapper = $('<div class="wrapper">');
this.$container.append(this.$wrapper);
},
_print: function (msg) {
this.manager.pushStep(this.capsule, {
type: 'print',
msg: msg
});
return this;
},
processStep: function (step, options) {
switch (step.type) {
case 'print':
this.print(step.msg);
break;
}
},
refresh: function () {
this.scrollToEnd(Math.min(50, this.interval));
},
clear: function () {
Tracer.prototype.clear.call(this);
this.$wrapper.empty();
},
print: function (message) {
this.$wrapper.append($('<span>').append(message + '<br/>'));
},
scrollToEnd: function (duration) {
this.$container.animate({
scrollTop: this.$container[0].scrollHeight
}, duration);
}
});
module.exports = LogTracer;
\ No newline at end of file
const {
toJSON,
fromJSON
toJSON,
fromJSON
} = require('../tracer_manager/util');
function Tracer(name) {
this.module = this.constructor;
this.capsule = this.manager.allocate(this);
$.extend(this, this.capsule);
this.setName(name);
return this.isNew;
this.module = this.constructor;
this.capsule = this.manager.allocate(this);
$.extend(this, this.capsule);
this.setName(name);
return this.isNew;
}
Tracer.prototype = {
constructor: Tracer,
manager: null,
constructor: Tracer,
name: 'Tracer',
manager: null,
_setData(...args) {
this.manager.pushStep(this.capsule, {
type: 'setData',
args: toJSON(args)
});
return this;
},
_setData(...args) {
this.manager.pushStep(this.capsule, {
type: 'setData',
args: toJSON(args)
});
return this;
},
_clear() {
this.manager.pushStep(this.capsule, {
type: 'clear'
});
return this;
},
_clear() {
this.manager.pushStep(this.capsule, {
type: 'clear'
});
return this;
},
_wait() {
this.manager.newStep();
return this;
},
_wait() {
this.manager.newStep();
return this;
},
processStep(step, options) {
const {
type,
args
} = step;
processStep(step, options) {
const {
type,
args
} = step;
switch (type) {
case 'setData':
this.setData(...fromJSON(args));
break;
case 'clear':
this.clear();
break;
}
},
switch (type) {
case 'setData':
this.setData(...fromJSON(args));
break;
case 'clear':
this.clear();
break;
}
},
setName(name) {
let $name;
if (this.isNew) {
$name = $('<span class="name">');
this.$container.append($name);
} else {
$name = this.$container.find('span.name');
}
$name.text(name || this.defaultName);
},
setName(name) {
let $name;
if (this.isNew) {
$name = $('<span class="name">');
this.$container.append($name);
} else {
$name = this.$container.find('span.name');
}
$name.text(name || this.defaultName);
},
setData() {
const data = toJSON(arguments);
if (!this.isNew && this.lastData === data) {
return true;
}
this.isNew = this.capsule.isNew = false;
this.lastData = this.capsule.lastData = data;
return false;
},
setData() {
const data = toJSON(arguments);
if (!this.isNew && this.lastData === data) {
return true;
}
this.isNew = this.capsule.isNew = false;
this.lastData = this.capsule.lastData = data;
return false;
},
resize() {},
refresh() {},
clear() {},
resize() {
},
refresh() {
},
clear() {
},
attach(tracer) {
if (tracer.module === LogTracer) {
this.logTracer = tracer;
}
return this;
},
attach(tracer) {
if (tracer.module === LogTracer) {
this.logTracer = tracer;
}
return this;
},
mousedown(e) {},
mousemove(e) {},
mouseup(e) {},
mousewheel(e) {}
mousedown(e) {
},
mousemove(e) {
},
mouseup(e) {
},
mousewheel(e) {
}
};
module.exports = Tracer;
\ No newline at end of file
const {
DirectedGraph,
DirectedGraphTracer
DirectedGraph,
DirectedGraphTracer
} = require('./directed_graph');
function UndirectedGraphTracer() {
if (DirectedGraphTracer.apply(this, arguments)) {
UndirectedGraphTracer.prototype.init.call(this);
return true;
}
return false;
if (DirectedGraphTracer.apply(this, arguments)) {
UndirectedGraphTracer.prototype.init.call(this);
return true;
}
return false;
}
UndirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGraphTracer.prototype), {
constructor: UndirectedGraphTracer,
init: function() {
var tracer = this;
constructor: UndirectedGraphTracer,
name: 'UndirectedGraphTracer',
init: function () {
var tracer = this;
this.s.settings({
defaultEdgeType: 'def',
funcEdgesDef: function(edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawEdge(edge, source, target, color, context, settings);
}
});
},
setData: function(G) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.s.settings({
defaultEdgeType: 'def',
funcEdgesDef: function (edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawEdge(edge, source, target, color, context, settings);
}
});
},
setData: function (G) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.graph.clear();
var nodes = [];
var edges = [];
var unitAngle = 2 * Math.PI / G.length;
var currentAngle = 0;
for (var i = 0; i < G.length; i++) {
currentAngle += unitAngle;
nodes.push({
id: this.n(i),
label: '' + i,
x: .5 + Math.sin(currentAngle) / 2,
y: .5 + Math.cos(currentAngle) / 2,
size: 1,
color: this.color.default
});
}
for (var i = 0; i < G.length; i++) {
for (var j = 0; j <= i; j++) {
if (G[i][j] || G[j][i]) {
edges.push({
id: this.e(i, j),
source: this.n(i),
target: this.n(j),
color: this.color.default,
size: 1
});
}
}
this.graph.clear();
var nodes = [];
var edges = [];
var unitAngle = 2 * Math.PI / G.length;
var currentAngle = 0;
for (var i = 0; i < G.length; i++) {
currentAngle += unitAngle;
nodes.push({
id: this.n(i),
label: '' + i,
x: .5 + Math.sin(currentAngle) / 2,
y: .5 + Math.cos(currentAngle) / 2,
size: 1,
color: this.color.default
});
}
for (var i = 0; i < G.length; i++) {
for (var j = 0; j <= i; j++) {
if (G[i][j] || G[j][i]) {
edges.push({
id: this.e(i, j),
source: this.n(i),
target: this.n(j),
color: this.color.default,
size: 1
});
}
}
}
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
return false;
},
e: function(v1, v2) {
if (v1 > v2) {
var temp = v1;
v1 = v2;
v2 = temp;
}
return 'e' + v1 + '_' + v2;
},
drawOnHover: function(node, context, settings, next) {
var tracer = this;
return false;
},
e: function (v1, v2) {
if (v1 > v2) {
var temp = v1;
v1 = v2;
v2 = temp;
}
return 'e' + v1 + '_' + v2;
},
drawOnHover: function (node, context, settings, next) {
var tracer = this;
context.setLineDash([5, 5]);
var nodeIdx = node.id.substring(1);
this.graph.edges().forEach(function(edge) {
var ends = edge.id.substring(1).split("_");
if (ends[0] == nodeIdx) {
var color = '#0ff';
var source = node;
var target = tracer.graph.nodes('n' + ends[1]);
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
} else if (ends[1] == nodeIdx) {
var color = '#0ff';
var source = tracer.graph.nodes('n' + ends[0]);
var target = node;
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
}
});
},
drawEdge: function(edge, source, target, color, context, settings) {
var prefix = settings('prefix') || '',
size = edge[prefix + 'size'] || 1;
context.setLineDash([5, 5]);
var nodeIdx = node.id.substring(1);
this.graph.edges().forEach(function (edge) {
var ends = edge.id.substring(1).split("_");
if (ends[0] == nodeIdx) {
var color = '#0ff';
var source = node;
var target = tracer.graph.nodes('n' + ends[1]);
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
} else if (ends[1] == nodeIdx) {
var color = '#0ff';
var source = tracer.graph.nodes('n' + ends[0]);
var target = node;
tracer.drawEdge(edge, source, target, color, context, settings);
if (next) next(edge, source, target, color, context, settings);
}
});
},
drawEdge: function (edge, source, target, color, context, settings) {
var prefix = settings('prefix') || '',
size = edge[prefix + 'size'] || 1;
context.strokeStyle = color;
context.lineWidth = size;
context.beginPath();
context.moveTo(
source[prefix + 'x'],
source[prefix + 'y']
);
context.lineTo(
target[prefix + 'x'],
target[prefix + 'y']
);
context.stroke();
}
context.strokeStyle = color;
context.lineWidth = size;
context.beginPath();
context.moveTo(
source[prefix + 'x'],
source[prefix + 'y']
);
context.lineTo(
target[prefix + 'x'],
target[prefix + 'y']
);
context.stroke();
}
});
var UndirectedGraph = {
random: function(N, ratio) {
if (!N) N = 5;
if (!ratio) ratio = .3;
var G = new Array(N);
for (var i = 0; i < N; i++) G[i] = new Array(N);
for (var i = 0; i < N; i++) {
for (var j = 0; j < N; j++) {
if (i > j) {
G[i][j] = G[j][i] = (Math.random() * (1 / ratio) | 0) == 0 ? 1 : 0;
}
}
random: function (N, ratio) {
if (!N) N = 5;
if (!ratio) ratio = .3;
var G = new Array(N);
for (var i = 0; i < N; i++) G[i] = new Array(N);
for (var i = 0; i < N; i++) {
for (var j = 0; j < N; j++) {
if (i > j) {
G[i][j] = G[j][i] = (Math.random() * (1 / ratio) | 0) == 0 ? 1 : 0;
}
return G;
}
}
return G;
}
};
module.exports = {
UndirectedGraph,
UndirectedGraphTracer
UndirectedGraph,
UndirectedGraphTracer
};
\ No newline at end of file
const {
DirectedGraph,
DirectedGraphTracer
DirectedGraph,
DirectedGraphTracer
} = require('./directed_graph');
const {
refineByType
refineByType
} = require('../tracer_manager/util');
function WeightedDirectedGraphTracer() {
if (DirectedGraphTracer.apply(this, arguments)) {
WeightedDirectedGraphTracer.prototype.init.call(this);
return true;
}
return false;
if (DirectedGraphTracer.apply(this, arguments)) {
WeightedDirectedGraphTracer.prototype.init.call(this);
return true;
}
return false;
}
WeightedDirectedGraphTracer.prototype = $.extend(true, Object.create(DirectedGraphTracer.prototype), {
constructor: WeightedDirectedGraphTracer,
init: function() {
var tracer = this;
constructor: WeightedDirectedGraphTracer,
name: 'WeightedDirectedGraphTracer',
init: function () {
var tracer = this;
this.s.settings({
edgeLabelSize: 'proportional',
defaultEdgeLabelSize: 20,
edgeLabelSizePowRatio: 0.8,
funcLabelsDef: function(node, context, settings) {
tracer.drawNodeWeight(node, context, settings);
tracer.drawLabel(node, context, settings);
},
funcHoversDef: function(node, context, settings) {
tracer.drawOnHover(node, context, settings, tracer.drawEdgeWeight);
},
funcEdgesArrow: function(edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawArrow(edge, source, target, color, context, settings);
tracer.drawEdgeWeight(edge, source, target, color, context, settings);
}
});
},
_weight: function(target, weight) {
this.manager.pushStep(this.capsule, {
type: 'weight',
target: target,
weight: weight
});
return this;
},
_visit: function(target, source, weight) {
this.manager.pushStep(this.capsule, {
type: 'visit',
target: target,
source: source,
weight: weight
});
return this;
},
_leave: function(target, source, weight) {
this.manager.pushStep(this.capsule, {
type: 'leave',
target: target,
source: source,
weight: weight
});
return this;
},
processStep: function(step, options) {
switch (step.type) {
case 'weight':
var targetNode = this.graph.nodes(this.n(step.target));
if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);
break;
case 'visit':
case 'leave':
var visit = step.type == 'visit';
var targetNode = this.graph.nodes(this.n(step.target));
var color = visit ? this.color.visited : this.color.left;
targetNode.color = color;
if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);
if (step.source !== undefined) {
var edgeId = this.e(step.source, step.target);
var edge = this.graph.edges(edgeId);
edge.color = color;
this.graph.dropEdge(edgeId).addEdge(edge);
}
if (this.logTracer) {
var source = step.source;
if (source === undefined) source = '';
this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);
}
break;
default:
DirectedGraphTracer.prototype.processStep.call(this, step, options);
this.s.settings({
edgeLabelSize: 'proportional',
defaultEdgeLabelSize: 20,
edgeLabelSizePowRatio: 0.8,
funcLabelsDef: function (node, context, settings) {
tracer.drawNodeWeight(node, context, settings);
tracer.drawLabel(node, context, settings);
},
funcHoversDef: function (node, context, settings) {
tracer.drawOnHover(node, context, settings, tracer.drawEdgeWeight);
},
funcEdgesArrow: function (edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawArrow(edge, source, target, color, context, settings);
tracer.drawEdgeWeight(edge, source, target, color, context, settings);
}
});
},
_weight: function (target, weight) {
this.manager.pushStep(this.capsule, {
type: 'weight',
target: target,
weight: weight
});
return this;
},
_visit: function (target, source, weight) {
this.manager.pushStep(this.capsule, {
type: 'visit',
target: target,
source: source,
weight: weight
});
return this;
},
_leave: function (target, source, weight) {
this.manager.pushStep(this.capsule, {
type: 'leave',
target: target,
source: source,
weight: weight
});
return this;
},
processStep: function (step, options) {
switch (step.type) {
case 'weight':
var targetNode = this.graph.nodes(this.n(step.target));
if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);
break;
case 'visit':
case 'leave':
var visit = step.type == 'visit';
var targetNode = this.graph.nodes(this.n(step.target));
var color = visit ? this.color.visited : this.color.left;
targetNode.color = color;
if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);
if (step.source !== undefined) {
var edgeId = this.e(step.source, step.target);
var edge = this.graph.edges(edgeId);
edge.color = color;
this.graph.dropEdge(edgeId).addEdge(edge);
}
if (this.logTracer) {
var source = step.source;
if (source === undefined) source = '';
this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);
}
},
setData: function(G) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
break;
default:
DirectedGraphTracer.prototype.processStep.call(this, step, options);
}
},
setData: function (G) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.graph.clear();
var nodes = [];
var edges = [];
var unitAngle = 2 * Math.PI / G.length;
var currentAngle = 0;
for (var i = 0; i < G.length; i++) {
currentAngle += unitAngle;
nodes.push({
id: this.n(i),
label: '' + i,
x: .5 + Math.sin(currentAngle) / 2,
y: .5 + Math.cos(currentAngle) / 2,
size: 1,
color: this.color.default,
weight: 0
});
for (var j = 0; j < G[i].length; j++) {
if (G[i][j]) {
edges.push({
id: this.e(i, j),
source: this.n(i),
target: this.n(j),
color: this.color.default,
size: 1,
weight: refineByType(G[i][j])
});
}
}
this.graph.clear();
var nodes = [];
var edges = [];
var unitAngle = 2 * Math.PI / G.length;
var currentAngle = 0;
for (var i = 0; i < G.length; i++) {
currentAngle += unitAngle;
nodes.push({
id: this.n(i),
label: '' + i,
x: .5 + Math.sin(currentAngle) / 2,
y: .5 + Math.cos(currentAngle) / 2,
size: 1,
color: this.color.default,
weight: 0
});
for (var j = 0; j < G[i].length; j++) {
if (G[i][j]) {
edges.push({
id: this.e(i, j),
source: this.n(i),
target: this.n(j),
color: this.color.default,
size: 1,
weight: refineByType(G[i][j])
});
}
}
}
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
return false;
},
clear: function() {
DirectedGraphTracer.prototype.clear.call(this);
return false;
},
clear: function () {
DirectedGraphTracer.prototype.clear.call(this);
this.clearWeights();
},
clearWeights: function() {
this.graph.nodes().forEach(function(node) {
node.weight = 0;
});
},
drawEdgeWeight: function(edge, source, target, color, context, settings) {
if (source == target)
return;
this.clearWeights();
},
clearWeights: function () {
this.graph.nodes().forEach(function (node) {
node.weight = 0;
});
},
drawEdgeWeight: function (edge, source, target, color, context, settings) {
if (source == target)
return;
var prefix = settings('prefix') || '',
size = edge[prefix + 'size'] || 1;
var prefix = settings('prefix') || '',
size = edge[prefix + 'size'] || 1;
if (size < settings('edgeLabelThreshold'))
return;
if (size < settings('edgeLabelThreshold'))
return;
if (0 === settings('edgeLabelSizePowRatio'))
throw '"edgeLabelSizePowRatio" must not be 0.';
if (0 === settings('edgeLabelSizePowRatio'))
throw '"edgeLabelSizePowRatio" must not be 0.';
var fontSize,
x = (source[prefix + 'x'] + target[prefix + 'x']) / 2,
y = (source[prefix + 'y'] + target[prefix + 'y']) / 2,
dX = target[prefix + 'x'] - source[prefix + 'x'],
dY = target[prefix + 'y'] - source[prefix + 'y'],
angle = Math.atan2(dY, dX);
var fontSize,
x = (source[prefix + 'x'] + target[prefix + 'x']) / 2,
y = (source[prefix + 'y'] + target[prefix + 'y']) / 2,
dX = target[prefix + 'x'] - source[prefix + 'x'],
dY = target[prefix + 'y'] - source[prefix + 'y'],
angle = Math.atan2(dY, dX);
fontSize = (settings('edgeLabelSize') === 'fixed') ?
settings('defaultEdgeLabelSize') :
settings('defaultEdgeLabelSize') *
size *
Math.pow(size, -1 / settings('edgeLabelSizePowRatio'));
fontSize = (settings('edgeLabelSize') === 'fixed') ?
settings('defaultEdgeLabelSize') :
settings('defaultEdgeLabelSize') *
size *
Math.pow(size, -1 / settings('edgeLabelSizePowRatio'));
context.save();
context.save();
if (edge.active) {
context.font = [
settings('activeFontStyle'),
fontSize + 'px',
settings('activeFont') || settings('font')
].join(' ');
if (edge.active) {
context.font = [
settings('activeFontStyle'),
fontSize + 'px',
settings('activeFont') || settings('font')
].join(' ');
context.fillStyle = color;
} else {
context.font = [
settings('fontStyle'),
fontSize + 'px',
settings('font')
].join(' ');
context.fillStyle = color;
} else {
context.font = [
settings('fontStyle'),
fontSize + 'px',
settings('font')
].join(' ');
context.fillStyle = color;
}
context.fillStyle = color;
}
context.textAlign = 'center';
context.textBaseline = 'alphabetic';
context.textAlign = 'center';
context.textBaseline = 'alphabetic';
context.translate(x, y);
context.rotate(angle);
context.fillText(
edge.weight,
0,
(-size / 2) - 3
);
context.translate(x, y);
context.rotate(angle);
context.fillText(
edge.weight,
0,
(-size / 2) - 3
);
context.restore();
},
drawNodeWeight: function(node, context, settings) {
var fontSize,
prefix = settings('prefix') || '',
size = node[prefix + 'size'];
context.restore();
},
drawNodeWeight: function (node, context, settings) {
var fontSize,
prefix = settings('prefix') || '',
size = node[prefix + 'size'];
if (size < settings('labelThreshold'))
return;
if (size < settings('labelThreshold'))
return;
fontSize = (settings('labelSize') === 'fixed') ?
settings('defaultLabelSize') :
settings('labelSizeRatio') * size;
fontSize = (settings('labelSize') === 'fixed') ?
settings('defaultLabelSize') :
settings('labelSizeRatio') * size;
context.font = (settings('fontStyle') ? settings('fontStyle') + ' ' : '') +
fontSize + 'px ' + settings('font');
context.fillStyle = (settings('labelColor') === 'node') ?
(node.color || settings('defaultNodeColor')) :
settings('defaultLabelColor');
context.font = (settings('fontStyle') ? settings('fontStyle') + ' ' : '') +
fontSize + 'px ' + settings('font');
context.fillStyle = (settings('labelColor') === 'node') ?
(node.color || settings('defaultNodeColor')) :
settings('defaultLabelColor');
context.textAlign = 'left';
context.fillText(
node.weight,
Math.round(node[prefix + 'x'] + size * 1.5),
Math.round(node[prefix + 'y'] + fontSize / 3)
);
}
context.textAlign = 'left';
context.fillText(
node.weight,
Math.round(node[prefix + 'x'] + size * 1.5),
Math.round(node[prefix + 'y'] + fontSize / 3)
);
}
});
var WeightedDirectedGraph = {
random: function(N, ratio, min, max) {
if (!N) N = 5;
if (!ratio) ratio = .3;
if (!min) min = 1;
if (!max) max = 5;
var G = new Array(N);
for (var i = 0; i < N; i++) {
G[i] = new Array(N);
for (var j = 0; j < N; j++) {
if (i != j && (Math.random() * (1 / ratio) | 0) == 0) {
G[i][j] = (Math.random() * (max - min + 1) | 0) + min;
}
}
random: function (N, ratio, min, max) {
if (!N) N = 5;
if (!ratio) ratio = .3;
if (!min) min = 1;
if (!max) max = 5;
var G = new Array(N);
for (var i = 0; i < N; i++) {
G[i] = new Array(N);
for (var j = 0; j < N; j++) {
if (i != j && (Math.random() * (1 / ratio) | 0) == 0) {
G[i][j] = (Math.random() * (max - min + 1) | 0) + min;
}
return G;
}
}
return G;
}
};
module.exports = {
WeightedDirectedGraph,
WeightedDirectedGraphTracer
WeightedDirectedGraph,
WeightedDirectedGraphTracer
};
\ No newline at end of file
const {
WeightedDirectedGraph,
WeightedDirectedGraphTracer
WeightedDirectedGraph,
WeightedDirectedGraphTracer
} = require('./weighted_directed_graph');
const {
UndirectedGraphTracer
UndirectedGraphTracer
} = require('./undirected_graph');
function WeightedUndirectedGraphTracer() {
if (WeightedDirectedGraphTracer.apply(this, arguments)) {
WeightedUndirectedGraphTracer.prototype.init.call(this);
return true;
}
return false;
if (WeightedDirectedGraphTracer.apply(this, arguments)) {
WeightedUndirectedGraphTracer.prototype.init.call(this);
return true;
}
return false;
}
WeightedUndirectedGraphTracer.prototype = $.extend(true, Object.create(WeightedDirectedGraphTracer.prototype), {
constructor: WeightedUndirectedGraphTracer,
init: function() {
var tracer = this;
constructor: WeightedUndirectedGraphTracer,
name: 'WeightedUndirectedGraphTracer',
init: function () {
var tracer = this;
this.s.settings({
defaultEdgeType: 'def',
funcEdgesDef: function(edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawEdge(edge, source, target, color, context, settings);
tracer.drawEdgeWeight(edge, source, target, color, context, settings);
}
});
},
setData: function(G) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.s.settings({
defaultEdgeType: 'def',
funcEdgesDef: function (edge, source, target, context, settings) {
var color = tracer.getColor(edge, source, target, settings);
tracer.drawEdge(edge, source, target, color, context, settings);
tracer.drawEdgeWeight(edge, source, target, color, context, settings);
}
});
},
setData: function (G) {
if (Tracer.prototype.setData.apply(this, arguments)) return true;
this.graph.clear();
var nodes = [];
var edges = [];
var unitAngle = 2 * Math.PI / G.length;
var currentAngle = 0;
for (var i = 0; i < G.length; i++) {
currentAngle += unitAngle;
nodes.push({
id: this.n(i),
label: '' + i,
x: .5 + Math.sin(currentAngle) / 2,
y: .5 + Math.cos(currentAngle) / 2,
size: 1,
color: this.color.default,
weight: 0
});
}
for (var i = 0; i < G.length; i++) {
for (var j = 0; j <= i; j++) {
if (G[i][j] || G[j][i]) {
edges.push({
id: this.e(i, j),
source: this.n(i),
target: this.n(j),
color: this.color.default,
size: 1,
weight: G[i][j]
});
}
}
this.graph.clear();
var nodes = [];
var edges = [];
var unitAngle = 2 * Math.PI / G.length;
var currentAngle = 0;
for (var i = 0; i < G.length; i++) {
currentAngle += unitAngle;
nodes.push({
id: this.n(i),
label: '' + i,
x: .5 + Math.sin(currentAngle) / 2,
y: .5 + Math.cos(currentAngle) / 2,
size: 1,
color: this.color.default,
weight: 0
});
}
for (var i = 0; i < G.length; i++) {
for (var j = 0; j <= i; j++) {
if (G[i][j] || G[j][i]) {
edges.push({
id: this.e(i, j),
source: this.n(i),
target: this.n(j),
color: this.color.default,
size: 1,
weight: G[i][j]
});
}
}
}
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
this.graph.read({
nodes: nodes,
edges: edges
});
this.s.camera.goTo({
x: 0,
y: 0,
angle: 0,
ratio: 1
});
this.refresh();
return false;
},
e: UndirectedGraphTracer.prototype.e,
drawOnHover: UndirectedGraphTracer.prototype.drawOnHover,
drawEdge: UndirectedGraphTracer.prototype.drawEdge,
drawEdgeWeight: function(edge, source, target, color, context, settings) {
var prefix = settings('prefix') || '';
if (source[prefix + 'x'] > target[prefix + 'x']) {
var temp = source;
source = target;
target = temp;
}
WeightedDirectedGraphTracer.prototype.drawEdgeWeight.call(this, edge, source, target, color, context, settings);
return false;
},
e: UndirectedGraphTracer.prototype.e,
drawOnHover: UndirectedGraphTracer.prototype.drawOnHover,
drawEdge: UndirectedGraphTracer.prototype.drawEdge,
drawEdgeWeight: function (edge, source, target, color, context, settings) {
var prefix = settings('prefix') || '';
if (source[prefix + 'x'] > target[prefix + 'x']) {
var temp = source;
source = target;
target = temp;
}
WeightedDirectedGraphTracer.prototype.drawEdgeWeight.call(this, edge, source, target, color, context, settings);
}
});
var WeightedUndirectedGraph = {
random: function(N, ratio, min, max) {
if (!N) N = 5;
if (!ratio) ratio = .3;
if (!min) min = 1;
if (!max) max = 5;
var G = new Array(N);
for (var i = 0; i < N; i++) G[i] = new Array(N);
for (var i = 0; i < N; i++) {
for (var j = 0; j < N; j++) {
if (i > j && (Math.random() * (1 / ratio) | 0) == 0) {
G[i][j] = G[j][i] = (Math.random() * (max - min + 1) | 0) + min;
}
}
random: function (N, ratio, min, max) {
if (!N) N = 5;
if (!ratio) ratio = .3;
if (!min) min = 1;
if (!max) max = 5;
var G = new Array(N);
for (var i = 0; i < N; i++) G[i] = new Array(N);
for (var i = 0; i < N; i++) {
for (var j = 0; j < N; j++) {
if (i > j && (Math.random() * (1 / ratio) | 0) == 0) {
G[i][j] = G[j][i] = (Math.random() * (max - min + 1) | 0) + min;
}
return G;
}
}
return G;
}
};
module.exports = {
WeightedUndirectedGraph,
WeightedUndirectedGraphTracer
WeightedUndirectedGraph,
WeightedUndirectedGraphTracer
};
\ No newline at end of file
......@@ -51,7 +51,8 @@ TracerManager.prototype = {
selectedCapsule = this.add(newTracer);
}
selectedCapsule.defaultName = `${newTracer.constructor.name} ${count}`;
console.log(newTracer);
selectedCapsule.defaultName = `${newTracer.name} ${count}`;
return selectedCapsule;
},
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部