Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

line-chart

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

line-chart - npm Package Compare versions

Comparing version 1.0.6 to 2.0.0

2

package.json
{
"name": "line-chart",
"version": "1.0.6",
"version": "2.0.0",
"description": "Line Chart",

@@ -5,0 +5,0 @@ "keywords": [

@@ -13,6 +13,8 @@ ## 雷達圖 Radar Chart

var data = [
{title: "寫作能力", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.2, basicRate:0.5, skilledRate: 0.7},
{title: "形音義", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.8, basicRate:0.6, skilledRate: 0.9},
{title: "詞句成語", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.7, basicRate:0.5, skilledRate: 0.8},
{title: "詞句成語2", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 1, basicRate:0.5, skilledRate: 0.8}
{title: "寫作能力", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.2, basicRate:0.5, skilledRate: 0.7},
{title: "形音義", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.8, basicRate:0.6, skilledRate: 0.9},
{title: "詞句成語", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.7, basicRate:0.5, skilledRate: 0.8},
{title: "java", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.01, basicRate:0.5, skilledRate: 0.8},
{title: "java", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 0.02, basicRate:0.5, skilledRate: 0.5},
{title: "java", tTitle: "精熟平均", bTitle: "基礎平均", rightRate: 1, basicRate:0.5, skilledRate: 0.8}
];

@@ -19,0 +21,0 @@

(function(){
var LineChart = {
options : {
viewBox : '0,0,1280,610',
viewBox : '0,0,1100,120',
preserveAspectRatio : "none",
chart : {width:'100%', height:'100%'},
axisZoom : 0.8, //縮放 (縱軸padding功用)
maxValue : 100, //軸的最大值
axisZoom : 1, //縮放
maxValue : 100, //軸最大值
minValue : 0, //軸的最小值
scale : 10, //軸刻度數
scaleNeedleH : 15, //刻度軸刻度垂直線高度
scaleNeedleHColor : "grey", //刻度軸刻度垂直線顏色
scaleTextGap : 0,
scaleTextOffsetH : 5,
axisHeight : 20, //line bar height
radius: {rx:0, ry:0}, //圓角
arc : 2 * Math.PI, //圓弧
top : 50, //
left: 10, //
barTop : 35,
gap : 90, //lineBar , text 通用垂直gap
hGap : 10, //lineBar 與 text 之間水平 gap
barHeight : 35,
barBackOpacity : 0.4, //lineBar 背景透明度
barBackColor : 'grey', //lineBar 背景色
scoreOpacity : 0.9, //lineBar 使用者成績透明
scoreBackColor : '#ff9800', //
surmiseFontGap: 3, //假設的font gap
color : d3.scale.category10(),
//標記
tagRadius : 6, //標記大小
tagOpacity : 0.9, //標記透明
topTagColor : '#259b24', //
bottomTagColor : '#29b6f6',
tagOffset : 15,
//指針
topNeedleColor : '#259b24',
topNeedleOpacity : 0.8,
bottomNeedleColor : '#29b6f6',
bottomNeedOpacity : 0.8,
//標記標題
topTitleGap :15,
bottomTitleGap : 15,
//user score
scoreOffsetH : 5, //使用者分數位置左水平間隔用
scoreOffsetV : 0, //使用者分數位置垂直校正用
scoreColor : 'black',
isDebug : false
zoomW : 0.85, //水平縮放係數
zoomH : 1, //垂直縮放係數
//刻度
scale : {
count : 10,
Height : 15, //刻度軸刻度垂直線高度
color : "grey", //刻度顏色
textGap : 0
},
bar :{
//繪製起點
top:0,
left:20 ,
height : 35, //條的高度
rx : 15 , //圓角x
ry : 15 , //圓角y
},
background : {
color : '#eeeeee',
opacity : 0.7, //透明
textColor : '#ff9800'
},
//bar 主要資訊
mainInfo : {
color : '#ffeb3b',
opacity : 0.9,
textColor : '#212121',
fontSize : 16,
textGapX : 5,
textGapY : 5
},
gradien : [
{ offset : '0%' , color : "#ffeb3b" , opacity : "1"},
{ offset : '50%' , color : "#fdd835" , opacity : "1"},
{ offset : '100%' , color : "#f5f5f5" , opacity : "1"},
],
//上標記
tMark : {
radius : 8,
opacity : 0.9,
color : '#673ab7',
gap : 15, //與bar的gap
lineColor : '#673ab7',
lineOpacity : 0.5,
isDash : true,
offsetY : -15,
textGapX : 15,
fontSize : 16,
text : '精熟平均'
},
//下標記
bMark : {
radius : 8,
opacity : 0.9,
color : '#5677fc',
gap : 15,
lineColor : '#29b6f6',
lineOpacity : 0.7,
isDash : true,
offsetY : 15,
textGapX : 15,
fontSize : 16,
text : '基礎平均'
}
},

@@ -63,175 +88,192 @@ mixOptions : function(options){

},
//利用三角函式計算坐標點
getPoint : function(radius, radians, offsetX, offsetY){
return {
x : radius * Math.sin(radians) + offsetX,
y : radius * Math.cos(radians) + offsetY
};
para : null,
isFloat : function(n){
return n % 1 !== 0;
},
titleWidth : 0,
//繪製軸上的標題
drawAxisText : function(svg, title, group, p, width, opt, self){
var text = group.append('text').text(title).attr('x', p.x).attr('y', p.y);
var fontSize = text.style("font-size").replace('pt','').replace('px','') | 0;
var gapTotal = opt.surmiseFontGap * (title.length - 1);
var offsetW = (fontSize * title.length + gapTotal) ; //
if(offsetW > self.titleWidth)
self.titleWidth = offsetW;
formatStr : function(val){
return (val * 100 | 0) / 100;
},
//繪製bar
drawLineBar : function(svg, group, p, minLength, color, opacity, opt, self){
group.append('rect')
.attr('x', p.x)
.attr('y', p.y)
.attr('width', minLength)
.attr('height', opt.barHeight)
.attr('fill', color)
.attr('fill-opacity', opacity);
randerMarkText : function(svg, g, x, y, text, fontSize, color){
g.append('text')
.attr('x', x)
.attr('y', y)
.attr('fill', color)
.attr('font-size', fontSize+'px')
.text(text);
},
drawTag : function(svg, group, cx, cy, r, color, opacity, opt, self){
group.append('circle')
randerMarkLine : function(svg, g, p1, p2, color, isDash, opacity){
var line = g.append('line');
line.attr('stroke',color)
.attr('stroke-opacity', opacity)
.attr('x1', p1.x)
.attr('y1', p1.y)
.attr('x2', p2.x)
.attr('y2', p2.y);
if(isDash){
line.attr('stroke-dasharray', '5 5');
}
},
randerTopMark : function(svg, g, parameter, opt, self){
var cy = (parameter.chartHeight - opt.bar.height) / 2 + opt.bar.top + opt.tMark.offsetY;
var basic = parameter.chartWidth / (opt.maxValue - opt.minValue);
var val = Number(svg.datum().skilledRate ) * 100;
var w = basic * val;
var cx = w + opt.bar.left;
//指針
var p1 = { x : cx, y : cy};
var p2 = { x : cx, y : (parameter.chartHeight - opt.bar.height) / 2 + opt.bar.top + opt.bar.height};
svg.call(self.randerMarkLine,g, p1, p2, opt.tMark.lineColor, opt.tMark.isDash, opt.tMark.lineOpacity);
//文字
var ty = p1.y + (opt.bMark.fontSize - opt.bMark.radius) /2;
var tx = p1.x + opt.tMark.textGapX;
var text = opt.tMark.text + ' : ';
if(val > 0){
if( self.isFloat(val) ){
text += self.formatStr(val);
}
else{
text += val;
}
}
svg.call(self.randerMarkText,g, tx , ty, text , opt.tMark.fontSize , opt.tMark.color);
//標記
g.append('circle')
.attr('cx', cx)
.attr('cy', cy)
.attr('r', r)
.attr('fill', color)
.attr('fill-opacity', opacity);
.attr('r', opt.tMark.radius * opt.zoomW)
.attr('fill', opt.tMark.color)
.attr('fill-opacity', opt.tMark.opacity);
},
drawNeedle: function(svg, group , p1, p2, color, opacity){
group.append('line')
.attr('stroke', color)
.attr('stroke-opacity', opacity)
.attr('x1', p1.x)
.attr('y1', p1.y)
.attr('x2', p2.x)
.attr('y2', p2.y);
randerBottomMark : function(svg, g, parameter, opt, self){
var cy = (parameter.chartHeight - opt.bar.height) / 2 + opt.bar.top + opt.bar.height + + opt.bMark.offsetY;
var basic = parameter.chartWidth / (opt.maxValue - opt.minValue);
var val = Number(svg.datum().basicRate ) * 100;
var w = basic * val;
var cx = w + opt.bar.left;
//指針
var p1 = { x : cx, y : cy};
var p2 = { x : cx, y : (parameter.chartHeight - opt.bar.height) / 2 + opt.bar.top};
svg.call(self.randerMarkLine,g, p1, p2, opt.bMark.lineColor, opt.bMark.isDash, opt.bMark.lineOpacity);
//文字
var ty = p1.y + (opt.bMark.fontSize - opt.bMark.radius) /2;
var tx = p1.x + opt.bMark.textGapX;
var text = opt.bMark.text + ' : ';
if(val > 0){
if( self.isFloat(val) ){
text += self.formatStr(val);
}
else{
text += val;
}
}
svg.call(self.randerMarkText,g, tx , ty, text , opt.bMark.fontSize , opt.bMark.color);
//標記
g.append('circle')
.attr('cx', cx)
.attr('cy', cy)
.attr('r', opt.bMark.radius * opt.zoomW)
.attr('fill', opt.bMark.color)
.attr('fill-opacity', opt.bMark.opacity);
},
drawTagTitle:function(svg, group, p, color, title, value, opt){
var textTitle = title + " : " + value;
var text = group.append('text');
text.attr('y', p.y)
.attr('x', p.x)
.attr('fill', color)
.text(textTitle);
},
drawUserScoreTitle : function(svg, group, p, color, value, opt){
var textTitle = value + '';
var text = group.append('text');
text.attr('fill', color)
.text(textTitle);
randerMainSourceText:function(svg, g, parameter, opt, self){
var val = self.formatStr( Number(svg.datum().rightRate) * 100 );
var y = (parameter.chartHeight / 2) + opt.bar.top + (opt.mainInfo.fontSize / 2);
var basic = parameter.chartWidth / (opt.maxValue - opt.minValue);
var x = basic * val + opt.bar.left;
var text = '0';
var offsetX = 0;
var fontSize = text.style("font-size").replace('pt','').replace('px','') | 0;
var gapTotal = opt.surmiseFontGap * (textTitle.length - 1);
var offsetW = (fontSize * textTitle.length + gapTotal) / 2;
var offsetH = (opt.axisHeight ) / 2 + fontSize;
p.x -= (offsetW + opt.scoreOffsetH);
p.y += offsetH + opt.scoreOffsetV;
text.attr('x', p.x);
text.attr('y', p.y);
if(val > 0){
if( self.isFloat(val) ){
text = val + '';
if(val > 1)
offsetX = (text.length-1) * opt.mainInfo.fontSize;
}
else{
text = val+'';
if(val > 1){
offsetX = (text.length) * opt.mainInfo.fontSize;
}else{
x = opt.bar.left;
}
}
}
g.append('text')
.attr('font-size', opt.mainInfo.fontSize + 'px')
.text(text)
.attr('x', x - offsetX )
.attr('y', y)
.attr('fill', opt.mainInfo.textColor);
},
drawScalaText : function(svg, group, p, color, value, opt){
var textTitle = value + '';
var text = group.append('text');
text.attr('fill', color)
.text(textTitle);
var fontSize = text.style("font-size").replace('pt','').replace('px','') | 0;
var gapTotal = opt.surmiseFontGap * (textTitle.length - 1);
var offsetW = (fontSize * textTitle.length + gapTotal) / 2;
var offsetH = (opt.axisHeight ) / 2 + fontSize;
p.x -= offsetW;
p.y += offsetH;
text.attr('x', p.x);
text.attr('y', p.y);
randerMainSourceBar : function(svg, g, parameter, opt, self){
var d = svg.datum();
var y = (parameter.chartHeight - opt.bar.height) / 2 + opt.bar.top;
var basic = parameter.chartWidth / (opt.maxValue - opt.minValue);
var w = basic * Number(d.rightRate) * 100;
g.append('rect')
.attr('x', opt.bar.left)
.attr('y', y)
.attr('rx', opt.bar.rx)
.attr('ry', opt.bar.ry)
.attr('width' , w)
.attr('height', opt.bar.height)
.attr('fill', opt.mainInfo.color)
.attr('fill-opacity', opt.mainInfo.opacity)
.attr('style', 'fill:url(#barGradient)');
},
drawAxis : function(svg, minLength, p1_radians, p2_radians, opt, self){
var scaleGroup = svg.append('g').attr('class', 'scaleGroup');
var d = svg.datum();
var groupList = [];
for(var i=0, count=d.length ; i < count ; i++){
var p = self.getPoint(opt.gap * i, p1_radians, 0, opt.top);
p.x += opt.left;
var g = svg.append('g');
groupList.push(g);
svg.call(self.drawAxisText, d[i].title, groupList[i], p, opt.titleWidth, opt, self);
randerBackgroune : function(svg, parameter, opt, self){
var y = (parameter.chartHeight - opt.bar.height) / 2 + opt.bar.top;
var g = svg.append('g');
g.append('rect')
.attr('x', opt.bar.left)
.attr('y', y)
.attr('rx', opt.bar.rx)
.attr('ry', opt.bar.ry)
.attr('width' , parameter.chartWidth)
.attr('height', opt.bar.height)
.attr('fill', opt.background.color)
.attr('fill-opacity', opt.background.opacity);
return g;
},
randerGradien : function(svg, d, opt ,self){
var defs = svg.append('g').append('defs');
var gradient = defs.append('linearGradient');
gradient.attr('id', 'barGradient')
.attr('x1','0%')
.attr('y1','0%')
.attr('x2','0%')
.attr('y2','100%')
.attr('spreadMethod', 'pad');
for(var i=0, l=d.length ; i < l ; i++){
gradient.append('stop')
.attr('offset', d[i].offset)
.attr('stop-color', d[i].color)
.attr('stop-opacity', d[i].opacity);
}
for(var j=0, count=d.length ; j < count ; j++){
var p = self.getPoint(opt.gap * j, p1_radians, opt.hGap, opt.barTop);
p.x += opt.left + self.titleWidth;
//bar background
svg.call(self.drawLineBar, groupList[j], p, minLength, opt.barBackColor, opt.barBackOpacity, opt, self);
//bar user score
var userScoreW = minLength * d[j].rightRate;
svg.call(self.drawLineBar, groupList[j], p, userScoreW, opt.scoreBackColor , opt.scoreOpacity , opt, self);
//basicRate tag
var basicOffset = minLength * d[j].basicRate;
var basicX = p.x + basicOffset;
var basicY = p.y + opt.barHeight + opt.tagOffset;
svg.call(self.drawTag, groupList[j], basicX, basicY , opt.tagRadius, opt.bottomTagColor, opt.tagOpacity, opt, self);
//skilledRate tag
var skilledOffset = minLength * d[j].skilledRate;
var skilledX = p.x + skilledOffset;
var skilledY = p.y - opt.tagOffset;
svg.call(self.drawTag, groupList[j], skilledX, skilledY , opt.tagRadius, opt.topTagColor, opt.tagOpacity, opt, self);
//basic 指針
var bNP1 = {x : basicX , y: basicY};
var bNP2 = {x : basicX , y: p.y};
svg.call(self.drawNeedle, groupList[j], bNP1, bNP2, opt.bottomNeedleColor, opt.bottomNeedOpacity);
//skill 指針
var SNP1 = {x : skilledX , y: skilledY};
var SNP2 = {x : skilledX , y: skilledY + opt.barHeight + opt.tagOffset};
svg.call(self.drawNeedle, groupList[j], SNP1, SNP2, opt.topNeedleColor, opt.topNeedleOpacity);
//basic title
var BTP = {x: basicX + opt.bottomTitleGap, y: basicY + opt.tagRadius};
var bval = Math.floor(d[j].basicRate * 100);
svg.call(self.drawTagTitle, groupList[j], BTP ,opt.bottomTagColor, d[j].bTitle, bval, opt);
//skill title
var TTP = {x: skilledX + opt.topTitleGap, y: skilledY + opt.tagRadius};
var tval = Math.floor(d[j].skilledRate * 100);
svg.call(self.drawTagTitle, groupList[j], TTP ,opt.topTagColor, d[j].tTitle, tval, opt);
//學生分數 title
var STP = {x : p.x + userScoreW , y : p.y };
var sval = Math.floor(d[j].rightRate * 100);
svg.call(self.drawUserScoreTitle, groupList[j], STP ,opt.scoreColor, sval, opt);
}
//刻度
//start
var sp1 = self.getPoint(opt.gap * j+1, p1_radians, opt.hGap, opt.barTop);
sp1.x += opt.left + self.titleWidth;
//var ep2 = {x: sp1.x + minLength , y : sp1.y};
var sectionVal = minLength / opt.scale;
var sectionV = (opt.maxValue - opt.minValue) / opt.scale;
for(var i=0 , count=opt.scale ; i <= count ; i++){
var scaleP1 = {x : sp1.x + i * sectionVal, y: sp1.y};
var scaleP2 = {x : scaleP1.x , y: sp1.y + opt.scaleNeedleH};
//刻度直線
svg.call(self.drawNeedle, scaleGroup, scaleP1, scaleP2, opt.scaleNeedleHColor, opt.topNeedleOpacity);
//刻度 text
var valP = {x : scaleP1.x + opt.scaleTextOffsetH , y : scaleP2.y + opt.scaleTextGap};
svg.call(self.drawScalaText, scaleGroup, valP, 'black', sectionV * i, opt );
}
//刻度橫線
var sph1 = {x: sp1.x , y : sp1.y + opt.scaleNeedleH/2 };
var sph2 = {x: sp1.x + minLength , y : sph1.y};
svg.call(self.drawNeedle, scaleGroup, sph1, sph2, opt.scaleNeedleHColor, opt.topNeedleOpacity);
//
},
renderRadar : function(svg, opt, self){
var p1_radians = 0;
var p2_radians = opt.arc / 8 * 2;
var parameter = {};
var viewBoxList = opt.viewBox.split(',');
var w = viewBoxList[2];
var h = viewBoxList[3];
var minLength = w * opt.axisZoom;
//render
svg.call(self.drawAxis, minLength, p1_radians, p2_radians, opt, self);
parameter.w = viewBoxList[2];
parameter.h = viewBoxList[3];
//圖長寬
parameter.chartWidth = parameter.w * opt.axisZoom * opt.zoomW;
parameter.chartHeight = parameter.h * opt.axisZoom * opt.zoomH;
//
parameter.halfW = parameter.chartWidth / 2;
parameter.halfH = parameter.chartHeight / 2;
self.para = parameter;
svg.call(self.randerGradien, opt.gradien, opt, self);
var g = svg.call(self.randerBackgroune, parameter, opt, self);
svg.call(self.randerMainSourceBar, g, parameter, opt, self);
svg.call(self.randerMainSourceText, g, parameter, opt, self);
svg.call(self.randerTopMark, g, parameter, opt, self);
svg.call(self.randerBottomMark, g, parameter, opt, self);
},
draw : function(id, data, options){
this.reset(id);
var opt = (options) ? this.mixOptions(options) : this.mixOptions(null) ;

@@ -244,4 +286,4 @@ var svg = d3.select(id).append("svg");

svg.attr("preserveAspectRatio", opt.preserveAspectRatio);
svg.datum(data); //塞入數據
svg.call(this.renderRadar, opt, this); //要呼叫的函數 (會先執行)
svg.datum(data);
svg.call(this.renderRadar, opt, this); //要呼叫的函數
}

@@ -248,0 +290,0 @@ };

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc