d3js时间轴图表-为了擦洗而设置一个矩形块

9
我正在考虑创建一个时间轴图表,只有底部的一个矩形块作为主要的刻度尺。
// 当前 - http://jsfiddle.net/NYEaX/2427/

enter image description here

在哪里的擦洗部分 - 我希望只有一个基本矩形。我应该对当前代码进行什么修改?

所以更像这样 输入图像描述

//my latest - https://jsfiddle.net/2mvhjr7z/2/

$(document).ready(function() {


  var $this = $('.timelinechart');
    
      var w = $this.data("width");
      var h = $this.data("height");
      //var data = $this.data("data");

      
    var data = [
      {
        "label": "person a",
        "icon": "4",
        "times": [
          {"text": "Test 1", "starting_time": 1355752800000, "ending_time": 1355759900000},
          {"text": "Test 2", "starting_time": 1355767900000, "ending_time": 1355774400000},
          {"text": "Test 6", "starting_time": 1355761900000, "ending_time": 1355764520000},
          {"text": "Test 7", "starting_time": 1355767900000, "ending_time": 1355774400000}
        ]
      },
      {
        "label": "person b",
        "icon": "5",
        "times": [
          {"text": "Test 8", "starting_time": 1355752800000, "ending_time": 1355759900000},
          {"text": "Test 9", "starting_time": 1355767900000, "ending_time": 1355774400000},
          {"text": "Test 10", "starting_time": 1355767900000, "ending_time": 1355867900000}
        ]
      }
    ];


    var lanes = [];
    var times = [];
    var icons = [];
    $.each(data, function(index, value) {
      lanes.push(value.label);
      //icons.push(_avatarList[value.icon].image);
      $.each(value.times, function(i, v) {
        v["lane"] = index;
      });
      times.push(value.times); 
    });

    var laneLength = lanes.length;
    var items = [].concat.apply([], times);

    $.each(items, function(i, v) {
      v["id"] = i;
    });

    var timeBegin = d3.min(items, function(d) { return d["starting_time"]; });
    var timeEnd = d3.max(items, function(d) { return d["ending_time"]; });

    var m = [25, 80, 15, 105], //top right bottom left 
      w = w - m[1] - m[3],
      h = h - m[0] - m[2],
      miniHeight = laneLength * 12 + 50,
      mainHeight = h - miniHeight - 50;

    //scales
    var x =  d3.scaleTime()
        .range([0, w])    
        .domain([timeBegin, timeEnd]);
    var x1 = d3.scaleLinear()
        .range([0, w]);
    var y1 = d3.scaleLinear()
        .range([0, mainHeight])
        .domain([0, laneLength]);
    var y2 = d3.scaleLinear()
        .range([0, miniHeight])
        .domain([0, laneLength]);

    var xAxis = d3.axisBottom(x)
      .ticks(d3.timeMonth)
      .tickFormat(d=>d3.timeFormat("%B %Y")(d));


    var scaleFactor = (1/(timeEnd - timeBegin)) * (w);

    var chartWidth = w + m[1] + m[3];
    var chartHeight = h + m[0] + m[2];

    var chart = d3.select($this[0])
          .append("svg")
          .attr("width", chartWidth)
          .attr("height", chartHeight)
          .attr("viewBox", "0 0 "+chartWidth+" "+chartHeight)
          .attr("preserveAspectRatio", "xMidYMid meet")
          .append("g")
          .attr("class", "timelinechartg");
    
    chart.append("defs").append("clipPath")
      .attr("id", "clip")
      .append("rect")
      .attr("width", w)
      .attr("height", mainHeight);

    var main = chart.append("g")
          .attr("transform", "translate(" + m[3] + "," + m[0] + ")")
          .attr("width", w)
          .attr("height", mainHeight)
          .attr("class", "main");

    var mini = chart.append("g")
          .attr("transform", "translate(" + m[3] + "," + (mainHeight + m[0]) + ")")
          .attr("width", w)
          .attr("height", miniHeight)
          .attr("class", "mini");


    var gX = chart.append("g")
          .attr("class", "axis")
          .attr("transform", "translate(" + m[3] + "," + (mainHeight + miniHeight) + ")")
          .call(xAxis); 
          
    //background colors
    function colores_background(n) {
      var colores_g = ["#f8dd2f", "#e9168a", "#448875", "#2b2d39", "#c3bd75", "#1b91dc"];
      return colores_g[n % colores_g.length];
    }

    //foreground colors
    function colores_foreground(n) {
      var colores_g = ["#553814", "#311854", "#f7b363", "#c12f39", "#89191d", "#2b2d39"];
      return colores_g[n % colores_g.length];
    }

    //main lanes and texts
    main.append("g").selectAll(".laneLines")
      .data(items)
      .enter().append("line")
      .attr("x1", 0)
      .attr("y1", function(d) {return y1(d.lane);})
      .attr("x2", w)
      .attr("y2", function(d) {return y1(d.lane);})
      .attr("stroke", "lightgray")

        var defs = main.append('svg:defs');

    main.append("g").selectAll(".laneText")
      .data(lanes)
      .enter().append("text")
      .text(function(d) {return d;})
      .attr("x", (-m[1] + 10))
      .attr("y", function(d, i) {
        return y1(i + .5);
      })
      .attr("dy", ".5ex")
      .attr("text-anchor", "end")
      .attr("class", "laneText");

    //mini lanes and texts
    mini.append("g").selectAll(".laneLines")
      .data(items)
      .enter().append("line")
      .attr("x1", 0)
      .attr("y1", function(d) {
        return y2(d.lane);
      })
      .attr("x2", w)
      .attr("y2", function(d) {
        return y2(d.lane);
      })
      .attr("stroke", "lightgray");

    mini.append("g").selectAll(".laneText")
      .data(lanes)
      .enter().append("text")
      .text(function(d) {return d;})
      .attr("x", -m[1] + 40)
      .attr("y", function(d, i) {return y2(i + .5);})
      .attr("dy", ".5ex")
      .attr("text-anchor", "end")
      .attr("class", "laneText");

    var itemRects = main.append("g")
              .attr("clip-path", "url(#clip)");
        
    //mini item rects
    mini.append("g").selectAll("miniItems")
      .data(items)
      .enter().append("rect")
      .attr("class", function(d) {return "miniItem "+d.state;})
      .attr("x", function(d) {return x(d.starting_time);})
      .attr("y", function(d) {return y2(d.lane + .5) - 5;})
      .attr("fill", function(d, i) {
        return colores_background(d.lane);
      })
      .attr("width", function(d) {
        return (d.ending_time - d.starting_time) * scaleFactor;
      })
      .attr("height", 10);

    //mini labels
    mini.append("g").selectAll(".miniLabels")
      .data(items)
      .enter().append("text")
      .text(function(d) {return d.text;})
      .attr("class", function(d) {return d.state;})
      .attr("x", function(d) {return x(d.starting_time);})
      .attr("y", function(d) {
        return y2(d.lane + .5);
      })
      .attr("fill", function(d, i) {
        return colores_foreground(d.lane);
      })
      .attr("dy", ".5ex");

    $.each(icons, function(index, value) {
      defs.append('svg:pattern')
        .attr('id', "--"+index)
        .attr('width', 1)
        .attr('height', 1)
        .append('svg:image')
        .attr('image-rendering', "optimizeQuality")
        .attr('preserveAspectRatio', "xMidYMid meet")
        .attr('xlink:href', value)
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', 50)
        .attr('height', 50);

      defs.append('svg:pattern')
        .attr('id', "--m"+index)
        .attr('width', 1)
        .attr('height', 1)
        .append('svg:image')
        .attr('image-rendering', "optimizeQuality")
        .attr('preserveAspectRatio', "xMidYMid meet")
        .attr('xlink:href', value)
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', 20)
        .attr('height', 20);  

      main.append("g")
          .attr("transform", function(d, i) {
          return "translate("+(-m[1] + 5)+","+ (y1(index + .5) - 50) +")";
        })
          .append("circle")
          .attr("class", "user")
          .style("stroke", "gray")
          .style("fill", "url(#--"+index+")")
          .attr("r", 25)
          .attr("cx", 40)
          .attr("cy", 50);

      mini.append("g")
          .attr("transform", function(d, i) {
          return "translate("+(-m[1] + 40)+","+ (y2(index + .5) - 20) +")";
        })
          .append("circle")
          .attr("class", "user")
          .style("stroke", "gray")
          .style("fill", "url(#--m"+index+")")
          .attr("r", 10)
          .attr("cx", 20)
          .attr("cy", 20);
    });

    var brush = d3.brushX()
        .extent([[0, 0], [w, miniHeight]])
        .on("brush", brushed);

    mini.append("g")
      .attr("class", "x brush")
      .call(brush)
      .selectAll("rect")
      .attr("y", 1)
      .attr("height", miniHeight - 1); 

    function brushed() {
      var selection = d3.event.selection;
      var timeSelection = selection.map(x.invert, x);
      //console.log("selection: " + selection);
      //console.log("start: " + timeSelection[0]);
      //console.log("end: " + timeSelection[1]);
      
      var rects;
      var labels;
      var minExtent = timeSelection[0];
      var maxExtent = timeSelection[1];    
      
      var visItems = items.filter(function(d) {return d.starting_time <  maxExtent && d.ending_time > minExtent;});
    
        //mini.select(".brush")
          //.call(brush.extent([minExtent, maxExtent]));          
          
        x1.domain([minExtent, maxExtent]);      
        
        //update main item rects
        rects = itemRects.selectAll("rect")
                .data(visItems, function(d) { return d.id; })
            .attr("x", function(d) {return x1(d.starting_time);})
            .attr("width", function(d) {return x1(d.ending_time) - x1(d.starting_time);});
        
        rects.enter().append("rect")
          .attr("class", function(d) {return "miniItem "+d.state;})
          .attr("x", function(d) {return x1(d.starting_time);})
          .attr("y", function(d) {return y1(d.lane) + 10;})
          .attr("fill", function(d, i) {
            return colores_background(d.lane);
          })
          .attr("width", function(d) {return x1(d.ending_time) - x1(d.starting_time);})
          .attr("height", function(d) {return .8 * y1(1);});

        rects.exit().remove();

        //update the item labels
        labels = itemRects.selectAll("text")
          .data(visItems, function (d) { return d.id; })
          .attr("x", function(d) {return x1(Math.max(d.starting_time, minExtent) + 2);});

        labels.enter().append("text")
          .text(function(d) {return d.text;})
          .attr("class", function(d) {return d.state;})
          .attr("x", function(d) {return x1(Math.max(d.starting_time, minExtent));})
          .attr("y", function(d) {return y1(d.lane + .5);})
          .attr("fill", function(d, i) {
            return colores_foreground(d.lane);
          })
          .attr("text-anchor", "start");

        labels.exit().remove();
    }

});
body {
  background: #eeeeee;
}

#holder {
  overflow: hidden;
}

/*
.chart {
  shape-rendering: crispEdges;
}
*/

.timelinechart{
  /*width:100%;
  border: 1px solid red;*/
}

.timelinechart svg{
  width:100%;
  /*border: 1px solid green;*/
}

.timelinechartg{
  
}

.mini text {
  font: 10px sans-serif; 
}

.main text {
  font: 12px sans-serif; 
}

.miniItem {
  /*fill: darksalmon;*/
  stroke-width: 6; 
}

.miniItem.future{
  fill: #448875;
}
text.future {
  fill: #f7b363;
}


.brush .extent {
  stroke: #b6b8b9;
  fill: #57585b;
  fill-opacity: .365;
  stroke-width: .2;
}

.laneImg{
  border-radius: 25px;
}
<script type='text/javascript' src='//code.jquery.com/jquery-1.9.1.js'></script>
<script type='text/javascript' src="http://d3js.org/d3.v4.min.js"></script>
<div class="timelinechart" data-role="timelinechart" data-width=500 data-height=300 data-data="" ></div>


最新的设计如下: 这里输入图片描述 当滑块显示更多细节 - 如一个月的日期范围时 - 刻度的格式变得更加详细。 这里输入图片描述

1
嗨,我不明白你想做什么,你是想从图表中删除“person p”部分吗? - ROOT
只需一个矩形 - 一个通用的刷子,而不是主图表的迷你版本。 - Rob
1
像这样https://jsfiddle.net/2mvhjr7z/2/ - Rob
你的意思是要移除黄色和粉色的条,并保留像提供的 fiddle 中那样的细小线条吗? - ROOT
1
是的 - 类似这样 -- https://jsfiddle.net/KgomDr/46uLtcvf/ - Rob
https://jsfiddle.net/2y8gkas3/7/ -- 最新的例子 -- - Rob
2个回答

