简体   繁体   English

如何在d3.js中条形图的每个条形的左上角设置模式原点?

[英]How to set pattern origin at the top left point of each bar of a barchart in d3.js?

I created a barchart and used patterns to fill it.我创建了一个条形图并使用模式来填充它。 For each pattern, I set x=0 and y=0, but I don't know where this (0,0) point is, so I don't know my pattern start tiling from where .对于每个模式,我设置 x=0 和 y=0,但我不知道这个 (0,0) 点在哪里,所以我不知道我的模式从哪里开始平铺。

I want to set the top left corner of bar as the origin point of pattern for each bar.我想将条形的左上角设置为每个条形的模式原点。 How can I achieve this?我怎样才能做到这一点?

Diagram of the result I want我想要的结果图

My code:我的代码:

 <!doctype html> <html> <head> <style> </style> <script src="https://d3js.org/d3.v4.min.js"></script> </head> <body> <svg width="600" height="500"></svg> <svg> <defs> <pattern id="pattern1" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" /> </pattern> </defs> <defs> <pattern id="pattern2" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <circle cx="10" cy="10" r="5" style="stroke: none; fill: #0000ff" /> </pattern> </defs> <defs> <pattern id="pattern3" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <circle cx="10" cy="10" r="3" style="stroke: none; fill: #0000ff" /> </pattern> </defs> <rect x="0" y="0" width="100" height="100" style="stroke: #000000; fill: url(#pattern1);" /> <rect x="100" y="0" width="100" height="100" style="stroke: #000000; fill: url(#pattern2);" /> <rect x="200" y="0" width="100" height="100" style="stroke: #000000; fill: url(#pattern3);" /> </svg> </body> <script> var data = [{ year: '2001', value:10 }, { year: '2002', value:30 }, { year: '2003', value:20 }, ] var svg = d3.select("svg"), margin = 200, width = svg.attr("width") - margin, height = svg.attr("height") - margin var xScale = d3.scaleBand().range([0, width]).padding(0.4), yScale = d3.scaleLinear().range([height, 0]); var g = svg.append("g") .attr("transform", "translate(" + 100 + "," + 100 + ")"); xScale.domain(data.map(function(d) { return d.year; })); yScale.domain([0, d3.max(data, function(d) { return d.value; })]); g.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(xScale)); g.append("g") .call(d3.axisLeft(yScale).tickFormat(function(d){ return d; }).ticks(10)); g.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return xScale(d.year); }) .attr("y", function(d) { return yScale(d.value); }) .attr("width", xScale.bandwidth()) .attr("height", function(d) { return height - yScale(d.value); }) .attr('stroke', "black") .attr('stroke-width', '1') .attr("fill", function(d,i) { return "url(#pattern" + (i+1) +")"}); </script> </html>

Thank you in advance.先感谢您。

What you could do, is to add the patterns using D3 as well.您可以做的是也使用 D3 添加模式。 D3 actually lets you add any type of tag to the DOM. D3 实际上允许您向 DOM 添加任何类型的标签。 Therefore, you could do a second join to add the patterns.因此,您可以进行第二次连接以添加模式。 In the following code I just "copied" your logic, but now the pattern is in the g element, and the patterns position is at the top left of your bars.在下面的代码中,我只是“复制”了您的逻辑,但现在模式位于 g 元素中,并且模式位置位于条形的左上角。 Of course you can now easily tune this, I hope it helps!当然,您现在可以轻松调整它,希望对您有所帮助!

 <!doctype html> <html> <head> <style> </style> <script src="https://d3js.org/d3.v4.min.js"></script> </head> <body> <svg width="600" height="500"></svg> <svg> <rect x="0" y="0" width="100" height="100" style="stroke: #000000; fill: url(#pattern1);" /> <rect x="100" y="0" width="100" height="100" style="stroke: #000000; fill: url(#pattern2);" /> <rect x="200" y="0" width="100" height="100" style="stroke: #000000; fill: url(#pattern3);" /> </svg> </body> <script> var data = [{ year: '2001', value:10 }, { year: '2002', value:30 }, { year: '2003', value:20 }, ] var svg = d3.select("svg"), margin = 200, width = svg.attr("width") - margin, height = svg.attr("height") - margin var xScale = d3.scaleBand().range([0, width]).padding(0.4), yScale = d3.scaleLinear().range([height, 0]); var g = svg.append("g") .attr("transform", "translate(" + 100 + "," + 100 + ")"); xScale.domain(data.map(function(d) { return d.year; })); yScale.domain([0, d3.max(data, function(d) { return d.value; })]); g.selectAll("defs.pattern") .data(data) .enter() .append("defs").append("pattern") .classed("pattern", true) .attr("id", (_, i) => `pattern${i + 1}`) .attr("x", (d) => xScale(d.year)) .attr("y", (d) => yScale(d.value)) .attr("width", 20) .attr("height", 20) .attr("patternUnits", "userSpaceOnUse") .append("circle") .attr("r", (_, i) => 3 * (i + 1)) .attr("cx", 10) .attr("cy", 10) .style("stroke", null) .style("fill", "#0000ff") g.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(xScale)); g.append("g") .call(d3.axisLeft(yScale).tickFormat(function(d){ return d; }).ticks(10)); g.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return xScale(d.year); }) .attr("y", function(d) { return yScale(d.value); }) .attr("width", xScale.bandwidth()) .attr("height", function(d) { return height - yScale(d.value); }) .attr('stroke', "black") .attr('stroke-width', '1') .attr("fill", function(d,i) { return "url(#pattern" + (i+1) +")"}); </script> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM