UNPKG

juijs-chart

Version:

SVG-based JUI chart that can be used in the browser and Node.js. Support many types of charts. (Dashboard, Map, Topology, Full 3D)

247 lines (207 loc) 10.1 kB
import jui from '../main.js'; export default { name: "chart.brush.bar", extend: "chart.brush.core", component: function() { var _ = jui.include("util.base"); var BarBrush = function() { var g; var zeroX, height, half_height, bar_height; this.getBarStyle = function() { return { borderColor: this.chart.theme("barBorderColor"), borderWidth: this.chart.theme("barBorderWidth"), borderOpacity: this.chart.theme("barBorderOpacity"), borderRadius: this.chart.theme("barBorderRadius"), disableOpacity: this.chart.theme("barDisableBackgroundOpacity"), circleColor: this.chart.theme("barPointBorderColor") } } this.getBarElement = function(dataIndex, targetIndex, info) { var style = this.getBarStyle(), color = this.color(dataIndex, targetIndex), value = this.getData(dataIndex)[this.brush.target[targetIndex]]; var r = this.chart.svg.pathRect({ width: info.width, height: info.height, fill : color, stroke : style.borderColor, "stroke-width" : style.borderWidth, "stroke-opacity" : style.borderOpacity }); if(value != 0) { this.addEvent(r, dataIndex, targetIndex); } if(this.barList == null) { this.barList = []; } this.barList.push(_.extend({ element: r, color: color }, info)); return r; } this.setActiveEffect = function(r) { var style = this.getBarStyle(), cols = this.barList; for(var i = 0; i < cols.length; i++) { var opacity = (cols[i] == r) ? 1 : style.disableOpacity; cols[i].element.attr({ opacity: opacity }); if(cols[i].minmax) { cols[i].minmax.style(cols[i].color, style.circleColor, opacity); } } } this.drawBefore = function() { var op = this.brush.outerPadding, ip = this.brush.innerPadding, len = this.brush.target.length; g = this.chart.svg.group(); zeroX = this.axis.x(0); height = this.axis.y.rangeBand(); if(this.brush.size > 0) { bar_height = this.brush.size; half_height = (bar_height * len) + ((len - 1) * ip); } else { half_height = height - (op * 2); bar_height = (half_height - (len - 1) * ip) / len; bar_height = (bar_height < 0) ? 0 : bar_height; } } this.drawETC = function(group) { if(!_.typeCheck("array", this.barList)) return; var self = this, style = this.getBarStyle(); // 액티브 툴팁 생성 this.active = this.drawTooltip(); group.append(this.active.tooltip); for(var i = 0; i < this.barList.length; i++) { var r = this.barList[i], d = this.brush.display; // Max & Min 툴팁 생성 if((d == "max" && r.max) || (d == "min" && r.min) || d == "all") { r.minmax = this.drawTooltip(r.color, style.circleColor, 1); r.minmax.control(r.position, r.tooltipX, r.tooltipY, this.format(r.value)); group.append(r.minmax.tooltip); } // 컬럼 및 기본 브러쉬 이벤트 설정 if(r.value != 0 && this.brush.activeEvent != null) { (function(bar) { self.active.style(bar.color, style.circleColor, 1); bar.element.on(self.brush.activeEvent, function(e) { self.active.style(bar.color, style.circleColor, 1); self.active.control(bar.position, bar.tooltipX, bar.tooltipY, self.format(bar.value)); self.setActiveEffect(bar); }); bar.element.attr({ cursor: "pointer" }); })(r); } } // 액티브 툴팁 위치 설정 var r = this.barList[this.brush.active]; if(r != null) { this.active.style(r.color, style.circleColor, 1); this.active.control(r.position, r.tooltipX, r.tooltipY, this.format(r.value)); this.setActiveEffect(r); } } this.draw = function() { var points = this.getXY(), style = this.getBarStyle(); this.eachData(function(data, i) { var startY = this.offset("y", i) - (half_height / 2); for(var j = 0; j < this.brush.target.length; j++) { var value = data[this.brush.target[j]], tooltipX = this.axis.x(value), tooltipY = startY + (bar_height / 2), position = (tooltipX >= zeroX) ? "right" : "left"; // 최소 크기 설정 if(Math.abs(zeroX - tooltipX) < this.brush.minSize) { tooltipX = (position == "right") ? tooltipX + this.brush.minSize : tooltipX - this.brush.minSize; } var width = Math.abs(zeroX - tooltipX), radius = (width < style.borderRadius || bar_height < style.borderRadius) ? 0 : style.borderRadius, r = this.getBarElement(i, j, { width: width, height: bar_height, value: value, tooltipX: tooltipX, tooltipY: tooltipY, position: position, max: points[j].max[i], min: points[j].min[i] }); if(tooltipX >= zeroX) { r.round(width, bar_height, 0, radius, radius, 0); r.translate(zeroX, startY); } else { r.round(width, bar_height, radius, 0, 0, radius); r.translate(zeroX - width, startY); } // 그룹에 컬럼 엘리먼트 추가 g.append(r); // 다음 컬럼 좌표 설정 startY += bar_height + this.brush.innerPadding; } }); this.drawETC(g); return g; } this.drawAnimate = function(root) { var svg = this.chart.svg, type = this.brush.animate; root.append( svg.animate({ attributeName: "opacity", from: "0", to: "1", begin: "0s" , dur: "1.4s", repeatCount: "1", fill: "freeze" }) ); root.each(function(i, elem) { if(elem.is("util.svg.element.path")) { var xy = elem.data("translate").split(","), x = parseInt(xy[0]), y = parseInt(xy[1]), w = parseInt(elem.attr("width")), start = (type == "right") ? x + w : x - w; elem.append(svg.animateTransform({ attributeName: "transform", type: "translate", from: start + " " + y, to: x + " " + y, begin: "0s", dur: "0.7s", repeatCount: "1", fill: "freeze" })); } }); } } BarBrush.setup = function() { return { /** @cfg {Number} [size=0] Set a fixed size of the bar. */ size: 0, /** @cfg {Number} [minSize=0] Sets the minimum size as it is not possible to draw a bar when the value is 0. */ minSize: 0, /** @cfg {Number} [outerPadding=2] Determines the outer margin of a bar. */ outerPadding: 2, /** @cfg {Number} [innerPadding=1] Determines the inner margin of a bar. */ innerPadding: 1, /** @cfg {Number} [active=null] Activates the bar of an applicable index. */ active: null, /** @cfg {String} [activeEvent=null] Activates the bar in question when a configured event occurs (click, mouseover, etc). */ activeEvent: null, /** @cfg {"max"/"min"/"all"} [display=null] Shows a tool tip on the bar for the minimum/maximum value. */ display: null, /** @cfg {Function} [format=null] Sets the format of the value that is displayed on the tool tip. */ format: null }; } return BarBrush; } }