3

尽管我不太清楚您想要实现什么,但我假设您需要一个通用的基础矩形。

我已经删除了显示此基础矩形标签的代码行,并更新了小节的高度。

如果这不符合您的期望,请告诉我。

请仔细查看我的fiddle。

$(document).ready(function() {


  var $this = $('.timelinechart');
  
     var w = $this.data("width");
     var h = $this.data("height");
     //var data = $this.data("data");

     
  var data = [
   {
    "label": "person a",
    "icon": "4",
    "times": [
     {"text": "Test 1", "starting_time": 1355752800000, "ending_time": 1355759900000},
     {"text": "Test 2", "starting_time": 1355767900000, "ending_time": 1355774400000},
     {"text": "Test 6", "starting_time": 1355761900000, "ending_time": 1355764520000},
     {"text": "Test 7", "starting_time": 1355767900000, "ending_time": 1355774400000}
    ]
   },
      {
    "label": "person b",
    "icon": "5",
    "times": [
     {"text": "Test 8", "starting_time": 1355752800000, "ending_time": 1355759900000},
     {"text": "Test 9", "starting_time": 1355767900000, "ending_time": 1355774400000},
     {"text": "Test 10", "starting_time": 1355767900000, "ending_time": 1355867900000}
    ]
   }
  ];


  var lanes = [];
  var times = [];
  var icons = [];
  $.each(data, function(index, value) {
   lanes.push(value.label);
   //icons.push(_avatarList[value.icon].image);
   $.each(value.times, function(i, v) {
    v["lane"] = index;
   });
   times.push(value.times); 
  });

  var laneLength = lanes.length;
  var items = [].concat.apply([], times);

  $.each(items, function(i, v) {
   v["id"] = i;
  });

  var timeBegin = d3.min(items, function(d) { return d["starting_time"]; });
  var timeEnd = d3.max(items, function(d) { return d["ending_time"]; });

  var m = [25, 80, 15, 105], //top right bottom left 
   w = w - m[1] - m[3],
   h = h - m[0] - m[2],
   miniHeight = laneLength * 12 + 25,
   mainHeight = h - miniHeight - 50;

  //scales
  var x =  d3.scaleTime()
    .range([0, w])    
    .domain([timeBegin, timeEnd]);
  var x1 = d3.scaleLinear()
    .range([0, w]);
  var y1 = d3.scaleLinear()
    .range([0, mainHeight])
    .domain([0, laneLength]);
  var y2 = d3.scaleLinear()
    .range([0, miniHeight])
    .domain([0, laneLength]);

  var xAxis = d3.axisBottom(x)
    .ticks(d3.timeMonth)
    .tickFormat(d=>d3.timeFormat("%B %Y")(d));


  var scaleFactor = (1/(timeEnd - timeBegin)) * (w);

  var chartWidth = w + m[1] + m[3];
  var chartHeight = h + m[0] + m[2];

  var chart = d3.select($this[0])
     .append("svg")
     .attr("width", chartWidth)
     .attr("height", chartHeight)
     .attr("viewBox", "0 0 "+chartWidth+" "+chartHeight)
     .attr("preserveAspectRatio", "xMidYMid meet")
     .append("g")
     .attr("class", "timelinechartg");
  
  chart.append("defs").append("clipPath")
   .attr("id", "clip")
   .append("rect")
   .attr("width", w)
   .attr("height", mainHeight);

  var main = chart.append("g")
     .attr("transform", "translate(" + m[3] + "," + m[0] + ")")
     .attr("width", w)
     .attr("height", mainHeight)
     .attr("class", "main");

  var mini = chart.append("g")
     .attr("transform", "translate(" + m[3] + "," + (mainHeight + m[0]) + ")")
     .attr("width", w)
     .attr("height", miniHeight)
     .attr("class", "mini");


  var gX = chart.append("g")
     .attr("class", "axis")
     .attr("transform", "translate(" + m[3] + "," + (mainHeight + miniHeight) + ")")
     .call(xAxis); 
     
  //background colors
  function colores_background(n) {
   var colores_g = ["#f8dd2f", "#e9168a", "#448875", "#2b2d39", "#c3bd75", "#1b91dc"];
   return colores_g[n % colores_g.length];
  }

  //foreground colors
  function colores_foreground(n) {
   var colores_g = ["#553814", "#311854", "#f7b363", "#c12f39", "#89191d", "#2b2d39"];
   return colores_g[n % colores_g.length];
  }
 
  main.append("g").selectAll(".laneText")
   .data(lanes)
   .enter().append("text")
   .text(function(d) {return d;})
   .attr("x", (-m[1] + 10))
   .attr("y", function(d, i) {
    return y1(i + .5);
   })
   .attr("dy", ".5ex")
   .attr("text-anchor", "end")
   .attr("class", "laneText");

  //main lanes and texts
  main.append("g").selectAll(".laneLines")
   .data(items)
   .enter().append("line")
   .attr("x1", 0)
   .attr("y1", function(d) {return y1(d.lane);})
   .attr("x2", w)
   .attr("y2", function(d) {return y1(d.lane);})
   .attr("stroke", "lightgray")

        var defs = main.append('svg:defs');

    

  var itemRects = main.append("g")
       .attr("clip-path", "url(#clip)");
    
  mini.append('rect')
  .attr("class", "miniBar")
  .attr("x", 0)
  .attr("y", 10)
  .attr("fill", "grey")
  .attr("width", w)
  .attr("height", 30);
  

 

  var brush = d3.brushX()
      .extent([[0, 0], [w, miniHeight]])
      .on("brush", brushed);

  mini.append("g")
   .attr("class", "x brush")
   .call(brush)
   .selectAll("rect")
   .attr("y", 1)
   .attr("height", miniHeight - 1); 

  function brushed() {
    var selection = d3.event.selection;
    var timeSelection = selection.map(x.invert, x);
    //console.log("selection: " + selection);
    //console.log("start: " + timeSelection[0]);
    //console.log("end: " + timeSelection[1]);
    
   var rects;
   var labels;
   var minExtent = timeSelection[0];
   var maxExtent = timeSelection[1];    
    
    var visItems = items.filter(function(d) {return d.starting_time <  maxExtent && d.ending_time > minExtent;});
   
    //mini.select(".brush")
     //.call(brush.extent([minExtent, maxExtent]));          
         
    x1.domain([minExtent, maxExtent]);      
       
    //update main item rects
    rects = itemRects.selectAll("rect")
            .data(visItems, function(d) { return d.id; })
      .attr("x", function(d) {return x1(d.starting_time);})
      .attr("width", function(d) {return x1(d.ending_time) - x1(d.starting_time);});
    
    rects.enter().append("rect")
     .attr("class", function(d) {return "miniItem "+d.state;})
     .attr("x", function(d) {return x1(d.starting_time);})
     .attr("y", function(d) {return y1(d.lane) + 10;})
     .attr("fill", function(d, i) {
      return colores_background(d.lane);
     })
     .attr("width", function(d) {return x1(d.ending_time) - x1(d.starting_time);})
     .attr("height", function(d) {return .8 * y1(1);});

    rects.exit().remove();

    //update the item labels
    labels = itemRects.selectAll("text")
     .data(visItems, function (d) { return d.id; })
     .attr("x", function(d) {return x1(Math.max(d.starting_time, minExtent) + 2);});

    labels.enter().append("text")
     .text(function(d) {return d.text;})
     .attr("class", function(d) {return d.state;})
     .attr("x", function(d) {return x1(Math.max(d.starting_time, minExtent));})
     .attr("y", function(d) {return y1(d.lane + .5);})
     .attr("fill", function(d, i) {
      return colores_foreground(d.lane);
     })
     .attr("text-anchor", "start");

    labels.exit().remove();
  }

});
body {
  background: #eeeeee;
}

