D3.js-如何在放大分组条形图时剪切矩形外的区域

时间:2016-06-27 10:42:34

标签: javascript jquery d3.js svg

这是我的代码http://jsfiddle.net/qkHK6/2174/的链接。我想隐藏或剪裁矩形外的区域。你可以从我的jsfiddle看到,当缩放时,条形移动到y轴的左边,所以我想要剪辑该区域。请有人帮助我。

var margin = {
    top: 20,
    right: 20,
    bottom: 30,
    left: 40
  },
  width = 300 - margin.left - margin.right,
  height = 400 - margin.top - margin.bottom;
//Data used for bar chart
var data = [{
  "State": "CA",
  "Under 5 Years": 2704659,
  "5 to 13 Years": 4499890,
  "14 to 17 Years": 2159981,
  "18 to 24 Years": 3853788,
  "25 to 44 Years": 10604510,
  "45 to 64 Years": 8819342,
  "65 Years and Over": 4114496
}, {
  "State": "TX",
  "Under 5 Years": 2027307,
  "5 to 13 Years": 3277946,
  "14 to 17 Years": 1420518,
  "18 to 24 Years": 2454721,
  "25 to 44 Years": 7017731,
  "45 to 64 Years": 5656528,
  "65 Years and Over": 2472223
}, {
  "State": "NY",
  "Under 5 Years": 1208495,
  "5 to 13 Years": 2141490,
  "14 to 17 Years": 1058031,
  "18 to 24 Years": 1999120,
  "25 to 44 Years": 5355235,
  "45 to 64 Years": 5120254,
  "65 Years and Over": 2607672
}, {
  "State": "FL",
  "Under 5 Years": 1140516,
  "5 to 13 Years": 1938695,
  "14 to 17 Years": 925060,
  "18 to 24 Years": 1607297,
  "25 to 44 Years": 4782119,
  "45 to 64 Years": 4746856,
  "65 Years and Over": 3187797
}, {
  "State": "IL",
  "Under 5 Years": 894368,
  "5 to 13 Years": 1558919,
  "14 to 17 Years": 725973,
  "18 to 24 Years": 1311479,
  "25 to 44 Years": 3596343,
  "45 to 64 Years": 3239173,
  "65 Years and Over": 1575308
}, {
  "State": "PA",
  "Under 5 Years": 737462,
  "5 to 13 Years": 1345341,
  "14 to 17 Years": 679201,
  "18 to 24 Years": 1203944,
  "25 to 44 Years": 3157759,
  "45 to 64 Years": 3414001,
  "65 Years and Over": 1910571
}];
var x0 = d3.scale.ordinal()
  .rangeRoundBands([0, width], .1);

var x1 = d3.scale.ordinal();

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

用于不同年龄的颜色

 var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c",   "#ff8c00"]);



 creating axis and bar graph

var xAxis = d3.svg.axis()   .scale(X0)   。东方("底部&#34);

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

var svg = d3.select("#chart").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 + ")")
  .call(d3.behavior.zoom().scaleExtent([1, 10]).on("zoom", zoom));

//d3.csv("data.csv", function(error, data) {
var ageNames = d3.keys(data[0]).filter(function(key) {
  return key !== "State";
});
console.log("ageNames=" + JSON.stringify(ageNames));
data.forEach(function(d) {
  d.ages = ageNames.map(function(name) {
    return {
      name: name,
      value: +d[name]
    };
  });
  console.log("d.ages=" + JSON.stringify(d.ages));
});

x0.domain(data.map(function(d) {
  return d.State;
}));
x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) {
  console.log(" before retuen d.ages=" + d.ages);
  return d3.max(d.ages, function(d) {
    console.log("d.value;=" + d.value);
    return d.value;
  });
})]);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

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

var allStates = svg.append("g")
  .attr("class", "allStates");


var state = allStates.selectAll(".state")
  .data(data)
  .enter().append("g")
  .attr("class", "state")
  .attr("transform", function(d) {
    return "translate(" + x0(d.State) + ",0)";
  });

state.selectAll("rect")
  .data(function(d) {
    return d.ages;
  })
  .enter().append("rect")
  .attr("width", x1.rangeBand())
  .attr("x", function(d) {
    return x1(d.name);
  })
  .attr("y", function(d) {
    return y(d.value);
  })
  .attr("height", function(d) {
    return height - y(d.value);
  })
  .style("fill", function(d) {
    return color(d.name);
  });
var legnColorGap = height / 17.5;
var legend = svg.selectAll(".legend")
  .data(ageNames.slice().reverse())
  .enter().append("g")
  .attr("class", "legend")
  .attr("transform", function(d, i) {
    return "translate(0," + i * legnColorGap + ")";
  });
var lwidth = width / 75,
  lht = height / 22,
  lwidth1 = lwidth + 2;
legend.append("rect")
  .attr("x", width - lwidth1)
  .attr("width", lwidth)
  .attr("height", lht)
  .style("fill", color);
var textht = lht / 2,
  textwd = textht + lwidth;
legend.append("text")
  .attr("x", width - textwd)
  .attr("y", textht)
  .attr("dy", ".35em")
  .style("text-anchor", "end")
  .text(function(d) {
    return d;
  });


  //Zooming Function 
function zoom() {
  svg.select(".allStates").attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)");
  svg.select(".x.axis").attr("transform", "translate(" + d3.event.translate[0] + "," + (height) + ")").call(xAxis.scale(x0.rangeRoundBands([0, width * d3.event.scale], .5 * d3.event.scale)));
  svg.select(".y.axis").call(yAxis);
}

2 个答案:

答案 0 :(得分:2)

这是updated jsfiddle

归结为一些修改。首先,您需要了解SVG clip-path这是一种定义svg形状的方法,该形状可以掩盖或裁剪另一种形状(在本例中为您的图表)。如链接文档中所示,<defs>需要<clipPath>元素,其中包含<clipPath>。在您的情况下,<rect>需要包含<defs>,其边界设置为覆盖可见区域。

要创建var mask = svg.append("defs") .append("clipPath") .attr("id", "mask") .style("pointer-events", "none") .append("rect") .attr({ x: 0, y: 0, width: width, height: height + margin.bottom, }) ,我添加了:

.attr("clip-path", "url(#mask)")

最终,要使用上面的遮罩来裁剪图表,需要调用

<g>

关于被掩盖的东西。

你设置的方式,没有一个SVG <g>包含需要屏蔽的东西(即图表和x轴)。所以我添加了allStates,并重新调整了一些内容,以便将轴和图表(var masked = svg.append("g") .attr("clip-path", "url(#mask)") masked.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); var allStates = masked .append("g") .attr("class", "allStates"); )添加到其中:

IBOutlet

就是这样。

答案 1 :(得分:0)

怎么样?

function zoom() {
svg.select(".allStates").attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)");
svg.select(".x.axis").attr("transform", "translate(" + d3.event.translate[0] + "," + (height) + ")").call(xAxis.scale(x0.rangeRoundBands([0, width * d3.event.scale], .5 * d3.event.scale)));
//svg.select(".y.axis").call(yAxis);
svg.select(".y.axis").attr("transform", "translate(" + (d3.event.translate[0]-d3.event.scale) + ", 0)")
}

我刚刚添加了最后一行,在缩放时将Y轴向左移动。

如果这对您来说足够了,请告诉我。