Gráfico de línea de tiempo d3js: con un bloque de rectángulo para un fregado

8

Estoy buscando crear un gráfico de línea de tiempo con solo un bloque de rectángulo en la parte inferior. Eso se usa como un depurador maestro.

// actual - http://jsfiddle.net/NYEaX/2427/

ingrese la descripción de la imagen aquí

donde está la sección de fregado: quiero tener solo un rectángulo base. ¿Qué tipo de modificaciones debo hacer a la base de código actual?

así que es más como esto ingrese la descripción de la imagen aquí

// mi último - 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>


el último diseño es así ingrese la descripción de la imagen aquí

y a medida que el depurador muestra más detalles, como un intervalo de fechas de 1 mes, el formato de la escala se vuelve más detallado ingrese la descripción de la imagen aquí

Robar
fuente
1
Hola, no obtuve lo que quieres hacer, ¿quieres eliminar la sección 'persona p' del gráfico?
RAÍZ
solo tiene un solo rectángulo, un depurador genérico, en lugar de una versión mini del gráfico principal
Rob
1
como esto jsfiddle.net/2mvhjr7z/2
Rob
¿quiere decir eliminar las barras amarillas y rosadas y mantener una línea pequeña y delgada como la del violín provisto?
RAÍZ
1
sí, algo como esto - jsfiddle.net/KgomDr/46uLtcvf
Rob

Respuestas:

3

Aunque no tengo claro qué es exactamente lo que quieres lograr, supongo que necesitas tener un rectángulo base genérico.

He eliminado la línea de código para mostrar la etiqueta de este rectángulo base y he actualizado la altura de la mini sección.

Avíseme si esto no es lo que espera.

Por favor revise mi violín.

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

Mayank Patel
fuente
sí, algo como esto, con un objeto de configuración - jsfiddle.net/KgomDr/46uLtcvf
Rob
¿Medio? ¿Cuál es el problema en mi resultado? ¿Puedes explicar qué es exactamente lo que falta?
Mayank Patel
Si. Esto es posible. ¿Puedes almacenar tu fecha como un dateobjeto en lugar de marcas de tiempo?
Mayank Patel
bueno, estoy tratando de modelarlo con datos reales posibles: ¿qué tan fácil es la conversión entre la marca de tiempo / objeto de fecha? ¿Es posible agregar esto al objeto de configuración?
Rob
jsfiddle.net/m0czbuxs/2 : agregué el objeto de configuración al dom, por lo que todo está en un solo lugar: es necesario agregar más clases para que los estilos se configuren en el CSS. He agregado más datos para acercarme a la estructura de datos real, pero el mini soporte con el depurador todavía está creando líneas verticales incorrectamente. He agregado una información sobre herramientas en esta versión: jsfiddle.net/m0czbuxs/3
Rob
1

No está claro en su pregunta qué quiere decir con el rectángulo base , sin embargo, puede ocultar cualquier cosa que no quiera ver estableciendo la opacidad en 0 usando .style("opacity", 0)para cada elemento que desea ocultar de la siguiente manera (escondí casi todo , excepto la línea de rango, que fue mi mejor conjetura para el rectángulo base ). Todavía puede seleccionarlo y restregarlo como antes:

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

isp-zax
fuente
no, eso no es lo que quise decir, algo más como esto, solo limpiar la base y sacar, no opacidad: 0 elementos, jsfiddle.net/2mvhjr7z/2
Rob