UNPKG

datavizstocklib

Version:

测试一下呗

472 lines (433 loc) 14.9 kB
import * as d3 from "d3"; import $ from "jquery"; var infoPanel = { svg: {}, el: "aa", /** * 初始化信息展示面板 */ initInfoPanel: function (targetSvg, elDiv, fontfamily) { this.svg = targetSvg; this.el = elDiv; this.svg .append("rect") .attr("id", "infoPanelBG" + this.el) .attr("width", 0) .attr("height", 32) .attr("x", 0) .attr("y", 0) .attr("fill", "#333333") .attr("fill-opacity", 0.8) .attr("display", "block"); this.svg .append("text") .attr("id", "infoId" + this.el) .text("") .attr("font-size", 12) .attr("font-family", fontfamily) .attr("fill", "#FFFFFF") .attr("width", 0) .attr("height", 0) .attr("x", 0) .attr("y", 0) .attr("display", "block"); this.svg .append("text") .attr("id", "infoValue" + this.el) .text("") .attr("font-size", 12) .attr("font-family", fontfamily) .attr("fill", "#FFFFFF") .attr("width", 0) .attr("height", 0) .attr("x", 0) .attr("y", 0) .attr("display", "block"); this.svg .append("text") .attr("id", "mdValue" + this.el) .text("") .attr("font-size", 12) .attr("font-family", fontfamily) .attr("fill", "#FFFFFF") .attr("width", 0) .attr("height", 0) .attr("x", 0) .attr("y", 0) .attr("display", "block"); this.svg .append("text") .attr("id", "mdId" + this.el) .text("") .attr("font-size", 12) .attr("font-family", fontfamily) .attr("fill", "#FFFFFF") .attr("width", 0) .attr("height", 0) .attr("x", 0) .attr("y", 0) .attr("display", "block"); }, /** * 展示隐藏信息 */ showInfoPanel: function (id, value, thisxy, elDiv) { let text = this.formatNum(value) + " 亿元"; this.showInfoPanel2(id, value, thisxy, elDiv, text); }, showInfoPanel2: function (id, value, thisxy, elDiv, t, md, industry, chartType) { var text = d3.select("#" + id).attr("memo"); var idLen = text.length * 2; var valueLen = String(value).length + 3; var bgWidth; if (idLen > valueLen) { bgWidth = idLen * 6 + 20; } else { bgWidth = valueLen * 6 + 20; } var thisX = thisxy[0] - bgWidth - 5; var thisY = thisxy[1] - 39 - 5; if (thisX > thisxy[0]) { thisX = thisxy[0]; } var idX = thisX + (bgWidth - idLen * 6) / 2; var idY = thisY + 5 + 11; var valueX = thisX + (bgWidth - (valueLen + 2) * 6) / 2; if (chartType == 'dupont' || chartType == 'valueper') { valueX = thisX + (bgWidth - idLen * 6) / 2; } var valueY = thisY + 22 + 11; let mdwidth = 0 if (industry) { mdwidth = (String(industry).length + 3) * 6 + 20; bgWidth = mdwidth * 2; thisX = thisX + 5 } let h = 39 if (md) h = h + 40 d3.select("#infoPanelBG" + elDiv) .attr("width", bgWidth) .attr("height", h) .attr("x", thisX) .attr("y", thisY) .attr("display", "block"); d3.select("#infoId" + elDiv) .text(text) .attr("x", idX) .attr("y", idY) .attr("display", "block"); d3.select("#infoValue" + elDiv) .text(t) .attr("x", valueX) .attr("y", valueY) .attr("display", "block"); if (md) { d3.select("#mdId" + elDiv) .text("中位值(" + industry + ")") .attr("x", idX) .attr("y", idY + 40) .attr("display", "block"); d3.select("#mdValue" + elDiv) .text(md) .attr("x", valueX) .attr("y", valueY + 40) .attr("display", "block"); } d3.select("#" + id).attr("fill-opacity", Number(d3.select("#" + id).attr("fill-opacity")) - 0.3); }, /** * 移动信息展示面板 */ moveInfoPanel: function (id, value, thisxy, elDiv) { let t = this.formatNum(value) + " 亿元"; this.moveInfoPanel2(id, value, thisxy, elDiv, t) }, /** * 移动信息展示面板 */ moveInfoPanel2: function (id, value, thisxy, elDiv, t, md, industry, chartType) { var text = d3.select("#" + id).attr("memo"); var idLen = text.length * 2; var valueLen = String(value).length + 3; var bgWidth; if (idLen > valueLen) { bgWidth = idLen * 6 + 20; } else { bgWidth = valueLen * 6 + 20; } var thisX = thisxy[0] - bgWidth - 5; var thisY = thisxy[1] - 39 - 5; if (bgWidth > thisxy[0]) { thisX = thisxy[0] + 10; } if (60 > thisxy[1]) { thisY = 40; } var idX = thisX + (bgWidth - idLen * 6) / 2; var idY = thisY + 5 + 11; var valueX = thisX + (bgWidth - (valueLen + 2) * 6) / 2; if (chartType == 'dupont' || chartType == 'valueper') { valueX = thisX + (bgWidth - idLen * 6) / 2; } var valueY = thisY + 22 + 11; let mdwidth = 0 if (industry) { mdwidth = (String(industry).length + 3) * 6 + 20; bgWidth = mdwidth * 2; thisX = thisX + 5 } let h = 39 if (md) h = h + 40 d3.select("#infoPanelBG" + elDiv) .attr("width", bgWidth) .attr("height", h) .attr("x", thisX) .attr("y", thisY) .attr("display", "block"); d3.select("#infoId" + elDiv) .text(text) .attr("x", idX) .attr("y", idY) .attr("display", "block"); d3.select("#infoValue" + elDiv) .text(t) .attr("x", valueX) .attr("y", valueY) .attr("display", "block"); if (md) { d3.select("#mdId" + elDiv) .text("中位值(" + industry + ")") .attr("x", idX) .attr("y", idY + 40) .attr("display", "block"); d3.select("#mdValue" + elDiv) .text(md) .attr("x", valueX) .attr("y", valueY + 40) .attr("display", "block"); } }, /** * 隐藏信息展示面板 */ hideInfoPanel: function (id, elDiv) { d3.select("#infoPanelBG" + elDiv) .attr("display", "none") .attr("width", 0) .attr("height", 39) .attr("x", 0) .attr("y", 0); d3.select("#infoId" + elDiv) .attr("display", "none") .text("") .attr("x", 0) .attr("y", 0); d3.select("#infoValue" + elDiv) .attr("display", "none") .text("") .attr("x", 0) .attr("y", 0); d3.select("#mdId" + elDiv) .attr("display", "none") .text("") .attr("x", 0) .attr("y", 0); d3.select("#mdValue" + elDiv) .attr("display", "none") .text("") .attr("x", 0) .attr("y", 0); d3.select("#" + id).attr("fill-opacity", Number(d3.select("#" + id).attr("fill-opacity")) + 0.3); }, /** * 格式化数字 */ formatNum: function (num) { return parseFloat(num).toLocaleString(); }, /** * 数组浅copy */ copyArray: function (arrays) { let arr = []; for (let i = 1; i < arrays.length; i++) { arr.push(arrays[i]); } return arr; }, /** * 画直线 * @param {String} svgTarget svg 目标 * @param {double} x1 * @param {double} y1 * @param {double} x2 * @param {double} y2 * @param {double} w 线宽度 * @param {String} c 颜色 */ addLineForDataviz(svgTarget, x1, y1, x2, y2, w, c) { svgTarget.append("line") .attr("x1", x1) .attr("y1", y1) .attr("x2", x2) .attr("y2", y2) .attr("stroke-width", w) .attr("stroke", c); }, /** * 阴影处理 * @param {String} id */ black(id) { var defs = this.svg.append("defs"); // create filter with id #drop-shadow // height=130% so that the shadow is not clipped if (id == undefined || id == "") { id = "drop-shadow"; } var filter = defs.append("filter") .attr("id", id) .attr("height", "200%") .attr("width", "200%"); // SourceAlpha refers to opacity of graphic that this filter will be applied to // convolve that with a Gaussian with standard deviation 3 and store result // in blur filter.append("feGaussianBlur") // .attr("in", "SourceAlpha") .attr("in", "SourceGraphic") .attr("stdDeviation", 1.5) .attr("result", "blur"); // translate output of Gaussian blur to the right and downwards with 2px // store result in offsetBlur filter.append("feOffset") .attr("in", "blur") .attr("dx", 1) .attr("dy", 1) .attr("result", "offsetBlur"); // overlay original SourceGraphic over translated blurred opacity by using // feMerge filter. Order of specifying inputs is important! var feMerge = filter.append("feMerge"); feMerge.append("feMergeNode") .attr("in", "offsetBlur") feMerge.append("feMergeNode") .attr("in", "SourceGraphic"); }, /** * 渐变定义 * @param {String } name 类名 * @param {String} start 开始颜色 * @param {String} end 结束颜色 * @param {String} rate 方向 默认为0 0/水平 1/垂直 2/左到右向上对角线 3/左到右向下对角线 */ gradient(target, name, start, end, rate) { let x1 = '0%', y1 = '0%', x2 = '100%', y2 = '0%'; if (rate == 1) { x1 = '0%'; y1 = '0%'; x2 = '0%'; y2 = '100%'; } else if (rate == 2) { x1 = '0%', y1 = '100%', x2 = '100%', y2 = '0%'; } else if (rate == 3) { x1 = '0%', y1 = '0%', x2 = '100%', y2 = '100%'; } var gradient = target.append("svg:defs") .append("svg:linearGradient") .attr("id", name) .attr("x1", x1) .attr("y1", y1) .attr("x2", x2) .attr("y2", y2) .attr("spreadMethod", "pad"); // Define the gradient colors gradient.append("svg:stop") .attr("offset", "0%") .attr("stop-color", start) .attr("stop-opacity", 1); gradient.append("svg:stop") .attr("offset", "100%") .attr("stop-color", end) .attr("stop-opacity", 1); }, // A helper function for formatting dec2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }, /** * * * @param {int} start 轴开始位置 * @param {int} end 轴结束位置 * @param {String} startColor 开始颜色 * @param {String} endColor 结束颜色 * */ colorBandForX(start, end, startColor, endColor) { let s = parseFloat(start); let e = parseFloat(end); let sp = e - s; let res = this.colorBand(startColor, endColor, 1000); let step = sp / 1000.0; return { "start": start, "end": end, "step": step, "cls": res }; }, /** * 计算色阶 * @param {String} startColor 开始色值 * @param {String} endColor 结束色值 * @param {int} bands 记录条数 */ colorBand(startColor, endColor, bands) { var a = this.colorRgb(startColor), // First color b = this.colorRgb(endColor), // Other color i, delta = []; // Difference between color in each channel // Compute difference between each color for (i = 0; i < 4; i++) { delta[i] = (a[i] - b[i]) / (bands + 1); } var res = []; // Use that difference to create your bands for (i = 0; i < bands; i++) { var r = Math.round(a[0] - delta[0] * i); var g = Math.round(a[1] - delta[1] * i); var b = Math.round(a[2] - delta[2] * i); res.push("#" + this.dec2hex(r) + this.dec2hex(g) + this.dec2hex(b)); } return res; }, colorRgb(c) { var sColor = c.toLowerCase(); var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; if (sColor && reg.test(sColor)) { if (sColor.length === 4) { var sColorNew = "#"; for (var i = 1; i < 4; i += 1) { sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)); } sColor = sColorNew; } //处理六位的颜色值 var sColorChange = []; for (var i = 1; i < 7; i += 2) { sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2))); } return sColorChange; } else { return sColor; } }, /** * randomWord 产生长度随机字母数字组合 */ randomWord(len) { len = len || 8; var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/ var maxPos = $chars.length; var pwd = ''; for (var i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } } export default infoPanel;