#holder {
  overflow: hidden;
}

/*
.chart {
  shape-rendering: crispEdges;
}
*/

.timelinechart{
  /*width:100%;
  border: 1px solid red;*/
}

.timelinechart svg{
  width:100%;
  /*border: 1px solid green;*/
}

.timelinechartg{
  
}

.mini text {
  font: 10px sans-serif; 
}

.main text {
  font: 12px sans-serif; 
}

.miniItem {
  /*fill: darksalmon;*/
  stroke-width: 6; 
}

.miniItem.future{
  fill: #448875;
}
text.future {
  fill: #f7b363;
}


.brush .extent {
  stroke: #b6b8b9;
  fill: #57585b;
  fill-opacity: .365;
  stroke-width: .2;
}

.laneImg{
  border-radius: 25px;
}
<script type='text/javascript' src='//code.jquery.com/jquery-1.9.1.js'></script>
<script type='text/javascript' src="http://d3js.org/d3.v4.min.js"></script>
<div class="timelinechart" data-role="timelinechart" data-width=500 data-height=300 data-data="" ></div>


是的 - 类似这样 - 使用配置对象 - https://jsfiddle.net/KgomDr/46uLtcvf/ - Rob
好的 - 我正在尝试基于可能的真实数据进行建模 - 时间戳/日期对象之间的转换有多容易 - 是否可以将其添加到配置对象中? - Rob
那么在最新的fiddle中有什么问题和剩下什么? - Mayank Patel
我正在尝试添加这个--在加载时设置画笔功能--https://bl.ocks.org/micahstubbs/3cda05ca68cba260cb81 - Rob
你好,你能帮我解决这个问题吗?https://dev59.com/Xr_qa4cB1Zd3GeqPP9Fm - Javascript Coder
显示剩余7条评论

