鱼骨图由日本管理大师石川馨先生所发明,故又名石川图。鱼骨图是一种发现问题“根本原因”的方法,它也可以称之为“Ishikawa”或者“因果图”。其特点是简捷实用,深入直观。它看上去有些象鱼骨,问题或缺陷(即后果)标在"鱼头"外。在鱼骨上长出鱼刺,上面按出现机会多寡列出产生生产问题的可能原因,有助于说明各个原因之间如何相互影响。
这玩意儿就体现了一个什么5w1h的管理方法,经过我将近4周的时间捣鼓。由于原先想实现的过于复杂(主要由于本人数学知识浅薄),后来放弃了原先的两个方案。一是分支斜线扩展;二是分支上下、左右扩展。
不知道写点个啥,直接上代码吧。
/**
* Created by numen_huang on 2014/8/6.
*/
$(function () {
if (!mxClient.isBrowserSupported()) {
// Displays an error message if the browser is not supported.
mxUtils.error('Browser is not supported!', 200, false);
}
else {
document.oncontextmenu = function () {
return false;
}
var fish=new fishBone();
fish.init();
}
});
var fishBone=function(){};
fishBone.prototype.graph=null;
fishBone.prototype.init=function(){
this.resetSourceCode();
this.buildCanvas();
this.setCanvasStyle();
this.buildContextMenu();
this.createFishBone();
};
fishBone.prototype.resetSourceCode=function(){
var _this=this;
mxCellRenderer.prototype.createLabel = function(state, value) {
var graph = state.view.graph;
var isEdge = graph.getModel().isEdge(state.cell);
if (state.style[mxConstants.STYLE_FONTSIZE] > 0 || state.style[mxConstants.STYLE_FONTSIZE] == null) {
var isForceHtml = (graph.isHtmlLabel(state.cell) || (value != null && mxUtils.isNode(value))) && graph.dialect == mxConstants.DIALECT_SVG;
var h='';
var spacingRight=-30;
var spacingLeft=1;
if(state.cell.id=='fishboneHead'){
h='horizontal';
spacingRight=spacingLeft=0;
}
if(state.cell.level%2==0 && state.cell.id!='fishboneHead'){
h='horizontal';
if(_this.getSelfTopParent(state.cell).direction=='bottom') {
spacingLeft = -25;
}else{
spacingLeft = 0;
}
}
var background=state.style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR];
var borderColor=state.style[mxConstants.STYLE_LABEL_BORDERCOLOR];
var color=state.style[mxConstants.STYLE_FONTCOLOR];
if(state.cell.level==1){
background='#B3D9D9';
borderColor='#005757';
color='#336666';
}else{
background='#F3F3F3';
borderColor='#005757';
color='#336666';
}
state.text = new mxText(value, null, (state.style[mxConstants.STYLE_ALIGN] || mxConstants.ALIGN_CENTER),
graph.getVerticalAlign(state),color,
state.style[mxConstants.STYLE_FONTFAMILY], state.style[mxConstants.STYLE_FONTSIZE],
state.style[mxConstants.STYLE_FONTSTYLE], state.style[mxConstants.STYLE_SPACING],
spacingLeft, 10,
spacingRight, 10, h,
background, borderColor,
graph.isWrapping(state.cell), graph.isLabelClipped(state.cell), state.style[mxConstants.STYLE_OVERFLOW]);
state.text.opacity = state.style[mxConstants.STYLE_TEXT_OPACITY];
state.text.dialect = (isForceHtml) ? mxConstants.DIALECT_STRICTHTML: state.view.graph.dialect;
this.initializeLabel(state);
var getState = function(evt) {
var result = state;
if (mxClient.IS_TOUCH) {
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var pt = mxUtils.convertPoint(graph.container, x, y);
result = graph.view.getState(graph.getCellAt(pt.x, pt.y));
}
return result;
};
var md = (mxClient.IS_TOUCH) ? 'touchstart': 'mousedown';
var mm = (mxClient.IS_TOUCH) ? 'touchmove': 'mousemove';
var mu = (mxClient.IS_TOUCH) ? 'touchend': 'mouseup';
mxEvent.addListener(state.text.node, md, mxUtils.bind(this,
function(evt) {
if (this.isLabelEvent(state, evt)) {
graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
}
}));
mxEvent.addListener(state.text.node, mm, mxUtils.bind(this,
function(evt) {
if (this.isLabelEvent(state, evt)) {
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
}
}));
mxEvent.addListener(state.text.node, mu, mxUtils.bind(this,
function(evt) {
if (this.isLabelEvent(state, evt)) {
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
}
}));
mxEvent.addListener(state.text.node, 'dblclick', mxUtils.bind(this,
function(evt) {
if (this.isLabelEvent(state, evt)) {
graph.dblClick(evt, state.cell);
mxEvent.consume(evt);
}
}));
}
};
mxTriangle.prototype.redrawPath = function(path, x, y, w, h) {
if (this.direction == mxConstants.DIRECTION_NORTH) {
path.moveTo(0, h);
path.lineTo(0.5 * w, 0);
path.lineTo(w, h);
} else if (this.direction == mxConstants.DIRECTION_SOUTH) {
path.moveTo(0, 0);
path.lineTo(0.5 * w, h);
path.lineTo(w, 0);
} else if (this.direction == mxConstants.DIRECTION_WEST) {
path.moveTo(0, 0);
path.lineTo(w, 0.5 * h);
path.lineTo(0, h);
}
else if(this.direction == 'east'){
path.moveTo(0, 0);
path.quadTo(w, 0.25 * h,w+1,0.5*h);
path.quadTo(w+1, 0.75 * h,0,h);
}
else{
path.moveTo(0, 0);
path.lineTo(w, 0.5 * h);
path.lineTo(0, h);
}
path.close();
};
mxGraphSelectionModel.prototype.singleSelection = true;
mxGraph.prototype.foldingEnabled=false;
mxGraph.prototype.selectCellForEvent = function(cell, evt) {
if(cell.id!='fishboneEnd' && cell.id!='fishboneBody' && !cell.isEdge()) {
var isSelected = this.isCellSelected(cell);
if (this.isToggleEvent(evt)) {
if (isSelected) {
this.removeSelectionCell(cell);
} else {
this.addSelectionCell(cell);
}
} else if (!isSelected || this.getSelectionCount() != 1) {
this.setSelectionCell(cell);
}
}
};
mxGraph.prototype.moveCells = function(cells, dx, dy, clone, target, evt) {
if(cells==null || cells.length>1){
return false;
}
var cell=cells[0];
if (dx != 0 || dy != 0 || clone || target != null) {
this.getModel().beginUpdate();
try {
if (clone) {
return false;
}
if(cell.level==1){
var fishHead=_this.getCellById('fishboneHead');
var fishBody=_this.getCellById('fishboneBody');
var fishEnd=_this.getCellById('fishboneEnd');
if(cell.geometry.x+dx>fishHead.geometry.x-100){
cell.geometry.x+=dx;
var size=cell.geometry.x-fishHead.geometry.x;
fishHead.geometry.x+=size+100;
fishBody.geometry.width+=size+100;
}
else if(cell.geometry.x+dx0?children[0].geometry.x:fishHead.geometry.x-30;
for(var i=0;imaxX){
maxX=children[i].geometry.x;
}
}
var oldX=fishHead.geometry.x;
fishHead.geometry.x+=dx;
var size=fishHead.geometry.x-oldX;
if(fishHead.geometry.x0?children[0].geometry.x:fishEnd.geometry.x-100;
for(var i=0;iminX-100){
fishEnd.geometry.x=minX-100;
size=fishEnd.geometry.x-oldX;
}
fishBody.geometry.x=fishEnd.geometry.x+fishEnd.geometry.width;
fishBody.geometry.width-=size;
}
else if (cell.direction == 'top' || cell.direction == 'bottom') {
if(cell.parent.children.length==1){
cell.geometry.x=0;
cell.parent.geometry.width-=dx;
cell.parent.geometry.x+=dx;
if(cell.parent.geometry.width<=70){
cell.parent.geometry.width=70;
cell.parent.geometry.x=-70;
}
}
else{
if(cell.geometry.x==0){
if(dx<0){
for(var i=0;i cell.geometry.x && !temp2) {
temp2=children[i];
continue;
}else if(temp2) {
if (children[i].geometry.x < temp2.geometry.x && children[i].id != cell.id) {
temp2 = children[i];
}
}
}
if(temp2 && t==1) {
//没有超过第二小x坐标
if (temp2.geometry.x - dx > 0) {
for (var k = 0; k < cell.parent.children.length; k++) {
if (cell.parent.children[k].id != cell.id) {
cell.parent.children[k].geometry.x -= dx;
}
}
cell.geometry.x += dx;
cell.parent.geometry.width -= dx;
cell.parent.geometry.x += dx;
cell.geometry.x = 0;
}
//超过第二小x坐标
else {
if(cell.parent.geometry.width-temp2.geometry.x==70){
for (var k = 0; k < cell.parent.children.length; k++) {
cell.parent.children[k].geometry.x=0;
}
cell.parent.geometry.width=70;
cell.parent.geometry.x=-70;
}else {
var size = dx - temp2.geometry.x;
var pSize = cell.parent.geometry.width - temp2.geometry.x;
for (var k = 0; k < cell.parent.children.length; k++) {
if (cell.parent.children[k].id != temp2.id && cell.parent.children[k].id != cell.id) {
cell.parent.children[k].geometry.x -= temp2.geometry.x;
}
}
cell.parent.geometry.width -= temp2.geometry.x;
cell.parent.geometry.x += temp2.geometry.x;
temp2.geometry.x = 0;
if(size-pSize>0){
cell.geometry.x = cell.parent.geometry.width-70;
}
else {
cell.geometry.x = size;
}
}
}
}
else if(t>1){
if(cell.geometry.x+dx0 && cell.geometry.x+dx py)
py = cell.parent.children[i].geometry.y;
}
if(py>70) {
cell.parent.geometry.height = py;
}else{
cell.parent.geometry.height = 70;
}
if(cell.geometry.y<70){
cell.geometry.y=70;
}
}
else{
if(cell.geometry.y==0){
if(dy<0) {
for (var i = 0; i < cell.parent.children.length; i++) {
if (cell.parent.children[i].id != cell.id) {
cell.parent.children[i].geometry.y -= dy;
}
}
cell.parent.geometry.y += dy;
cell.parent.geometry.height -= dy;
}
else{
//只有一个子集的时候
if(cell.parent.children.length==1){
var fishBody=_this.getCellById('fishboneBody');
//拖动超过父级label的位置
if(!(cell.geometry.y==0 && cell.parent.geometry.height==70)) {
if (cell.parent.geometry.height - dy < 70) {
if(cell.parent.parent.id==1){
cell.parent.geometry.y = fishBody.geometry.y - 68;
}else{
cell.parent.geometry.y = cell.parent.parent.geometry.y - 70;
}
cell.parent.geometry.height = 70;
} else {
cell.parent.geometry.height -= dy;
cell.parent.geometry.y += dy;
}
cell.geometry.y = 0;
}
}
else {//超过一个子集
var children=cell.parent.children;
var temp1=children[0];//最小y坐标的cell
var t=0;
for (var i = 0; i < children.length; i++) {
if (children[i].geometry.y < temp1.geometry.y) {
temp1 = children[i];
}
if(children[i].geometry.y==0){
t++;
}
}
var temp2=null;//第二小y坐标的cell
for (var i = 0; i < children.length; i++) {
if (children[i].geometry.y > temp1.geometry.y && !temp2) {
temp2=children[i];
continue;
}else if(temp2) {
if (children[i].geometry.y < temp2.geometry.y && children[i].id != temp1.id) {
temp2 = children[i];
}
}
}
//当没有超过第二小y坐标时。
if(temp2 && t==1) {
if (cell.geometry.y + dy < temp2.geometry.y) {
for (var k = 0; k < cell.parent.children.length; k++) {
if (cell.parent.children[k].id != cell.id) {
cell.parent.children[k].geometry.y -= dy;
}
}
cell.parent.geometry.height -= dy;
cell.parent.geometry.y += dy;
cell.geometry.y = 0;
}
//当超过第二小y坐标时候
else {
cell.geometry.y += dy;
var py = cell.parent.geometry.height - (cell.parent.geometry.height - temp2.geometry.y);
for (var k = 0; k < cell.parent.children.length; k++) {
if (cell.parent.children[k].id != temp2.id) {
cell.parent.children[k].geometry.y -= py;
}
}
cell.parent.geometry.height -= temp2.geometry.y;
cell.parent.geometry.y += temp2.geometry.y;
temp2.geometry.y = 0;
for (var j = 0; j < cell.parent.children.length; j++) {
if (cell.parent.geometry.height - cell.parent.children[j].geometry.y < 70) {
cell.parent.children[j].geometry.y = cell.parent.geometry.height - 70;
}
}
}
}
else if(t>1){
if(cell.parent.geometry.height>70) {
if (cell.parent.geometry.height - dy < 70) {
cell.geometry.y = 70;
} else {
cell.geometry.y = dy;
}
}
}
}
}
}
else{
if(cell.geometry.y+dy>0){
if(cell.parent.geometry.height-(cell.geometry.y+dy)<=70){
cell.geometry.y=cell.parent.geometry.height-70;
}else {
cell.geometry.y += dy;
}
}else{
for (var i = 0; i < cell.parent.children.length; i++) {
if (cell.parent.children[i].id != cell.id) {
cell.parent.children[i].geometry.y -= (cell.geometry.y+dy);
}
}
cell.parent.geometry.y += (cell.geometry.y+dy);
cell.parent.geometry.height -= cell.geometry.y+dy;
cell.geometry.y=0;
}
}
}
}
} finally {
this.getModel().endUpdate();
this.refresh();
}
}
return cells;
};
mxGraph.prototype.dblClick = function(evt, cell) {
if(cell.id!='fishboneEnd' && cell.id!='fishboneBody' && !cell.isEdge()) {
var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
this.fireEvent(mxe);
if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() && cell != null && this.isCellEditable(cell)) {
this.startEditingAtCell(cell, evt);
}
}
};
// mxGraph.prototype.labelChanged = function(cell, value, evt) {
// this.model.beginUpdate();
// var geo=cell.geometry;
// try {
// this.cellLabelChanged(cell, value, true);
// this.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED, 'cell', cell, 'value', value, 'event', evt));
// geo.height =geo.height+((value.length-5>0)? (value.length-5)*18:0);
// cell.geometry=geo;
// if(cell.level>1){
//// var myEdge = cell.edges[0];
//// var point = myEdge.geometry.points[0];
//// point.x=0;
//// myEdge.geometry.points=[point];
// }
// } finally {
// this.model.endUpdate();
// }
// return cell;
// };
mxCellEditor.prototype.init = function() {
this.textarea = document.createElement('input');
this.textarea.className = 'mxCellEditor';
this.textarea.style.position = 'absolute';
this.textarea.style.overflow = 'visible';
this.textarea.setAttribute('type', 'textbox');
if (false) {
this.textarea.style.resize = 'none';
}
mxEvent.addListener(this.textarea, 'blur', mxUtils.bind(this,
function(evt) {
this.stopEditing(!this.graph.isInvokesStopCellEditing());
}));
mxEvent.addListener(this.textarea, 'keydown', mxUtils.bind(this,
function(evt) {
if (!mxEvent.isConsumed(evt)) {
if (evt.keyCode == 113 || (this.graph.isEnterStopsCellEditing() && evt.keyCode == 13 && !mxEvent.isControlDown(evt) && !mxEvent.isShiftDown(evt))) {
this.graph.stopEditing(false);
mxEvent.consume(evt);
} else if (evt.keyCode == 27) {
this.graph.stopEditing(true);
mxEvent.consume(evt);
} else {
if (this.clearOnChange) {
this.clearOnChange = false;
this.textarea.value = '';
}
this.setModified(true);
}
}
}));
};
mxGraphHandler.prototype.selectEnabled=false;
};
fishBone.prototype.buildCanvas=function(){
var container = document.createElement('div');
container.style.position = 'absolute';
container.style.overflow = 'hidden';
container.style.left = '0px';
container.style.top = '0px';
container.style.right = '0px';
container.style.bottom = '0px';
document.body.appendChild(container);
var node = mxUtils.load('config/keyhandler-commons.xml').getDocumentElement();
this.editor = new mxEditor(node);
this.editor.graph=new mxGraph(container);
this.graph = this.editor.graph;
var outline = document.getElementById('outlineContainer');
new mxOutline(this.graph, outline);
if (mxClient.IS_IE) {
new mxDivResizer(container);
new mxDivResizer(outline);
}
this.graph.clearSelection();
this.graph.setEnabled(true);
this.graph.setTooltips(false);
this.graph.setConnectable(false);
this.graph.setPanning(true);
this.graph.setCellsResizable(false);
};
fishBone.prototype.setCanvasStyle=function(){
var graph=this.graph;
var style = graph.getStylesheet().getDefaultVertexStyle();
style[mxConstants.STYLE_FONTCOLOR] = 'black';
style[mxConstants.STYLE_STROKECOLOR] = '#8E8E8E';
style[mxConstants.STYLE_FILLCOLOR] = 'white';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_FONTSTYLE] = 1;
style[mxConstants.STYLE_FONTFAMILY] = '微软雅黑';
// Sets the default style for edges
style = graph.getStylesheet().getDefaultEdgeStyle();
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.STRAIGHT;
// Enables rubberband selection and key handling
var rubberband = new mxRubberband(graph);
var keyHandler = new mxKeyHandler(graph);
};
fishBone.prototype.buildContextMenu=function(){
var fish=this;
mxPopupMenu.prototype.submenuImage = 'src/images/submenu.gif';
this.graph.panningHandler.factoryMethod = function (menu, cell, evt) {
if (cell != null && !cell.isEdge() && cell.id!='fishboneEnd' && cell.id!='fishboneBody') {
var item= menu.addItem('插入','src/images/maximize.gif');
menu.addItem('插入主题','src/images/maximize.gif', function () {
fish.createSubject(cell);
fish.graph.clearSelection();
},item);
menu.addItem('插入子主题','src/images/normalize.gif', function () {
fish.createSubject(cell,true);
fish.graph.clearSelection();
},item);
menu.addItem('删除','images/delete2.png', function () {
fish.graph.removeCells([cell]);
});
menu.addItem('编辑','images/icons48/tab.png', function () {
fish.graph.startEditingAtCell(cell);
});
}else{
this.graph.clearSelection();
};
};
};
fishBone.prototype.createFishBone=function(){
var xml = '\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
';
doc = mxUtils.parseXml(xml);
var codec = new mxCodec(doc);
//mxShape.prototype.direction = mxConstants.DIRECTION_NORTH;
codec.decode(doc.documentElement, this.graph.getModel());
var items=['人员','管理','过程','环境','设备','材料'];
var cell=this.getCellById('fishboneHead');
for(var i=0;i 1) {
if (cell.parent.parent.children.length > 1 && cell.parent.children.length == 1 && cell.parent.geometry.x > 0) {
for (var k = 0; k < cell.parent.parent.children.length; k++) {
if (cell.parent.parent.children[k].geometry.x >= cell.parent.geometry.x && cell.parent.children.length == 1) {
cell.parent.parent.children[k].geometry.x += 50;
cell.parent.parent.geometry.x -= 50;
cell.parent.parent.geometry.width += 50;
}
}
}
cell.parent.geometry.height = cell.parent.children[cell.parent.children.length - 1].geometry.y;
} else {
cell.parent.geometry.height = 1;
}
if (cell.parent.level != 1) {
resize(cell.parent);
} else {
cell.parent.geometry.height = cell.parent.children[cell.parent.children.length - 1].geometry.y;
}
};
resize(myCell);
}
else{
y = 0;
for(var i=0;i0) {
cell.geometry.height += 70;
cell.geometry.y -= 70;
}
var myCell = graph.insertVertex(cell, null, text, x, y, 70, 1, 'shape=line;verticalAlign=top;align=right;strokeWidth=1;strokeColor=#BB3D00;');
myCell.level = cell.level + 1;
myCell.direction = 'left';
myCell.geometry.x -= 70;
if (myCell.parent.parent.direction == 'left') {
myCell.parent.parent.geometry.height = 1;
}
var resize = function (cell) {
if(cell.direction=='top' && cell.level!=1 && cell.children.length==1){
for(var k=cell.parent.children.length-1;k>=0;k--){
if(cell.parent.children[k].geometry.x>=cell.geometry.x){
cell.parent.children[k].geometry.x+=cell.children[0].geometry.width;
}
}
cell.geometry.x-=myCell.geometry.width;
}
};
resize(myCell.parent);
}
};
/*垂直方向子主题*/
var insertVerticalSubLevel=function(){
var selfTopParent = fish.getSelfTopParent(cell);
var leftTopParents=fish.getLeftTopParent(selfTopParent,true);
if (!text)text = '分支主题'+(cell.children.length+1);
if(cell.children.length==0)
x=0;
else {
var maxX=0;
for(var i=0;imaxX){
maxX=cell.children[i].geometry.x;
}
}
x = 50 + maxX;
}
var align='right';
var direction='bottom';
if(selfTopParent.direction=='bottom') {
y = 1;
}else{
y=0;
align='left';
direction='top';
}
var myCell = graph.insertVertex(cell, null, text, x, y, 1, 70, 'shape=line;direction=north;verticalAlign=top;align='+align+';spacingBottom=10;strokeWidth=1;strokeColor=#BB3D00;');
myCell.parentId = cell.id;
myCell.level=cell.level+1;
myCell.direction=direction;
if(selfTopParent.direction=='bottom') {
if (cell.children.length == 1) {
var t = 0;
for (var i = 0; i < cell.parent.children.length; i++) {
if (cell.parent.children[i].id != cell.id && cell.parent.children[i].geometry.y > cell.geometry.y) {
cell.parent.children[i].geometry.y += myCell.geometry.height;
t++;
}
}
if (t > 0) {
selfTopParent.geometry.height += myCell.geometry.height;
}
};
var resize = function (cell) {
var parent = cell.parent;
if(parent.id!=1) {
if (cell.direction == 'left')cell.geometry.height = 1;
if (parent.direction == 'left') {
parent.geometry.height = 1;
if (parent.children.length > 1 && cell.geometry.x > 0) {
parent.geometry.width += 50;
parent.geometry.x -= 50;
}
resize(parent);
} else {
parent.geometry.height = parent.children[parent.children.length - 1].geometry.y;
if (parent.level != 1 && parent.parent.children.length > 1 && cell.parent.geometry.x > 0) {
for (var k = 0; k < parent.parent.children.length; k++) {
if (parent.parent.children[k].geometry.x >= parent.geometry.x)
parent.parent.children[k].geometry.x += 50;
}
}
resize(parent);
}
}
};
resize(myCell);
}
else{
myCell.geometry.y-=70;
var t=0;
if (cell.children.length == 1&&cell.geometry.y>0) {
for (var i = 0; i < cell.parent.children.length; i++) {
if(cell.parent.children[i].geometry.y>0 && cell.parent.children[i].geometry.y>=cell.geometry.y){
cell.parent.children[i].geometry.y+=cell.geometry.height;
t++;
}
}
cell.parent.geometry.height += myCell.geometry.height;
cell.parent.geometry.y -= myCell.geometry.height;
};
var resize = function (cell) {
if (cell.direction == 'left') {
cell.geometry.height = 1;
if(cell.children.length>1){
for (var k = 0; k < cell.children.length; k++) {
if (cell.children[k].geometry.x <= cell.geometry.x)
cell.children[k].geometry.x += 50;
}
cell.geometry.x-=50;
cell.geometry.width+=50;
}
}
else {
if(cell.children.length>1){
for (var k = 0; k < cell.children.length; k++) {
if (cell.children[k].geometry.x >= cell.geometry.x)
cell.children[k].geometry.x += 50;
}
cell.geometry.x-=50;
}
}
};
resize(myCell.parent);
}
};
var insertTopLevel=function(){
var direction='bottom';
if(myChild.length%2==0){
direction='top';
}
model.beginUpdate();
x = cell.geometry.x - (myChild.length / 2 * 100) - (myChild.length + 1) * 30;
if(myChild.length>0) {
x = myChild[0].geometry.x;
for (var t = 0; t < myChild.length; t++) {
if (myChild[t].geometry.x < x) {
x = myChild[t].geometry.x;
}
}
}
x-=100;
if (myChild.length % 2 == 0) {
y = cell.geometry.y - 30;
} else {
y = cell.geometry.y + 45;
}
if (!text)text = '分支主题';
var vAlign='top';
var dir='north';
var align='right';
if (myChild.length % 2 == 0) {
vAlign='bottom';
dir='south';
align='left';
}
var myCell = graph.insertVertex(graph.getDefaultParent(), null, text, x, y, 1, 70, 'shape=line;align='+align+';verticalAlign='+vAlign+';direction='+dir+';verticalLabelPosition=middle;fontSize=18;strokeWidth=1;strokeColor=#8C8C00;');
myCell.parentId = cell.id;
myCell.level=cell.level+1;
myCell.direction=direction;
model.endUpdate();
graph.clearSelection();
};
var insert=function(){
if(cell.level==0){
insertTopLevel();
}else{
if(isSub){
insertSubLevel();
}else{
insertSameLevel();
}
}
};
var insertSameLevel=function(){
if(cell.level){
if(cell.level==1){
cell=fish.getCellById('fishboneHead');
myChild = fish.getChildSubject(cell);
insertTopLevel();
}else{
cell=cell.parent;
myChild = cell.children;
insertSubLevel();
}
}else{
cell=cell.parent;
myChild = cell.children;
insertTopLevel();
}
};
var insertSubLevel=function(){
switch (cell.direction){
case 'left':
insertVerticalSubLevel();
break;
case 'top':
case 'bottom':
insertHorizontalSubLevel();
break;
}
graph.refresh();
};
insert();
};
fishBone.prototype.getChildSubject=function(cell){
var allCells=this.graph.model.root.children[0].children;
var children=[];
for(var i=0;i