D3.js實(shí)現(xiàn)議程漂移圖

一、首先引用D3.js插件庫,還有jquery.js,因?yàn)檫@個(gè)demo是基于jquery實(shí)現(xiàn)的。

二、D3圖demo主文件 -- index.html

<!DOCTYPE html >

<html xmlns="http://www.w3.org/1999/xhtml">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script src="jquery-2.1.0.js"></script>

<script src="checkDate.js"></script>

<script src="d3.min.js"></script>?

<body>

<!--<a id="cropButton"? title="保存為圖片"? href="javascript:void(0);" ><img src="../../images/save2.png"? style="width:25px;height:25px;"/></a>-->

<div id="chart" style="width:100%;overflow:auto;">


</div>

<div class="flag" id="ddd" style="left: 724px; top: 66px; display: none; opacity: 1;">

</div>

<div id="bgDiv">

<div id="agen" >

<div id="agenda">

</div>

</div>

</div>

<script>

? ? var bgDiv=document.getElementById("bgDiv");

? ? var sHeight=window.screen.height-200;

? ? var aHeight=(sHeight-200)/2;

? ? if(aHeight<0){

? ? ? ? aHeight=0;

? ? }

? ? bgDiv.style.display="block";

? ? $("#agen").attr("style","margin-top:"+aHeight+"px");

? ? var w = 850,

? ? ? ? ? ? h = 500,

? ? ? ? ? ? i = 0,

? ? ? ? ? ? barHeight = 20,

? ? ? ? ? ? duration = 400,

? ? ? ? ? ? root,

? ? ? ? ? ? item_w=13,

? ? ? ? ? ? item_h=13,

? ? ? ? ? ? timeTick=0;

? ? var tree = d3.layout.tree()

? ? ? ? ? ? .size([h, 100]);

? ? var itemImg,vis;

? ? var xTime = d3.time.scale().range([0, w-300]);

? ? var color = d3.scale.category10();

? ? var color1 = ["gray","#fe6263","orange","#2196F3","#69c970"];

? ? var parseDate = d3.time.format("%Y/%m/%d").parse;

? ? var diagonal = d3.svg.diagonal()

? ? ? ? ? ? .projection(function(d) { return [d.y,d.x] });

? ? var mintime;

? ? var maxtime;

? ? var id="1508738733433";

? ? var leveljson;?

var data = {

"data": {

"total": 7,

"data": {

"redu": 3,

"color": 0,

"children": [{

"summary": "考試人員為符合公司專業(yè)、學(xué)歷等要求,2.有相關(guān)工作經(jīng)驗(yàn)者優(yōu)先錄用,具有專業(yè)相關(guān)工作經(jīng)歷者優(yōu)先,符合招聘崗位工作要求,376985322@qq.com 寧夏寧東擔(dān)保有限公司招人 一、招聘崗位及要求 (一)公司副總經(jīng)理 1.全日制大學(xué)本科及以上學(xué)歷,依據(jù)筆試、面試成績和國家電網(wǎng)公司要求,  二、組織招聘考試 1.公司按照國家電網(wǎng)公司安排2018年4月1日組織第二批統(tǒng)一考試,3.有房地產(chǎn)/代理公司工作經(jīng)驗(yàn)者優(yōu)先錄用,一招聘崗位及要求 1.大學(xué)??萍耙陨蠈W(xué)歷,是公司發(fā)布招聘信息、應(yīng)聘者報(bào)名的唯一渠道",

"redu": 3,

"color": 0,

"children": null,

"tendency": 0,

"name": "寧夏這些單位正在大量招人,找工作的快來!",

"endtime": "2018/03/16",

"id": 2393,

"source": null,

"starttime": "2018/03/15",

"url": null,

"docPublishtime": null

}, {

"summary": "有意應(yīng)聘者請登錄交通銀行招聘網(wǎng)站進(jìn)行簡歷投遞,金融同業(yè)的正式員工相關(guān)工作經(jīng)驗(yàn)可放寬至一年,金融同業(yè)的正式員工相關(guān)工作經(jīng)驗(yàn)可放寬至一年,交通銀行是中國境內(nèi)主要綜合金融服務(wù)提供商之一,(5)具有會計(jì)從業(yè)資格證或銀行從業(yè)資格證等相關(guān)資格證書者優(yōu)先,(5)具有會計(jì)從業(yè)資格證或銀行從業(yè)資格證等相關(guān)資格證書者優(yōu)先,符合交通銀行親屬回避規(guī)定,運(yùn)行管理 職位信息,? (5)?具有相關(guān)資格證書者或具有金融IT從業(yè)經(jīng)歷者優(yōu)先,交通銀行寧波分行組建于1987年10月26日",

"redu": 2,

"color": 0,

"children": null,

"tendency": 0,

"name": "【HR招聘】交通銀行股份有限公司寧波分行",

"endtime": "2018/03/15",

"id": 2392,

"source": null,

"starttime": "2018/03/15",

"url": null,

"docPublishtime": null

}, {

"summary": "中國最低工資是世界平均工資的21%,中國最低工資是平均工資的21%,? 世界最低工資平均是人均GDP的58%,因?yàn)槭澜缍鄶?shù)國家公務(wù)員工資是最低工資的2倍,? 中國最低工資是人均GDP的25%,平均每年增長1.52%. ? 2.公務(wù)員工資是最低工資的2倍 ? 可對比性工資制度被世界多數(shù)國家改采納,最低工資與人均GDP的比值世界平均為58%(國際勞工組織《世界工資報(bào)告08/09》的數(shù)據(jù)是60%,最低工資是人均GDP的58%,目前中國的最低工資只是人均GDP的25%,中國公務(wù)員工資是最低工資的6倍",

"redu": 2,

"color": 0,

"children": null,

"tendency": 0,

"name": "讓國人震驚的“工資調(diào)查”",

"endtime": "2018/03/15",

"id": 2394,

"source": null,

"starttime": "2018/03/15",

"url": null,

"docPublishtime": null

}],

"tendency": null,

"name": "交通銀行",

"endtime": "2018/03/16",

"id": 152117033395127300,

"source": null,

"starttime": "2018/03/15",

"url": null,

"docPublishtime": null

}

},

"httpCode": 200,

"msg": "請求成功",

"timestamp": 1521538054458

};