1

从您的问题中不清楚您所说的基本矩形是什么意思,但是您可以通过使用.style("opacity", 0)将任何不想看到的内容隐藏起来,对于每个要隐藏的元素都要设置透明度为0,如下所示(我几乎隐藏了所有内容,除了范围线,这是我对基本矩形的最佳猜测)。您仍然可以像以前一样选择和擦拭它:

$(document).ready(function() {


  var $this = $('.timelinechart');
    
      var w = $this.data("width");
      var h = $this.data("height");
      //var data = $this.data("data");

      
    var data = [
      {
        "label": "person a",
        "icon": "4",
        "times": [
          {"text": "Test 1", "starting_time": 1355752800000, "ending_time": 1355759900000},
          {"text": "Test 2", "starting_time": 1355767900000, "ending_time": 1355774400000},
          {"text": "Test 6", "starting_time": 1355761900000, "ending_time": 1355764520000},
          {"text": "Test 7", "starting_time": 1355767900000, "ending_time": 1355774400000}
        ]
      },
      {
        "label": "person b",
        "icon": "5",
        "times": [
          {"text": "Test 8", "starting_time": 1355752800000, "ending_time": 1355759900000},
          {"text": "Test 9", "starting_time": 1355767900000, "ending_time": 1355774400000},
          {"text": "Test 10", "starting_time": 1355767900000, "ending_time": 1355867900000}
        ]
      }
    ];


    var lanes = [];
    var times = [];
    var icons = [];
    $.each(data, function(index, value) {
      lanes.push(value.label);
      //icons.push(_avatarList[value.icon].image);
      $.each(value.times, function(i, v) {
        v["lane"] = index;
      });
      times.push(value.times); 
    });

    var laneLength = lanes.length;
    var items = [].concat.apply([], times);

    $.each(items, function(i, v) {
      v["id"] = i;
    });

    var timeBegin = d3.min(items, function(d) { return d["starting_time"]; });
    var timeEnd = d3.max(items, function(d) { return d["ending_time"]; });

    var m = [25, 80, 15, 105], //top right bottom left 
      w = w - m[1] - m[3],
      h = h - m[0] - m[2],
      miniHeight = laneLength * 12 + 50,
      mainHeight = h - miniHeight - 50;

    //scales
    var x =  d3.scaleTime()
        .range([0, w])    
        .domain([timeBegin, timeEnd]);
    var x1 = d3.scaleLinear()
        .range([0, w]);
    var y1 = d3.scaleLinear()
        .range([0, mainHeight])
        .domain([0, laneLength]);
    var y2 = d3.scaleLinear()
        .range([0, miniHeight])
        .domain([0, laneLength]);

    var xAxis = d3.axisBottom(x)
      .ticks(d3.timeMonth)
      .tickFormat(d=>d3.timeFormat("%B %Y")(d));


    var scaleFactor = (1/(timeEnd - timeBegin)) * (w);

    var chartWidth = w + m[1] + m[3];
    var chartHeight = h + m[0] + m[2];

    var chart = d3.select($this[0])
          .append("svg")
          .attr("width", chartWidth)
          .attr("height", chartHeight)
          .attr("viewBox", "0 0 "+chartWidth+" "+chartHeight)
          .attr("preserveAspectRatio", "xMidYMid meet")
          .append("g")
          .attr("class", "timelinechartg");
    
    chart.append("defs").append("clipPath")
      .attr("id", "clip")
      .append("rect")
      .attr("width", w)
      .attr("height", mainHeight);

    var main = chart.append("g")
          .attr("transform", "translate(" + m[3] + "," + m[0] + ")")
          .attr("width", w)
          .attr("height", mainHeight)
          .attr("class", "main");

    var mini = chart.append("g")
          .attr("transform", "translate(" + m[3] + "," + (mainHeight + m[0]) + ")")
          .attr("width", w)
          .attr("height", miniHeight)
          .attr("class", "mini");


    var gX = chart.append("g")
          .attr("class", "axis")
          .attr("transform", "translate(" + m[3] + "," + (mainHeight + miniHeight) + ")")
          .call(xAxis); 
          
    //background colors
    function colores_background(n) {
      var colores_g = ["#f8dd2f", "#e9168a", "#448875", "#2b2d39", "#c3bd75", "#1b91dc"];
      return colores_g[n % colores_g.length];
    }

    //foreground colors
    function colores_foreground(n) {
      var colores_g = ["#553814", "#311854", "#f7b363", "#c12f39", "#89191d", "#2b2d39"];
      return colores_g[n % colores_g.length];
    }

    //main lanes and texts
    main.append("g").selectAll(".laneLines")
      .data(items)
      .enter().append("line")
      .attr("x1", 0)
      .attr("y1", function(d) {return y1(d.lane);})
      .attr("x2", w)
      .attr("y2", function(d) {return y1(d.lane);})
      .attr("stroke", "lightgray")

        var defs = main.append('svg:defs');

    main.append("g").selectAll(".laneText")
      .data(lanes)
      .enter().append("text")
      .text(function(d) {return d;})
      .attr("x", (-m[1] + 10))
      .attr("y", function(d, i) {
        return y1(i + .5);
      })
      .attr("dy", ".5ex")
      .attr("text-anchor", "end")
      .attr("class", "laneText");

    //mini lanes and texts
    mini.append("g").selectAll(".laneLines")
      .data(items)
      .enter().append("line")
      .attr("x1", 0)
      .attr("y1", function(d) {
        return y2(d.lane);
      })
      .attr("x2", w)
      .attr("y2", function(d) {
        return y2(d.lane);
      })
      .style("opacity", 0)
      .attr("stroke", "lightgray");

    mini.append("g").selectAll(".laneText")
      .data(lanes)
      .enter().append("text")
      .text(function(d) {return d;})
      .attr("x", -m[1] + 40)
      .attr("y", function(d, i) {return y2(i + .5);})
      .attr("dy", ".5ex")
      .attr("text-anchor", "end")
      .style("opacity", 0)
      .attr("class", "laneText");

    var itemRects = main.append("g")
              .attr("clip-path", "url(#clip)");
        
    //mini item rects
    mini.append("g").selectAll("miniItems")
      .data(items)
      .enter().append("rect")
      .attr("class", function(d) {return "miniItem "+d.state;})
      .attr("x", function(d) {return x(d.starting_time);})
      .attr("y", function(d) {return y2(d.lane + .5) - 5;})
      .attr("fill", function(d, i) {
        return colores_background(d.lane);
      })
      .attr("width", function(d) {
        return (d.ending_time - d.starting_time) * scaleFactor;
      })
      .style("opacity", 0)
      .attr("height", 10);

    //mini labels
    mini.append("g").selectAll(".miniLabels")
      .data(items)
      .enter().append("text")
      .text(function(d) {return d.text;})
      .attr("class", function(d) {return d.state;})
      .attr("x", function(d) {return x(d.starting_time);})
      .attr("y", function(d) {
        return y2(d.lane + .5);
      })
      .attr("fill", function(d, i) {
        return colores_foreground(d.lane);
      })
      .style("opacity", 0)
      .attr("dy", ".5ex");

    $.each(icons, function(index, value) {
      defs.append('svg:pattern')
        .attr('id', "--"+index)
        .attr('width', 1)
        .attr('height', 1)
        .append('svg:image')
        .attr('image-rendering', "optimizeQuality")
        .attr('preserveAspectRatio', "xMidYMid meet")
        .attr('xlink:href', value)
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', 50)
        .attr('height', 50);

      defs.append('svg:pattern')
        .attr('id', "--m"+index)
        .attr('width', 1)
        .attr('height', 1)
        .append('svg:image')
        .attr('image-rendering', "optimizeQuality")
        .attr('preserveAspectRatio', "xMidYMid meet")
        .attr('xlink:href', value)
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', 20)
        .attr('height', 20);  

      main.append("g")
          .attr("transform", function(d, i) {
          return "translate("+(-m[1] + 5)+","+ (y1(index + .5) - 50) +")";
        })
          .append("circle")
          .attr("class", "user")
          .style("stroke", "gray")
          .style("fill", "url(#--"+index+")")
          .attr("r", 25)
          .attr("cx", 40)
          .attr("cy", 50);

      mini.append("g")
          .attr("transform", function(d, i) {
          return "translate("+(-m[1] + 40)+","+ (y2(index + .5) - 20) +")";
        })
          .append("circle")
          .attr("class", "user")
          .style("stroke", "gray")
          .style("fill", "url(#--m"+index+")")
          .attr("r", 10)
          .attr("cx", 20)
          .attr("cy", 20);
    });

    var brush = d3.brushX()
        .extent([[0, 0], [w, miniHeight]])
        .on("brush", brushed);

    mini.append("g")
      .attr("class", "x brush")
      .call(brush)
      .selectAll("rect")
      .attr("y", 1)
      .attr("height", miniHeight - 1); 

    function brushed() {
      var selection = d3.event.selection;
      var timeSelection = selection.map(x.invert, x);
      //console.log("selection: " + selection);
      //console.log("start: " + timeSelection[0]);
      //console.log("end: " + timeSelection[1]);
      
      var rects;
      var labels;
      var minExtent = timeSelection[0];
      var maxExtent = timeSelection[1];    
      
      var visItems = items.filter(function(d) {return d.starting_time <  maxExtent && d.ending_time > minExtent;});
    
        //mini.select(".brush")
          //.call(brush.extent([minExtent, maxExtent]));          
          
        x1.domain([minExtent, maxExtent]);      
        
        //update main item rects
        rects = itemRects.selectAll("rect")
                .data(visItems, function(d) { return d.id; })
            .attr("x", function(d) {return x1(d.starting_time);})
            .attr("width", function(d) {return x1(d.ending_time) - x1(d.starting_time);});
        
        rects.enter().append("rect")
          .attr("class", function(d) {return "miniItem "+d.state;})
          .attr("x", function(d) {return x1(d.starting_time);})
          .attr("y", function(d) {return y1(d.lane) + 10;})
          .attr("fill", function(d, i) {
            return colores_background(d.lane);
          })
          .attr("width", function(d) {return x1(d.ending_time) - x1(d.starting_time);})
          .attr("height", function(d) {return .8 * y1(1);});

        rects.exit().remove();

        //update the item labels
        labels = itemRects.selectAll("text")
          .data(visItems, function (d) { return d.id; })
          .attr("x", function(d) {return x1(Math.max(d.starting_time, minExtent) + 2);});

        labels.enter().append("text")
          .text(function(d) {return d.text;})
          .attr("class", function(d) {return d.state;})
          .attr("x", function(d) {return x1(Math.max(d.starting_time, minExtent));})
          .attr("y", function(d) {return y1(d.lane + .5);})
          .attr("fill", function(d, i) {
            return colores_foreground(d.lane);
          })
          .attr("text-anchor", "start");

        labels.exit().remove();
    }

});
body {
  background: #eeeeee;
}

#holder {
  overflow: hidden;
}

/*
.chart {
  shape-rendering: crispEdges;
}
*/

.timelinechart{
  /*width:100%;
  border: 1px solid red;*/
}

.timelinechart svg{
  width:100%;
  /*border: 1px solid green;*/
}

.timelinechartg{
  
}

.mini text {
  font: 10px sans-serif; 
}

.main text {
  font: 12px sans-serif; 
}

.miniItem {
  /*fill: darksalmon;*/
  stroke-width: 6; 
}

.miniItem.future{
  fill: #448875;
}
text.future {
  fill: #f7b363;
}


.brush .extent {
  stroke: #b6b8b9;
  fill: #57585b;
  fill-opacity: .365;
  stroke-width: .2;
}

.laneImg{
  border-radius: 25px;
}
<script type='text/javascript' src='//code.jquery.com/jquery-1.9.1.js'></script>
<script type='text/javascript' src="http://d3js.org/d3.v4.min.js"></script>
<div class="timelinechart" data-role="timelinechart" data-width=500 data-height=300 data-data="" ></div>


不,那不是我的意思——更像是这样——只是清理基础并删除不透明度为0的元素,https://jsfiddle.net/2mvhjr7z/2/ - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接