/*
** Views/Partial/LCA/BOM.cshtml is using this controller
*/
angular.module('CarbonFootprint')
.controller('LifecycleFlowChartController', ['$scope', '$routeParams', 'Notification',
function ($scope, $routeParams, Notification) {
main(document.getElementById('graphContainer'));
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
function main(container) {
// Checks if browser is supported
if (!mxClient.isBrowserSupported()) {
// Displays an error message if the browser is
// not supported.
mxUtils.error('Browser is not supported!', 200, false);
}
else {
//// Creates a wrapper editor around a new graph inside
//// the given container using an XML config for the
//// keyboard bindings
//var config = mxUtils.load(
// 'Scripts/mxgraph/editors/config/keyhandler-commons.xml').
// getDocumentElement();
//var editor = new mxEditor(config);
//editor.setGraphContainer(container);
//var graph = editor.graph;
//var model = graph.getModel();
// Creates the graph inside the given container
var graph = new mxGraph(container);
var model = graph.getModel();
// Disables folding
graph.isCellFoldable = function (cell, collapse) {
return false;
};
// Auto-resizes the container
graph.border = 80;
graph.getView().translate = new mxPoint(graph.border / 2, graph.border / 2);
graph.setResizeContainer(true);
graph.graphHandler.setRemoveCellsFromParent(false);
// Changes the default vertex style in-place
var style = graph.getStylesheet().getDefaultVertexStyle();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE;
style[mxConstants.STYLE_VERTICAL_ALIGN] = 'middle';
style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = 'white';
style[mxConstants.STYLE_FONTSIZE] = 11;
style[mxConstants.STYLE_STARTSIZE] = 22;
style[mxConstants.STYLE_HORIZONTAL] = false;
style[mxConstants.STYLE_FONTCOLOR] = 'black';
style[mxConstants.STYLE_STROKECOLOR] = 'black';
delete style[mxConstants.STYLE_FILLCOLOR];
style = mxUtils.clone(style);
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_FONTSIZE] = 10;
style[mxConstants.STYLE_ROUNDED] = false;
style[mxConstants.STYLE_HORIZONTAL] = true;
style[mxConstants.STYLE_VERTICAL_ALIGN] = 'middle';
delete style[mxConstants.STYLE_STARTSIZE];
style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = 'none';
graph.getStylesheet().putCellStyle('process', style);
style = mxUtils.clone(style);
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.EllipsePerimeter;
delete style[mxConstants.STYLE_ROUNDED];
graph.getStylesheet().putCellStyle('state', style);
style = mxUtils.clone(style);
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RHOMBUS;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RhombusPerimeter;
style[mxConstants.STYLE_VERTICAL_ALIGN] = 'top';
style[mxConstants.STYLE_SPACING_TOP] = 40;
style[mxConstants.STYLE_SPACING_RIGHT] = 64;
graph.getStylesheet().putCellStyle('condition', style);
style = mxUtils.clone(style);
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_DOUBLE_ELLIPSE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.EllipsePerimeter;
style[mxConstants.STYLE_SPACING_TOP] = 28;
style[mxConstants.STYLE_FONTSIZE] = 14;
style[mxConstants.STYLE_FONTSTYLE] = 1;
delete style[mxConstants.STYLE_SPACING_RIGHT];
graph.getStylesheet().putCellStyle('end', style);
style = graph.getStylesheet().getDefaultEdgeStyle();
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_BLOCK;
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_FONTCOLOR] = 'black';
style[mxConstants.STYLE_STROKECOLOR] = 'black';
style = mxUtils.clone(style);
style[mxConstants.STYLE_DASHED] = true;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_OPEN;
style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_OVAL;
graph.getStylesheet().putCellStyle('crossover', style);
// Installs double click on middle control point and
// changes style of edges between empty and this value
graph.alternateEdgeStyle = 'elbow=vertical';
// Adds automatic layout and various switches if the
// graph is enabled
if (graph.isEnabled()) {
// Allows new connections but no dangling edges
graph.setConnectable(true);
graph.setAllowDanglingEdges(false);
// End-states are no valid sources
var previousIsValidSource = graph.isValidSource;
graph.isValidSource = function (cell) {
if (previousIsValidSource.apply(this, arguments)) {
var style = this.getModel().getStyle(cell);
return style == null || !(style == 'end' || style.indexOf('end') == 0);
}
return false;
};
// Start-states are no valid targets, we do not
// perform a call to the superclass function because
// this would call isValidSource
// Note: All states are start states in
// the example below, so we use the state
// style below
graph.isValidTarget = function (cell) {
var style = this.getModel().getStyle(cell);
return !this.getModel().isEdge(cell) && !this.isSwimlane(cell) &&
(style == null || !(style == 'state' || style.indexOf('state') == 0));
};
// Allows dropping cells into new lanes and
// lanes into new pools, but disallows dropping
// cells on edges to split edges
graph.setDropEnabled(false);
graph.setSplitEnabled(false);
// Returns true for valid drop operations
graph.isValidDropTarget = function (target, cells, evt) {
if (this.isSplitEnabled() && this.isSplitTarget(target, cells, evt)) {
return true;
}
var model = this.getModel();
var lane = false;
var pool = false;
var cell = false;
// Checks if any lanes or pools are selected
for (var i = 0; i < cells.length; i++) {
var tmp = model.getParent(cells[i]);
lane = lane || this.isPool(tmp);
pool = pool || this.isPool(cells[i]);
cell = cell || !(lane || pool);
}
return !pool && cell != lane && ((lane && this.isPool(target)) ||
(cell && this.isPool(model.getParent(target))));
};
// Adds new method for identifying a pool
graph.isPool = function (cell) {
var model = this.getModel();
var parent = model.getParent(cell);
return parent != null && model.getParent(parent) == model.getRoot();
};
// Changes swimlane orientation while collapsed
graph.model.getStyle = function (cell) {
var style = mxGraphModel.prototype.getStyle.apply(this, arguments);
if (graph.isCellCollapsed(cell)) {
if (style != null) {
style += ';';
}
else {
style = '';
}
style += 'horizontal=1;align=left;spacingLeft=14;';
}
return style;
};
// Keeps widths on collapse/expand
var foldingHandler = function (sender, evt) {
var cells = evt.getProperty('cells');
for (var i = 0; i < cells.length; i++) {
var geo = graph.model.getGeometry(cells[i]);
if (geo.alternateBounds != null) {
geo.width = geo.alternateBounds.width;
}
}
};
graph.addListener(mxEvent.FOLD_CELLS, foldingHandler);
}
// Applies size changes to siblings and parents
new mxSwimlaneManager(graph);
// Creates a stack depending on the orientation of the swimlane
var layout = new mxStackLayout(graph, false);
// Makes sure all children fit into the parent swimlane
layout.resizeParent = true;
// Applies the size to children if parent size changes
layout.fill = true;
// Only update the size of swimlanes
layout.isVertexIgnored = function (vertex) {
return !graph.isSwimlane(vertex);
}
// Keeps the lanes and pools stacked
var layoutMgr = new mxLayoutManager(graph);
layoutMgr.getLayout = function (cell) {
if (!model.isEdge(cell) && graph.getModel().getChildCount(cell) > 0 &&
(model.getParent(cell) == model.getRoot() || graph.isPool(cell))) {
layout.fill = graph.isPool(cell);
return layout;
}
return null;
};
// Installs a handler for click events in the graph
// that toggles the overlay for the respective cell
graph.addListener(mxEvent.CLICK, function (sender, evt) {
var cell = evt.getProperty('cell');
clickHandler(sender.selectionModel.cells[0].value);
//mxUtils.alert('Click: ' + sender.selectionModel.cells[0].value);
//evt.consume();
});
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
var parent = graph.getDefaultParent();
// Adds cells to the model in a single step
model.beginUpdate();
try {
var pool1 = graph.insertVertex(parent, null, '生命週期階段', 0, 0, 640, 0);
pool1.setConnectable(false);
var lane1a = graph.insertVertex(pool1, null, '原料取得', 0, 0, 640, 110);
lane1a.setConnectable(false);
var lane2a = graph.insertVertex(pool1, null, '上游運輸', 0, 0, 640, 110);
lane1a.setConnectable(false);
var lane3a = graph.insertVertex(pool1, null, '運作支援及服務', 0, 0, 640, 330);
lane1a.setConnectable(false);
var lane4a = graph.insertVertex(pool1, null, '下游運輸', 0, 0, 640, 110);
lane1a.setConnectable(false);
var lane5a = graph.insertVertex(pool1, null, '產品使用及廢棄', 0, 0, 640, 110);
lane1a.setConnectable(false);
var lane6a = graph.insertVertex(pool1, null, '廢棄物處裡', 0, 0, 640, 110);
lane1a.setConnectable(false);
var step11 = graph.insertVertex(lane1a, null, '半導\n體控\n制IC', 120, 15, 40, 80, 'process');
var step12 = graph.insertVertex(lane1a, null, '洗板\n水', 170, 15, 40, 80, 'process');
var step13 = graph.insertVertex(lane1a, null, '主變\n壓器', 220, 15, 40, 80, 'process');
var step14 = graph.insertVertex(lane1a, null, 'PCB', 270, 15, 40, 80, 'process');
var step15 = graph.insertVertex(lane1a, null, '一次\n側大\n電容', 320, 15, 40, 80, 'process');
var step16 = graph.insertVertex(lane1a, null, '線材', 370, 15, 40, 80, 'process');
var step17 = graph.insertVertex(lane1a, null, '外殼', 420, 15, 40, 80, 'process');
var step18 = graph.insertVertex(lane1a, null, '套袋', 470, 15, 40, 80, 'process');
var step19 = graph.insertVertex(lane1a, null, '能源\n生產\n(c4)', 560, 15, 40, 80, 'process');
var step311 = graph.insertVertex(lane3a, null, '上\n游\n租\n賃', 50, 5, 20, 190, 'process');
var step312 = graph.insertVertex(lane3a, null, '下\n游\n租\n賃', 50, 200, 20, 125, 'process');
var step320 = graph.insertVertex(lane3a, null, '', 110, 5, 420, 320, 'process');
var step321 = graph.insertVertex(step320, null, '產品開發', 70, 15, 280, 50, 'process');
var step322 = graph.insertVertex(step320, null, '製造過程', 70, 135, 280, 50, 'process');
var step323 = graph.insertVertex(step320, null, '其他支援流程', 70, 255, 280, 50, 'process');
var step331 = graph.insertVertex(lane3a, null, '能\n資\n源', 570, 5, 20, 140, 'process');
var step332 = graph.insertVertex(lane3a, null, '廢\n棄\n物', 570, 150, 20, 175, 'process');
var step5 = graph.insertVertex(lane5a, null, '產品使用階段\n及\n廢棄階段', 220, 15, 200, 80, 'process');
var step61 = graph.insertVertex(lane6a, null, '焚化', 250, 15, 40, 80, 'process');
var step62 = graph.insertVertex(lane6a, null, '回收', 300, 15, 40, 80, 'process');
var step63 = graph.insertVertex(lane6a, null, '掩埋', 350, 15, 40, 80, 'process');
var e = null;
graph.insertEdge(parent, null, null, step11, step320);
graph.insertEdge(parent, null, null, step12, step320);
graph.insertEdge(parent, null, null, step13, step320);
graph.insertEdge(parent, null, null, step14, step320);
graph.insertEdge(parent, null, null, step15, step320);
graph.insertEdge(parent, null, null, step16, step320);
graph.insertEdge(parent, null, null, step17, step320);
graph.insertEdge(parent, null, null, step18, step320);
graph.insertEdge(parent, null, null, step19, step331);
graph.insertEdge(step320, null, null, step321, step322);
graph.insertEdge(step320, null, null, step323, step322);
graph.insertEdge(lane3a, null, null, step311, step320);
e = graph.insertEdge(lane3a, null, null, step331, step320); // 能资源 -> step320
e.geometry.points = [new mxPoint(step320.geometry.x + step320.geometry.width, step331.geometry.y + step311.geometry.height / 2)];
//e.getGeometry().points = [{ x: 80, y: 10 }];
graph.insertEdge(lane3a, null, null, step320, step332);
graph.insertEdge(parent, null, null, step320, step5);
graph.insertEdge(parent, null, null, step5, step61);
graph.insertEdge(parent, null, null, step5, step62);
graph.insertEdge(parent, null, null, step5, step63);
}
finally {
// Updates the display
model.endUpdate();
}
}
};
function clickHandler(value) {
if (value == '生命週期階段') {
$scope.changeSelectedTab('LifecycleAssmt');
}
else if (value == '原料取得') {
$scope.changeSelectedTab('MaterialC3Emission');
}
else if (value == '上游運輸') {
$scope.changeSelectedTab('ItemPurchase');
}
else if (value == '運作支援及服務') {
$scope.changeSelectedTab('WaterUsage');
}
else if (value == '下游運輸') {
$scope.changeSelectedTab('ItemDelivery');
}
else if (value == '產品使用及廢棄') {
$scope.changeSelectedTab('PowerConsumption');
}
else if (value == '廢棄物處裡') {
$scope.changeSelectedTab('WasteMaterial');
}
}
}]);