datavizstocklib
Version:
测试一下呗
472 lines (433 loc) • 14.9 kB
JavaScript
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;