2015-03-26 2 views
0

Прямо сейчас у меня есть файл csv, который содержит широкий диапазон точек данных, которые я показываю в сложной гистограмме. Дело в том, что я хочу, чтобы я мог управлять диапазоном значений, отображаемых на оси х, динамически с помощью ползунка.D3- Обновить диапазон оси гистограммы с ползунком

т.е. изменения ползунка от 1 -> 5 теперь будет отображать только бруски данных больше, чем 5.

У меня есть функция обновления, который обрабатывает изменение значения слайдера и даже динамически изменять метки для оси х, но бары сами не меняются ...

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

body { 
    font: 10px sans-serif; 
} 

.axis path, 
.axis line { 
    fill: none; 
    stroke: #000; 
    shape-rendering: crispEdges; 
} 

.bar { 
    fill: steelblue; 
} 

.x.axis path { 
    display: none; 
} 

.x.axis line { 
    display: none; 
} 

.d3-tip { 
    line-height: 1; 
    font-weight: bold; 
    padding: 12px; 
    background: rgba(0, 0, 0, 0.8); 
    color: #fff; 
    border-radius: 2px; 
} 

/* Creates a small triangle extender for the tooltip */ 
.d3-tip:after { 
    box-sizing: border-box; 
    display: inline; 
    font-size: 10px; 
    width: 100%; 
    line-height: 1; 
    color: rgba(0, 0, 0, 0.8); 
    content: "\25BC"; 
    position: absolute; 
    text-align: center; 
} 

/* Style northward tooltips differently */ 
.d3-tip.n:after { 
    margin: -1px 0 0 0; 
    top: 100%; 
    left: 0; 
} 

</style> 

<p> 
    <label for="nMedals" 
     style="display: inline-block; width: 240px; text-align: right"> 
     Total Medals = <span id="nMedals-value">…</span> 
    </label> 
    <input type="range" min="0" max="50" id="nMedals"> 
</p> 

<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script> 
<script> 

var margin = {top: 60, right: 20, bottom: 85, left: 40}, 
    width = 1160 - margin.left - margin.right, 
    height = 500 - margin.top - margin.bottom; 

var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width], .1); 

var y = d3.scale.linear() 
    .rangeRound([height, 0]); 

var color = d3.scale.ordinal() 
    .range(["#EAC530", "#c0c0c0", "#cd7f32"]); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .tickFormat(d3.format(".2s")); 

var tip = d3.tip() 
    .attr('class', 'd3-tip') 
    .offset([-10, 0]) 
    .html(function(d) { 
    return "<strong>" + d.medals[0].name + ":</strong> <span style='color:white'>" + d.medals[0].y1 + "</span>" + 
    "<br/><strong>" + d.medals[1].name + ":</strong> <span style='color:white'>" + (d.medals[1].y1 - d.medals[0].y1) + "</span>" + 
    "<br/><strong>" + d.medals[2].name + ":</strong> <span style='color:white'>" + (d.medals[2].y1 - d.medals[1].y1) + "</span>"; 
    }) 

var filterMedals = 0; 

d3.select("#nMedals").on("input", function(){ 
    update(+this.value); 
}); 

