D3.js实现议程漂移图

一、首先引用D3.js插件库,还有jquery.js,因为这个demo是基于jquery实现的。

二、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": "考试人员为符合公司专业、学历等要求,2.有相关工作经验者优先录用,具有专业相关工作经历者优先,符合招聘岗位工作要求,376985322@qq.com 宁夏宁东担保有限公司招人 一、招聘岗位及要求 (一)公司副总经理 1.全日制大学本科及以上学历,依据笔试、面试成绩和国家电网公司要求,  二、组织招聘考试 1.公司按照国家电网公司安排2018年4月1日组织第二批统一考试,3.有房地产/代理公司工作经验者优先录用,一招聘岗位及要求 1.大学专科及以上学历,是公司发布招聘信息、应聘者报名的唯一渠道",

"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": "有意应聘者请登录交通银行招聘网站进行简历投递,金融同业的正式员工相关工作经验可放宽至一年,金融同业的正式员工相关工作经验可放宽至一年,交通银行是中国境内主要综合金融服务提供商之一,(5)具有会计从业资格证或银行从业资格证等相关资格证书者优先,(5)具有会计从业资格证或银行从业资格证等相关资格证书者优先,符合交通银行亲属回避规定,运行管理 职位信息,  (5) 具有相关资格证书者或具有金融IT从业经历者优先,交通银行宁波分行组建于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%,因为世界多数国家公务员工资是最低工资的2倍,  中国最低工资是人均GDP的25%,平均每年增长1.52%.   2.公务员工资是最低工资的2倍   可对比性工资制度被世界多数国家改采纳,最低工资与人均GDP的比值世界平均为58%(国际劳工组织《世界工资报告08/09》的数据是60%,最低工资是人均GDP的58%,目前中国的最低工资只是人均GDP的25%,中国公务员工资是最低工资的6倍",

"redu": 2,

"color": 0,

"children": null,

"tendency": 0,

"name": "让国人震惊的“工资调查”",

"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传数据。

                    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("时间");

                    update(root);

                }else{

                    $("#chart").html("无数据");

                }

            }

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")//设置字体颜色

  .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图自行封装的时间方法 -- 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('有错误');

exit;

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容