Your IP : 18.219.40.177
(function(exports) {
'use strict';
var init = function() {
},
checkData = function(data) {
return true;
},
doc = document;
/**
* constructor DCMap
* @param {String} cont id of wrapper
* @constructor
*/
var DCMap = function(cont) {
this.name = 'dcmap';
this.elem = 'elem';
this.cont = cont;
this.selectedElems = {};
this.changedElems = {};
this.bound = {};
this.beforeChangeView = {};
this.toSaveElems = {};
};
DCMap.fn = DCMap.prototype;
/**
* init function
*
* @param {Object} data data of map
*/
DCMap.fn.init = function(data) {
if (checkData(data)) {
this.mdata = data;
}
};
/**
* set handler by select event element
* @param {Function} selectCallback
*/
DCMap.fn.onSelect = function(selectCallback) {
this.selectCallback = selectCallback;
};
DCMap.fn.onDblClick = function(callback) {
this.dblClickCallback = callback;
};
/**
* set handler by change event element
* @param {Function} changeCallback
*/
DCMap.fn.onChange = function(changeCallback) {
this.changeCallback = changeCallback;
};
/**
* set handler by change event element
* @param {Function} changeCallback
*/
DCMap.fn.onSave = function(saveCallback) {
this.saveCallback = saveCallback;
};
/**
* render scale ruler and workarea,
* append in page
*/
DCMap.fn.renderWorkarea = function() {
var width = this.mdata.width,
height = this.mdata.height,
scale = this.mdata.scale;
this.papper = new Svg(this.cont, width, height, scale);
this.papper.master = this;
this.papper.append();
this.papper.zoomCallback = this.renderScaleRuler;
this.renderScaleRuler();
};
/**
* get order of number
* @param {Number} number
* @return {*} order or false if is not number
*/
DCMap.fn.getOrder = function(number) {
var n = number - 0, p = 0;
if (typeof n !== 'number') {
return false;
}
while (n > 10) {
n /= 10;
p++;
}
return p;
};
/**
* get number of scale
* @param {Number} maxSize
* @return {number}
*/
DCMap.fn.getMagicNumber = function(maxSize) {
var order = this.getOrder(maxSize),
n = order - 2;
if (n < 0) {
return 1;
} else {
return Math.pow(10, n);
}
};
/**
* render Toolbar for change views
* @param {Array} views views of map
*/
DCMap.fn.renderToolbar = function(views) {
if (views && views.length > 0) {
var l = views.length, a,
self = this,
wrapper = doc.createElement('div'),
clickHandler = this.changeView.bind(this),
saveHandler = this.saveData.bind(this),
zoomInHandler = function() {
self.papper.viewBoxZoom({ direction: 1, preventDefault: function() {} });
},
zoomOutHandler = function() {
self.papper.viewBoxZoom({ direction: -1, preventDefault: function() {} });
};
wrapper.className = 'b-map-toolbar';
if (this.mdata.edit) {
a = doc.createElement('a');
a.href = '#';
a.className = 'b-map-toolbar__button b-map-toolbar__button_save_yes b-map-toolbar__button_disable_yes';
a.setAttribute('data-state', 'notactive');
a.innerHTML = this.mdata.msg.save;
wrapper.appendChild(a);
a.addEventListener('click', saveHandler);
}
for (var i = 0; i < l; i++) {
a = doc.createElement('a');
a.href = '#';
a.className = 'b-map-toolbar__button';
a.setAttribute('data-view', views[i].name);
a.innerHTML = views[i].localName;
wrapper.appendChild(a);
a.addEventListener('click', clickHandler);
}
//zoomIn
a = doc.createElement('a');
a.href = '#';
a.className = 'b-map-toolbar__button b-map-toolbar__button_zoomin';
a.innerHTML = '+';
wrapper.appendChild(a);
a.addEventListener('click', zoomInHandler);
//zoomOut
a = doc.createElement('a');
a.href = '#';
a.className = 'b-map-toolbar__button b-map-toolbar__button_zoomout';
a.innerHTML = '-';
wrapper.appendChild(a);
a.addEventListener('click', zoomOutHandler);
var contWrapper = doc.getElementById(this.cont);
var span = doc.createElement('span');
span.className = 'b-map-status';
span.innerHTML = this.mdata.msg.unsave;
wrapper.appendChild(span);
contWrapper.insertBefore(wrapper, contWrapper.lastChild);
this.renderLegend(views);
}
};
/**
* change view of map
* @param {Object} e object event
*/
DCMap.fn.changeView = function(e) {
var elem = e.target,
name = elem.getAttribute('data-view'),
viewElem, actBtn, legend,
actIdClass = 'b-map-toolbar__button_t_' + this.cont,
actClass = ' b-map-toolbar__button_active ' + actIdClass;
//detect current state
//this view is active
if (this.activeView === name) {
viewElem = doc.querySelectorAll('.view-' + name);
this.hideElements(viewElem);
this.activeView = null;
elem.className = elem.className.replace(actClass, '');
legend = doc.querySelector('.b-rack-legend_name_' + name);
if (legend) {
legend.style.display = 'none';
}
//active other view
} else {
if (this.activeView) {
viewElem = doc.querySelectorAll('.view-' + this.activeView);
this.hideElements(viewElem);
actBtn = doc.querySelector('.' + actIdClass);
actBtn.className = actBtn.className.replace(actClass, '');
legend = doc.querySelector('.b-rack-legend_name_' + this.activeView);
if (legend) {
legend.style.display = 'none';
}
}
viewElem = doc.querySelectorAll('.view-' + name);
if (this.beforeChangeView[name]) {
var hook = this.beforeChangeViewGetArgs(name);
this.visibleElements(viewElem, hook);
this.beforeChangeView[name] = false;
} else {
this.visibleElements(viewElem);
}
legend = doc.querySelector('.b-rack-legend_name_' + name);
if (legend) {
legend.style.display = 'block';
}
this.activeView = name;
elem.className += actClass;
}
e.preventDefault();
};
/**
* Save Data
*/
DCMap.fn.saveData = function() {
if (typeof this.saveCallback === 'function') {
this.saveCallback.apply({}, [this.toSaveElems, this.tabId]);
}
this.toSaveElems = {};
var status = doc.querySelector('#' + this.cont + ' .b-map-status');
if (status) {
status.classList.remove('b-map-status_active');
}
};
DCMap.fn.hideElements = function(elems) {
var l = elems.length;
while (l--) {
elems[l].setAttribute('visibility', 'hidden');
}
};
DCMap.fn.visibleElements = function(elems, hook) {
var l = elems.length;
if (hook && typeof this[hook.func] === 'function') {
var args = [''],
argLen = hook.arg.length || 0;
for (var i = 0; i < argLen; i++) {
args.push(hook.arg[i]);
}
while (l--) {
elems[l].setAttribute('visibility', 'visible');
args[0] = elems[l];
this[hook.func].apply(this, args);
}
} else {
while (l--) {
elems[l].setAttribute('visibility', 'visible');
}
}
};
DCMap.fn.renderScaleRuler = function() {
if (!this) { return; }
var width = this.papper.width,
height = this.papper.height,
scale = this.papper.scale,
maxSize = (width > height) ? width : height,
magicNumber = this.getMagicNumber(maxSize),
countW = Math.round(width / magicNumber),
countH = Math.round(height / magicNumber),
count = (countW > countH) ? countW : countH,
g = this.papper.group('scale-ruler', { id: 'scaleruler' }),
scaleruler = this.papper.elems.scaleruler,
elem, y2, x;
//@todo uniq name
//remove if exist
if (scaleruler) {
scaleruler.elem.parentNode.removeChild(scaleruler.elem);
}
for (var i = 0; i < count; i++) {
if (i % 10 === 0) {
y2 = 5 * scale;
} else if (i % 5 === 0) {
y2 = 3 * scale;
} else {
y2 = 2 * scale;
}
x = i * magicNumber;
if (i < countW) {
elem = this.papper.line('scaleruler-x-' + i, { x1: x, x2: x, y1: '0', y2: y2, stroke: '#000', 'stroke-width': scale });
g.appendChild(elem);
}
if (i < countH) {
elem = this.papper.line('scaleruler-y-' + i, { x1: 0, x2: y2, y1: x, y2: x, stroke: '#000', 'stroke-width': scale });
g.appendChild(elem);
}
}
this.papper.appendChild(g);
this.papper.elems.scaleruler = g;
};
/**
* render layer
* @param {Object} current current layer
* @param {Object} layer layers data
* @param {Array} views array with objects views
* @param {Object} objects object with object type on the map
*/
DCMap.fn.renderLayer = function(current, layer, views, objects) {
var elems = layer.elems,
childLayer = layer.layers,
viewsLen = views ? views.length : 0, viewElem,
eLen, elem, cObj, shape, attr, svgElem, gEl, innerObj, innerElem,
transform, innerAttr, line, lineAttr, transformProp,
scale = this.mdata.scale || 1,
g = this.papper.group(layer.name, { id: layer.name }),
showHint;
if (elems) {
eLen = elems.length;
//go to elements
for (var j = 0; j < eLen; j++) {
elem = elems[j];
cObj = objects[elem.oName];
//detect shape
shape = cObj.shape;
if (!this.papper[shape]) {
console.log("don't have this shape: " + shape);
continue;
}
attr = {
'class': cObj.name,
width: elem.width,
height: elem.height,
y: elem.top,
x: elem.left,
'stroke-width': 1 * scale,
stroke: '#666'
};
//set transform
if (elem.direction && elem.direction !== 360) {
transform = 'rotate(' + elem.direction + ', ' + (elem.left - 0 + elem.width / 2) + ', ' + (elem.top - 0 + elem.height / 2) + ')';
transformProp = { 'direction': elem.direction };
} else {
transform = null;
}
if (transform) { attr.transform = transform; }
if (elem.elid) { attr.elid = elem.elid; }
if (cObj.color) { attr.fill = cObj.color; }
if (shape === 'image') { attr.href = { ns: 'xlink', v: pageInfo.commonDir + 'img/' + cObj.img + '.png' }; }
svgElem = this.papper[shape](cObj.name, attr, transformProp);
//overlay for hint
delete attr.color;
delete attr.stroke;
attr.fill = '#FFFFFF';
attr['fill-opacity'] = '0.0';
var overlay = this.papper[shape](cObj.name, attr, transformProp);
svgElem.children.push(overlay);
overlay.parent = svgElem;
delete attr['fill-opacity'];
//render inner elems
if (cObj.innerObj || cObj.edit) {
gEl = this.papper.group('g-' + cObj.name, { id: 'g-' + elem.elid });
gEl.appendChild(svgElem);
innerObj = cObj.innerObj;
//render inner objects
/* jslint forin:true */
for (var keyVar in innerObj) {
innerAttr = { y: elem.top - 0 + 20 * scale, x: elem.left - 0 + 15 * scale, 'font-size': 20 * scale };
if (transform) {
if (keyVar !== 'text') {
innerAttr.transform = transform;
} else if (elem.direction > 125 && elem.direction < 225) {
innerAttr.transform = 'rotate(' + 0 + ', ' + (elem.left - 0 + elem.width / 2) + ', ' + (elem.top - 0 + elem.height / 2) + ')';
} else {
innerAttr.transform = transform;
}
}
if (this.papper[keyVar]) {
innerElem = this.papper[keyVar](innerObj[keyVar], elem[innerObj[keyVar]], innerAttr, transformProp);
gEl.appendChild(innerElem);
svgElem.children.push(innerElem);
innerElem.parent = svgElem;
}
}
var parentEl, value, l;
//append in element view state
for (var i = 0; i < viewsLen; i ++) {
if (elem[views[i].name] || elem[views[i].name + '_used']) {
parentEl = {};
parentEl.attr = attr;
parentEl.shape = shape;
parentEl.transformProp = transformProp;
value = elem[views[i].name] ? elem[views[i].name] : elem;
viewElem = this.renderViewElem(value, views[i], parentEl);
if (views[i].type === 'color' && views[i].gradient === 'relative') {
this.getBounds(views[i].name, elem[views[i].name]);
this.beforeChangeView[views[i].name] = 'relativeGradient';
}
if (viewElem) {
l = viewElem.length;
if (l) {
gEl.appendChild(viewElem[0]);
for (var k = 1; k < l; k++) {
svgElem.children.push(viewElem[k]);
// viewElem.parent = svgElem;
}
} else {
gEl.appendChild(viewElem);
svgElem.children.push(viewElem);
viewElem.parent = svgElem;
}
}
}
}
//render line direction
lineAttr = { y: elem.top, x: elem.left, width: elem.width, height: 5 * scale, stroke: '#ccc' };
if (transform) { lineAttr.transform = transform; }
line = this.papper.rect('line-' + elem.elid, lineAttr, transformProp);
gEl.appendChild(line);
svgElem.children.push(line);
line.parent = svgElem;
//add event listerner
if (cObj.edit) {
// svgElem.onDrag(this, this.dragElemHandler, this.moveElemHandler, this.dropElemHandler);
svgElem.onDrag(this, this.dragElemHandler, this.moveElemHandler, this.dropElemHandler);
svgElem.changeFunc = cObj.drag;
svgElem.draged = true;
}
//add direction control
if (cObj.edit) {
svgElem.rotated = true;
var rcAttr = {
y: (elem.top - 8 * scale) + (elem.height - 0),
x: (elem.left - 8 * scale) + (elem.width - 0),
stroke: '#ccc',
height: 16 * scale,
width: 16 * scale };
if (transform) {
rcAttr.transform = transform;
}
var rotateControl = this.papper.rect('rotate-' + elem.elid, rcAttr, transformProp);
gEl.appendChild(rotateControl);
svgElem.children.push(rotateControl);
rotateControl.parent = svgElem;
rotateControl.onRotate(this, null, null, this.dropRotateElemHandler);
svgElem.dropRotateCallback = this.dropRotateElemHandler;
}
}
//append overlay after all children
gEl.appendChild(overlay);
//add select listern
if (elem.elid !== undefined) {
svgElem.onSelect(this, this.selectElem);
}
if (elem.elid !== undefined && !cObj.edit) {
svgElem.onSelectOnly(overlay);
}
//add listener dblclick
if (elem.elid !== undefined) {
svgElem.onDblclick(this, this.dblClickCallback);
if (overlay) {
overlay.onDblclick(this, this.dblClickCallback);
}
}
if (cObj.edit) {
elem.msg = this.mdata.msg;
showHint = this.showHint.bind(elem);
overlay.elem.addEventListener('mouseover', showHint);
overlay.elem.addEventListener('mouseout', this.hideHint);
} else if (innerObj && innerObj.hint && overlay) {
var showActHint = this.showActHint.bind(elem);
overlay.elem.addEventListener('mouseover', showActHint);
overlay.elem.addEventListener('mouseout', this.hideHint);
overlay.elem.setAttribute('data-elid', elem.elid);
overlay.elem.setAttribute('data-name', elem.oName);
overlay.elem.setAttribute('data-func', innerObj.hint);
}
//if edit elements
if (gEl) {
svgElem = gEl;
}
g.appendChild(svgElem);
}
}
current.appendChild(g);
if (childLayer) {
eLen = childLayer.length;
for (var ii = 0; ii < eLen; ii++) {
this.renderLayer(g, childLayer[ii], views, objects);
}
}
};
/**
* render view element, visible:hidden by default
* @param {String} value Value of parameter
* @param {Object} view view object
* @param {Object} parentEl Props of parent
*/
DCMap.fn.renderViewElem = function(value, view, parentEl) {
if (parentEl.shape !== 'image') {
var attr = parentEl.attr,
x, y;
attr.visibility = undefined;
attr['class'] = undefined;
attr.fill = undefined;
attr['font-size'] = undefined;
attr['data-value'] = undefined;
if (view.type === 'color') {
attr.visibility = 'hidden';
attr['class'] = 'view-' + view.name;
if (view.gradient === 'fixed') {
attr.fill = this.gradientGreenToRed(value, 0, 100);
return this.papper[parentEl.shape]('name', attr, parentEl.transformProp);
} else if (view.gradient === 'relative') {
attr['data-value'] = value;
return this.papper[parentEl.shape]('name', attr, parentEl.transformProp);
}
} else if (view.type === 'indicator') {
x = attr.x;
y = attr.y;
var group = this.papper.group('name', { 'class': 'view-' + view.name, 'visibility': 'hidden' }),
wrapper = this.papper[parentEl.shape]('name', attr, parentEl.transformProp),
text,
used = value[view.name + '_used'],
total = value[view.name + '_total'];
wrapper.attr('fill', this.gradientGreenToRed(used, 0, total));
attr['font-size'] = 20 * this.papper.scale;
attr.x = attr.x - 0 + (7 * this.papper.scale);
attr.y = attr.y - 0 + (20 * this.papper.scale);
if (parentEl.transformProp) {
if (parentEl.transformProp.direction > 125 && parentEl.transformProp.direction < 225) {
var regex = new RegExp(parentEl.transformProp.direction);
attr.transform = attr.transform.replace(regex, 0);
}
}
text = this.papper.text('name', used + ' / ' + total, attr, parentEl.transformProp);
attr.x = x;
attr.y = y;
group.appendChild(wrapper);
group.appendChild(text);
return [group, wrapper, text];
}
}
};
DCMap.fn.getBounds = function(id, value) {
value = value - 0;
if (!this.bound[id]) {
this.bound[id] = {};
this.bound[id].min = value;
this.bound[id].max = value;
} else {
var min = this.bound[id].min,
max = this.bound[id].max;
this.bound[id].min = (min > value) ? value : min;
this.bound[id].max = (max < value) ? value : max;
}
};
DCMap.fn.beforeChangeViewGetArgs = function(name) {
if (this.beforeChangeView[name] === 'relativeGradient') {
return { 'func': this.beforeChangeView[name], arg: [this.bound[name].min, this.bound[name].max] };
}
};
DCMap.fn.renderLegend = function(views) {
var l = views.length,
bl, br;
while (l--) {
if (views[l].type === 'color') {
if (views[l].gradient === 'fixed') {
bl = views[l].boundleft - 0;
br = views[l].boundright - 0;
} else {
bl = this.bound[views[l].name].min;
br = this.bound[views[l].name].max;
}
var step = Math.floor(((br - bl) / 10)),
html = '<h3 class="b-rack-legend__title">' + views[l].localName + '</h3>',
curValue = bl,
toTen = step % 10,
count = 10;
if (toTen !== 0) {
if ((curValue % 10) !== 0) {
curValue -= (curValue % 10);
}
toTen = 10 - toTen;
step = step + toTen;
count = Math.floor(br / step);
}
for (var i = 0; i <= count; i++) {
html += '<div class="b-rack-legend__item"><span class="b-rack-legend__color" style="background-color: ' + this.gradientGreenToRed(curValue, bl, br) + ';">' +
'</span><span class="b-rack-legend__value">' + Math.floor(curValue) + '</span></div>';
curValue += step;
}
var div = doc.createElement('div');
div.className = 'b-rack-legend b-rack-legend_dcmap b-rack-legend_name_' + views[l].name;
div.innerHTML = html;
this.papper.cont.appendChild(div);
}
}
};
/**
* trigger event for show hint
* @param {Object} e
*/
DCMap.fn.showHint = function(e) {
var hintElem = doc.querySelector('body'),
event = new CustomEvent('showHintMap', { 'detail': { props: this, elem: e.srcElement }});
hintElem.dispatchEvent(event);
};
DCMap.fn.showActHint = function(e) {
var hintElem = doc.querySelector('body'),
event = new CustomEvent('hintActiveShowHandler', { 'detail': { elem: e.srcElement }});
hintElem.dispatchEvent(event);
};
/**
* trigger event for hide hint
*/
DCMap.fn.hideHint = function() {
var hintElem = doc.querySelector('body'),
event = new CustomEvent('hideHint');
hintElem.dispatchEvent(event);
};
/**
*
*/
DCMap.fn.stopShowHint = function() {
if (this.runHandler !== true) {
setTimeout(function() {
var hintElem = doc.querySelector('body'),
event = new CustomEvent('stopShowHint');
hintElem.dispatchEvent(event);
}, 200);
}
};
DCMap.fn.relativeGradient = function(elem, min, max) {
var value = elem.getAttribute('data-value');
elem.setAttribute('fill', this.gradientGreenToRed(value, min, max));
};
/**
* get color from number
* @param {Number} n current value
* @param {Number} m max value
* @return {string}
*/
DCMap.fn.gradientGreenToRed = function(value, min, max) {
// value is a value between 0 and max;
// 0 = green, max/2 = yellow, max = red.
var R, G,
B = 0,
bound = max - min,
halfMax = bound / 2;
if (value > halfMax) {
//yellow to red
R = 255;
G = Math.round((255 * (bound - value)) / halfMax);
} else {
//green to yellow
G = 255;
R = Math.round((255 * value) / halfMax);
}
return 'rgb(' + R + ',' + G + ',' + B + ')';
};
/**
* render Layers
* @param {Object} dataLayer
*/
DCMap.fn.renderLayers = function(dataLayer) {
var layers = dataLayer.layers,
objects = dataLayer.objects,
views = dataLayer.views,
l = layers.length;
if (l === 1) {
this.renderLayer(this.papper, layers[0], views, objects);
}
this.renderToolbar(views);
};
/**
* resize map to actual page size
* @param {Object} sizeObj
*/
DCMap.fn.resize = function(sizeObj) {
var width = sizeObj.width,
height = sizeObj.height;
if (width || height) {
if (width) {
this.papper.setWidth(width);
}
if (height) {
this.papper.setHeight(height);
}
}
};
/**
* Select element handler
* @param {jQuery object} elem
* @param {Boolean} ctrl
*/
DCMap.fn.selectElem = function(elem, ctrl) {
if (!ctrl) {
/* jslint forin:true */
for (var keyVar in this.selectedElems) {
this.selectedElems[keyVar].removeClass('selected');
this.selectedElems[keyVar].selected = false;
delete this.selectedElems[keyVar];
}
}
if (elem.selected || elem.dblclicked) {
elem.addClass('selected');
elem.selected = true;
this.selectedElems[elem.id] = elem;
} else {
elem.removeClass('selected');
delete this.selectedElems[elem.id];
}
if (typeof this.selectCallback === 'function') {
this.selectCallback.apply({}, [this.selectedElems, this]);
}
};
/**
* Drag element handler
* @param {jQuery object} elem
* @param {Object} event
*/
DCMap.fn.dragElemHandler = function(elem, event) {
var curElem;
for (var keyVar in this.selectedElems) {
if (elem.elid !== keyVar) {
curElem = this.selectedElems[keyVar];
curElem.drag.apply(curElem, [event, true]);
}
}
this.hideHint();
this.stopShowHint();
};
/**
* Move element handler
* @param {jQuery object} elem
* @param {Object} event
*/
DCMap.fn.moveElemHandler = function(elem, event) {
var curElem;
for (var keyVar in this.selectedElems) {
if (elem.id !== keyVar) {
curElem = this.selectedElems[keyVar];
curElem.move.apply(curElem, [event, true]);
}
}
this.stopShowHint();
this.runHandler = true;
};
/**
* Drop element handler
* @param {jQuery object} elem
* @param {Object} event
*/
DCMap.fn.dropElemHandler = function(elem, event) {
if (typeof this.changeCallback === 'function') {
this.changeCallback.apply({}, [this.selectedElems]);
}
this.preSaveData(this.selectedElems);
this.runHandler = false;
};
/**
* Presave changed data
* @param {Object} elems
*/
DCMap.fn.preSaveData = function(elems) {
/* jslint forin:true */
for (var keyVar in elems) {
this.toSaveElems[keyVar] = this.selectedElems[keyVar];
}
var status = doc.querySelector('#' + this.cont + ' .b-map-status');
if (status) {
status.classList.add('b-map-status_active');
}
};
/**
*
* @param {jQuery object} elem
* @param {Object} event
*/
DCMap.fn.dropRotateElemHandler = function(elem, event) {
if (typeof this.changeCallback === 'function') {
this.changeCallback.apply({}, [{ 't': elem }]);
}
var o = {};
o[elem.elid] = elem;
this.preSaveData(o);
};
/**
*
*/
DCMap.fn.forceRotate = function() {
var curElem;
/* jslint forin:true */
for (var keyVar in this.selectedElems) {
curElem = this.selectedElems[keyVar];
if (curElem.rotated) {
curElem.forceRotate();
}
}
};
/**
*
* @param {String} direction
*/
DCMap.fn.forceMove = function(direction) {
var curElem;
/* jslint forin:true */
for (var keyVar in this.selectedElems) {
curElem = this.selectedElems[keyVar];
if (curElem.draged) {
curElem.forceMove(direction);
}
}
};
exports.DCMap = DCMap;
} (window));