biểu đồ dòng thời gian của d3js - với một khối hình chữ nhật để chà


8

Tôi đang xem xét việc tạo một biểu đồ dòng thời gian chỉ có một khối hình chữ nhật ở phía dưới. Nó được sử dụng như một máy chà sàn chính.

// hiện tại - http://jsfiddle.net/NYEaX/2427/

nhập mô tả hình ảnh ở đây

trong đó phần chà là - tôi muốn chỉ có một hình chữ nhật cơ sở. Tôi nên thực hiện loại sửa đổi nào cho cơ sở mã hiện tại

vì vậy nó giống như thế này nhập mô tả hình ảnh ở đây

// mới nhất của tôi - 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>


thiết kế mới nhất là như thế này nhập mô tả hình ảnh ở đây

và khi bộ lọc hiển thị chi tiết hơn - như phạm vi ngày 1 tháng - định dạng của thang đo trở nên chi tiết hơn nhập mô tả hình ảnh ở đây


1
Xin chào, tôi không nhận được những gì bạn muốn làm, bạn có muốn xóa phần 'người p' khỏi biểu đồ không?
ROOT

chỉ có một hình chữ nhật duy nhất - một bộ lọc chung - chứ không phải là một phiên bản nhỏ của biểu đồ chính
Rob

1
như thế này jsfiddle.net/2mvhjr7z/2
Rob

bạn có nghĩa là để loại bỏ các thanh màu vàng và màu hồng và giữ một dòng nhỏ mỏng như cái trong fiddle được cung cấp?
ROOT

1
vâng - một cái gì đó như thế này - jsfiddle.net/KeimDr/46uLtcvf
Rob

Câu trả lời:


3

Mặc dù tôi không rõ ràng về chính xác những gì bạn muốn đạt được, tôi giả sử bạn cần phải có hình chữ nhật cơ sở chung.

Tôi đã xóa dòng mã để hiển thị nhãn của hình chữ nhật cơ sở này và đã cập nhật chiều cao của phần mini.

Hãy cho tôi biết nếu đây không phải là những gì bạn đang mong đợi.

Vui lòng xem lại fiddle của tôi.

$(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>


có - một cái gì đó như thế này - với một đối tượng cấu hình - jsfiddle.net/KeimDr/46uLtcvf
Rob

Có nghĩa? Vấn đề trong kết quả của tôi là gì? Bạn có thể giải thích chính xác những gì đang thiếu?
Mayank Patel

Đúng. Điều này là khả thi. Bạn có thể lưu trữ ngày của bạn như một dateđối tượng thay vì dấu thời gian?
Mayank Patel

tốt - Tôi đang cố gắng mô hình hóa nó trên dữ liệu thực có thể - việc chuyển đổi giữa đối tượng dấu thời gian / ngày dễ dàng như thế nào - có thể thêm điều này vào đối tượng cấu hình không?
Cướp

jsfiddle.net/m0czbuxs/2 - Tôi đã thêm đối tượng cấu hình vào dom để tất cả ở một nơi-- - cần thêm nhiều lớp hơn để các kiểu được cấu hình trong css. Tôi đã thêm nhiều dữ liệu để đến gần hơn với cấu trúc dữ liệu thực tế - nhưng bộ giữ mini với bộ lọc vẫn đang tạo các đường thẳng đứng không chính xác. Tôi đã thêm một chú giải công cụ trên phiên bản này - jsfiddle.net/m0czbuxs/3
Rob

1

Không rõ câu hỏi của bạn là gì bởi hình chữ nhật cơ sở , tuy nhiên, bạn có thể ẩn bất cứ điều gì bạn không muốn thấy bằng cách đặt độ mờ thành 0 bằng cách sử dụng .style("opacity", 0)cho từng yếu tố bạn muốn ẩn như sau (Tôi đã giấu khá nhiều thứ , ngoại trừ dòng phạm vi là dự đoán tốt nhất của tôi cho hình chữ nhật cơ sở ). Bạn vẫn có thể chọn và chà lên nó như trước:

$(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>


không - đó không phải là những gì tôi có nghĩa là - một cái gì đó nhiều như thế này - chỉ dọn dẹp các cơ sở và lấy ra, không opacity: 0 tố, jsfiddle.net/2mvhjr7z/2
Rob
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.