d3.js中的可排序条形图

时间:2017-01-11 14:49:36

标签: d3.js bar-chart jquery-ui-sortable

我是d3.js的新手,我正在尝试创建一个可排序的条形图。我正在关注这个例子,但我无法得到相同的结果。条形移动但标签不移动。我不确定我做错了什么。任何指导都非常感谢。感谢

<label><input id="sort" type="checkbox"> Sort values</label>
<div id="check"></div>

<script src="~/Scripts/d3-tip.js"></script>
<script>
debugger;

var data=@Html.Raw(@JsonConvert.SerializeObject(Model));

var margin = {
    top: 20,
    right: 20,
    bottom: 50,
    left: 40
},
width = 250 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;




var x=d3.scaleBand()
.rangeRound([0, width])
.padding(0.1);

var y=d3.scaleLinear().range([height,0]);


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

var tip=d3.tip()
       .attr("class","d3-tip")
       .offset([-10,0])
       .html(function(d){

 return "<strong>Rec Items:</strong> <span style='color:red'>" +        d.TotalRecItemsSum + "</span>"
 })


chart.call(tip)

x.domain(data.map(function(d){
    return d.AppClientName;
})) //x domain is a map of all client names

y.domain([0,d3.max(data,function(d){return d.TotalRecItemsSum;})])
//y is range from maximum(count) value in array until 0

chart.selectAll(".bar").data(data).enter().append("svg:rect")
.attr("x",function(d){
    return x(d.AppClientName);
})
.attr("class", "bar")

.attr("width",x.bandwidth())

.attr("y",function (d){
    return y(d.TotalRecItemsSum);})

.attr("height",function(d){
    return height-y(d.TotalRecItemsSum);})


.on('mouseover', tip.show)
.on('mouseout', tip.hide)

var xAxis=d3.axisBottom().scale(x);

var yAxis=d3.axisLeft().scale(y);



chart.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("TotalRecItemSum");

chart.append("g").attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("transform","rotate(90)")//In some cases the labels will overlap
 //so I want to rotate the label's so they are vertical
.attr("x", 0) //After that some finetuning to align everything the right way:
.attr("y", -6)
.attr("dx", ".6em")
.attr("class","x axis")
.attr("class","text")
.style("text-anchor", "start")


d3.select("#sort").on("change", change);

var sortTimeout = setTimeout(function() {
    d3.select("#sort").property("checked", true).each(change);
}, 2000);

function change() {
    clearTimeout(sortTimeout);

    // Copy-on-write since tweens are evaluated after a delay.
    var x0 = x.domain(data.sort(this.checked
        ? function(a, b) { return b.TotalRecItemsSum - a.TotalRecItemsSum; }
       : function(a, b) { return d3.ascending(a.AppClientName, b.AppClientName); })
        .map(function(d) { return d.AppClientName; }))
        .copy();

    chart.selectAll(".bar")
        .sort(function(a, b) { return x0(a.AppClientName) - x0(b.AppClientName); });

    var transition = chart.transition().duration(750),
        delay = function(d, i) { return i * 100; };

    transition.selectAll(".bar")
        .delay(delay)     
        .attr("x", function(d) { return x0(d.AppClientName); });



    transition.select(".x.axis")
        .call(xAxis)
        .selectAll("g")
        .delay(delay);
}

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

.chart rect {
    stroke: white;
    fill: orange;
}

.bar:hover {
    fill: orangered;
}

.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;
    }

    .d3-tip.n:after {
        margin: -1px 0 0 0;
        top: 100%;
        left: 0;
    }


.x.axis path {
    display: none;
}

我正在使用d3版本4.在上面的代码中,我的x轴有客户名称,y轴是数值。因此,在选中复选框时,栏会按升序排列,只有标签不会移动。另外,另一个问题是复选框会在几秒钟后自动检查,这是因为var超时而发生的,所以我应该在函数更改中加入超时吗?

如果我的解释不清楚,请问我任何问题,我总是很难说清楚。谢谢。

0 个答案:

没有答案