function update(nMedals){ 
    d3.select("#nMedals-value").text(nMedals); 
    d3.select("#nMedals").property("value", nMedals); 

    filterMedals = nMedals; 

    //get data again 
    d3.csv("data/Olympics.csv", function(error, data) { 
    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Country" && key !== "TotalMedals"; })); 

    data.forEach(function(d) { 
    var y0 = 0; 
    d.medals = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; }); 
    d.total = d.medals[d.medals.length - 1].y1; 
    }); 

    data.sort(function(a, b) { return b.total - a.total; }); 

    //Put all countries with more than 5 medals in the x-axis 
    x.domain(data.map(function(d) { if (d.TotalMedals > filterMedals) return d.Country; })); 
    y.domain([0, d3.max(data, function(d) { return d.total; })]); 


    //select area we want to change 
    var svg = d3.select("body").transition(); 

    //make changes 
    svg.select(".x.axis") // change the x axis 
    .duration(750) 
    .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
     .selectAll("text") 
     .style("text-anchor", "end") 
     .attr("dx", "-.8em") 
     .attr("dy", ".15em") 
     .attr("transform", function(d) { 
      return "rotate(-65)" 
      }); 

    //Do whatever to the bars 
    var country = svg.selectAll(".Country") 
     .data(data) 
     .filter(function(d) { return d.total > filterMedals }) 

    country.enter() 
     .append("g") 
     .attr("transform", function(d) { return "translate(" + x(d.Country) + ",0)"; }) 
     .on('mouseover', tip.show) 
     .on('mouseout', tip.hide); 

    country.selectAll("rect") 
     .data(function(d) { return d.medals; }) 
     .enter().append("rect") 
     .attr("width", x.rangeBand()) 
     //puts bars on the bottom x-axis 
     .attr("y", function(d) { return y(d.y1); }) 
     .attr("height", function(d) { return y(d.y0) - y(d.y1); }) 
     //Does the coloring of the bars 
     .style("fill", function(d) { return color(d.name); }); 

    country.exit().remove() 


    }); 
} 

var svg = d3.select("body").append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
     .append("text") 
     .text("Countries") 
     .attr("transform", function(d) {return "translate(" + -.75 * margin.left + ", " + margin.bottom * .5 + ")";}); 

svg.call(tip); 

d3.csv("data/Olympics.csv", function(error, data) { 
    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Country" && key !== "TotalMedals"; })); 

    data.forEach(function(d) { 
    var y0 = 0; 
    d.medals = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; }); 
    d.total = d.medals[d.medals.length - 1].y1; 
    }); 

    data.sort(function(a, b) { return b.total - a.total; }); 

    //Put all countries with more than 5 medals in the x-axis 
    x.domain(data.map(function(d) { if (d.TotalMedals > filterMedals) return d.Country; })); 
    y.domain([0, d3.max(data, function(d) { return d.total; })]); 

    //Puts the name of the countries on the x-axis 
    svg.append("g") 
     .attr("class", "x axis") 


    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Medals"); 

    var country = svg.selectAll(".Country") 
     .data(data) 
     .enter().append("g") 
     //moves bars along x-axis 
     .attr("transform", function(d) { return "translate(" + x(d.Country) + ",0)"; }) 
     .on('mouseover', tip.show) 
     .on('mouseout', tip.hide); 

    country.selectAll("rect") 
     .data(function(d) { return d.medals; }) 
     .enter().append("rect") 
     .attr("width", x.rangeBand()) 
     //puts bars on the bottom x-axis 
     .attr("y", function(d) { return y(d.y1); }) 
     .attr("height", function(d) { return y(d.y0) - y(d.y1); }) 
     //Does the coloring of the bars 
     .style("fill", function(d) { return color(d.name); }); 


    var legend = svg.selectAll(".legend") 
     .data(color.domain().slice().reverse()) 
    .enter().append("g") 
     .attr("class", "legend") 
     .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); 

    legend.append("rect") 
     .attr("x", width - 18) 
     .attr("width", 18) 
     .attr("height", 18) 
     .style("fill", color); 

    legend.append("text") 
     .attr("x", width - 24) 
     .attr("y", 9) 
     .attr("dy", ".35em") 
     .style("text-anchor", "end") 
     .text(function(d) { return d; }); 

    update(0); 
}); 

</script> 

ответ

0

сломать ваш войти, обновление, удаление следующим образом:

var medals = country.selectAll("rect") 
    .data(function(d) { return d.medals; }) 
    .enter(); 
medals.append("rect"); 

medals.attr("width", x.rangeBand()) 
    //puts bars on the bottom x-axis 
    .attr("y", function(d) { return y(d.y1); }) 
    .attr("height", function(d) { return y(d.y0) - y(d.y1); }) 
    //Does the coloring of the bars 
    .style("fill", function(d) { return color(d.name); }); 

country.exit().remove() 

так, как вы сделали это, ваши атрибуты и стили применяются только к вашим вновь созданным прямоугольникам.

Смежные вопросы