? ? ? ? ? ? if(data.httpCode==200){

? ? ? ? ? ? ? ? if(data.data!=undefined){

? ? ? ? ? ? ? ? ? root= data.data.data;

? ? ? ? ? ? ? ? ? ? root.x0 = 0;

? ? ? ? ? ? ? ? ? ? root.y0 = 0;

? ? ? ? ? ? ? ? ? ? if(root!=null){

? ? ? ? ? ? ? ? ? ? ? ? bgDiv.style.display="none";

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? //給d3.js傳數(shù)據(jù)。

? ? ? ? ? ? ? ? ? ? var nodes = tree.nodes(root);

? ? ? ? ? ? ? ? ? ? var wh;

? ? ? ? ? ? ? ? ? ? // Compute the "layout".

? ? ? ? ? ? ? ? ? ? nodes.forEach(function(n, i) {

? ? ? ? ? ? ? ? ? ? ? ? n.x = i * barHeight*1.2;

? ? ? ? ? ? ? ? ? ? ? ? n.x= n.x+20;

? ? ? ? ? ? ? ? ? ? ? ? wh=n.x;

? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? leveljson = root;

? ? ? ? ? ? ? ? ? ? var mynodes = tree.nodes(root);

? ? ? ? ? ? ? ? ? ? var mintime = d3.min(mynodes,function(d){return d.starttime});

? ? ? ? ? ? ? ? ? ? var maxtime = d3.max(mynodes,function(d){return d.endtime});

? ? ? ? ? ? ? ? ? ? xTime.domain([parseDate(mintime),parseDate(maxtime)]);

? ? ? ? ? ? ? ? ? ? var reg=new RegExp("\/","g");

? ? ? ? ? ? ? ? ? ? var tt1=mintime.replace(reg,"-");

? ? ? ? ? ? ? ? ? ? var tt2=maxtime.replace(reg,"-");

? ? ? ? ? ? ? ? ? ? var days =dateDiff(tt1,tt2);

? ? ? ? ? ? ? ? ? ? //timeTick=days<8?1:(days<16?2:4);

? ? ? ? ? ? ? ? ? ? if(days<8){

? ? ? ? ? ? ? ? ? ? ? ? timeTick=1;

? ? ? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? ? ? timeTick=Math.floor(days/8);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? var xAxisTime = d3.svg.axis()

? ? ? ? ? ? ? ? ? ? ? ? ? ? .scale(xTime)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .orient("top")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .ticks(d3.time.days, timeTick)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .tickFormat(d3.time.format('%m'+'/'+'%d'));

? ? ? ? ? ? ? ? ? ? //alert(timeTick);

? ? ? ? ? ? ? ? ? ? vis = d3.select("#chart").append("svg:svg")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("width", w)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("height", wh+100)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .append("svg:g")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("transform", "scale(1,1)translate(30,30)");

? ? ? ? ? ? ? ? ? ? vis.append("g")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("class", "x axis")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .style("fill","none")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .style("stroke","gray")

.style("font-size", "12px")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("transform", "translate(0,3)")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .call(xAxisTime)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .style("opacity",1)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .append("text")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("class", "xlabel")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("x", w - 150)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .attr("y", 0)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .style("text-anchor", "end")

.style("font-size", "12px")

? ? ? ? ? ? ? ? ? ? ? ? ? ? .text("時(shí)間");

? ? ? ? ? ? ? ? ? ? update(root);

? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? $("#chart").html("無數(shù)據(jù)");

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

function update(source) {

? // Compute the flattened node list. TODO use d3.layout.hierarchy.

? var nodes = tree.nodes(root);


? // Compute the "layout".

? nodes.forEach(function(n, i) {

? ? n.x = i * barHeight*1.2;

n.x= n.x+20;

? });


? // Update the nodes…

? var node = vis.selectAll("g.node")

? ? ? .data(nodes, function(d) { return d.id || (d.id = ++i); });


? var nodeEnter = node.enter().append("svg:g") ;

? nodeEnter.append("svg:rect")

? .attr("rx","9px")

? ? ? .attr("y", -barHeight / 2 )

? ? ? .attr("height", barHeight)

? ? ? .attr("stroke-width",3)

? ? ? .attr("stroke",function(d,i) {

? ? ? ? ? if(d.tendency==1){

? ? ? ? ? ? ? return color1[4];

? ? ? ? ? }else if(d.tendency==0){

? ? ? ? ? ? ? return color1[3];

? ? ? ? ? }else if(d.tendency==-1){

? ? ? ? ? ? ? return color1[1];

? ? ? ? ? }else{

? ? ? ? ? ? ? return color1[0];

? ? ? ? ? }

? ? ? ? // return color1[d.color];

? ? ? })

? .attr("width",function(d,i) { if(i==0){return 300}else{return 270}})

? ? ? .style("fill","none");

? /*添加圖像*/

? itemImg=nodeEnter.append("svg:image")

? .attr("class", function(d,i){ return "image_item"+d.id;})

.filter(function(d) { return d.children; })

// .style("fill", "url(#MyGradient2)")

.attr("xlink:href", function(d) {return "images/subtract.png"; })

? .attr("y", function(d) { return -barHeight / 2+2; })

.attr("width", item_w)

.attr("height", item_h)

? .style("opacity",0.8) ;

? nodeEnter.append("svg:text")

? ? ? .attr("dy", 3.5)

? ? ? .attr("dx", 5.5)

? ? ? .attr("transform", "translate(10,0)")

? ? ? .style("fill","black")//設(shè)置字體顏色

? .style("font-size", "12px")

? ? ? .text(function(d,i) {if(i!=0 && d.name.length>20){return d.name.substring(0,21)+"..."}else{return d.name;} });


? // Transition nodes to their new position.

? nodeEnter.transition()

? ? ? .duration(duration)

? ? ? .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })

? ? ? .style("opacity", opacity);


? node.transition()

? ? ? .duration(duration)

.attr("transform", function(d) { return "translate(" + xTime(parseDate(d.starttime)) + "," + d.x + ")"; })

? ? ? .style("opacity", opacity)

? ? .select("rect") ;


? // Transition exiting nodes to the parent's new position.

? node.exit().transition()

? ? ? .duration(duration)

? ? ? .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })

? ? ? .style("opacity", 1e-6)

? ? ? .remove();

? ? var ldate=tree.links(nodes);

? // Update the links…

? var link = vis.selectAll("path.link")

? ? ? .data(tree.links(nodes), function(d) { return d.target.id; });

? // Enter any new links at the parent's previous position.

? link.enter().insert("svg:path", "g")

? ? ? .attr("class", "link")

? .style("opacity", 0.6)

? .style("stroke", function(d,i){

? ? ? ? ? if(d.target.tendency==1){

? ? ? ? ? ? ? return color1[4];

? ? ? ? ? }else if(d.target.tendency==0){

? ? ? ? ? ? ? return color1[3];

? ? ? ? ? }else if(d.target.tendency==-1){

? ? ? ? ? ? ? return color1[1];

? ? ? ? ? }else{

? ? ? ? ? ? ? return color1[0];

? ? ? ? ? }

// return color1[d.target.color]

? })

? .style("fill","none")

? ? .style("stroke-width","1.5px")

? ? ? .attr("d", function(d) {

? ? ? var o = {x: d.source.x, y: xTime(parseDate(d.source.starttime))};

? ? ? ? return diagonal({source: o, target: o});

? ? ? })

? ? .transition()

? ? ? .duration(duration)

? ? ? .attr("d", function(d) {

? ? ? ? var o = {x: d.source.x, y:xTime(parseDate(d.source.starttime)) };

var ot = {x: d.target.x, y:xTime(parseDate(d.target.starttime)) };;

? ? ? ? return diagonal({source: o, target: ot});

? ? ? });

? // Transition links to their new position.

? link.transition()

? ? ? .duration(duration)

? .style("opacity", 0.6)

? ? ? .attr("d", function(d,i) {

? ? ? ? var o = {x:d.source.x , y: xTime(parseDate(d.source.starttime))};

var ot = {x: d.target.x, y:xTime(parseDate(d.target.starttime)) };;

? ? ? ? return diagonal({source: o, target: ot});

? ? ? });

? // Transition exiting nodes to the parent's new position.

? link.exit().transition()

? ? ? .duration(duration)

? .style("opacity", 0)

? ? ? .attr("d", function(d) {

? ? ? var o = {x: d.source.x, y:xTime(parseDate(d.source.starttime)) };

? ? ? ? return diagonal({source: o, target: o})

? ? ? })

? ? ? .remove();


}

// Toggle children on click.

function click(d) {

? if (d.children) {

? ? d._children = d.children;

? ? d.children = null;

? } else {

? ? d.children = d._children;

? ? d._children = null;

? }

? this.update(d);

}

function opacity(d) {

? return d._children ? 1 : d.children ? 0.8 : 0.8;

}

var u = navigator.userAgent;

</script>

</body>

</html>

三、D3圖自行封裝的時(shí)間方法 -- checkDate.js

function isLeapYear(year){

? ? ? ? if(year % 4 == 0 && ((year % 100 != 0) || (year % 400 == 0)))

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? return false;

}

function validatePeriod(fyear,fmonth,fday,byear,bmonth,bday){

? ? ? ? if(fyear < byear){

? ? ? ? ? ? return true;

? ? ? ? }else if(fyear == byear){

? ? ? ? ? ? if(fmonth < bmonth){

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? } else if (fmonth == bmonth){

? ? ? ? ? ? ? ? ? if(fday <= bday){

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }else {

? ? ? ? ? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? }

? ? ? ? }else {

? ? ? ? ? ? return false;

? ? ? ? }


function dateDiff(d1,d2){

var disNum=compareDate(d1,d2);

return disNum;

}

function compareDate(date1,date2){

var regexp=/^(\d{1,4})[-|\.]{1}(\d{1,2})[-|\.]{1}(\d{1,2})$/;

var monthDays=[0,3,0,1,0,1,0,0,1,0,0,1];

regexp.test(date1);

var date1Year=RegExp.$1;

var date1Month=RegExp.$2;

var date1Day=RegExp.$3;

regexp.test(date2);

var date2Year=RegExp.$1;

var date2Month=RegExp.$2;

var date2Day=RegExp.$3;

if(validatePeriod(date1Year,date1Month,date1Day,date2Year,date2Month,date2Day)){

firstDate=new Date(date1Year,date1Month,date1Day);

secondDate=new Date(date2Year,date2Month,date2Day);

result=Math.floor((secondDate.getTime()-firstDate.getTime())/(1000*3600*24));

for(j=date1Year;j<=date2Year;j++){

if(isLeapYear(j)){

monthDays[1]=2;

}else{

monthDays[1]=3;

}

for(i=date1Month-1;i<date2Month;i++){

result=result-monthDays[i];

}

}

return result;

}else{

alert('有錯(cuò)誤');

exit;

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容