gpt4 book ai didi

d3.js - D3 三角形定位到一个精确的点

转载 作者:行者123 更新时间:2023-12-02 00:58:47 25 4
gpt4 key购买 nike

Good Image Bad Image

我正在尝试创建一个 D3 图表,它看起来像 Illustrator 创建的设计(好图像 1),但我能够获得的最接近定位的是第二个(坏图像 2)。

我对 D3 和一般创建 SVG 真的很陌生,所以我可能会做错这一切。下面的代码是我能够在网上弄清楚/找到的。看起来我不能直接使用 css 定位来调整元素本身的定位?我尝试通过 html 添加类,也在 JQuery 中使用 $(.myClass).css... 添加类,但我所做的一切都完全为零。唯一似乎有效的是变换,但它很难看,如第二张图片所示。

var margin = { left:10, right:10, top:10, bottom:10 };

var width = 400 - margin.left - margin.right,
height = 450 - margin.top - margin.bottom;

var g = d3.select("#pyramid-chart-area")
.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 + ")");

d3.json("../data/pyramid_hp.json").then(function(data){
data.forEach(function(d){
d.hp = +d.hp;
});

var x = d3.scaleBand()
.domain(data.map(function(d){ return d.hp; }))
.range([0, width])
.paddingInner(0.3)
.paddingOuter(0.3);

var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d){
return d.hp;
})])
.range([height, 0]);

var xAxisCall = d3.axisBottom(x);
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + height + ")")
.call(xAxisCall)
.selectAll("text")
.attr("y", "10")
.attr("x", "-5")
.attr("text-anchor", "end")
.attr("transform", "rotate(-40)");

var yAxisCall = d3.axisLeft(y)
.ticks(3)
.tickFormat(function(d){
return d;
});


g.append("g")
.attr("class", "y-axis")
.call(yAxisCall);


var arc = d3.symbol().type(d3.symbolTriangle)
.size(function(d){ return scale(d.hp); });

var scale = d3.scaleLinear()
.domain([0, 5])
.range([0, width]);

var colors = d3.scaleLinear()
.domain(d3.extent(data, function(d) {return d.hp}))
.range([
'#ffffff',
'#303030'
]);

var group = g.append('g')
.attr('transform','translate('+ 192 +','+ 320 +')')
.attr('class', 'triangle-container');


var line = group.selectAll('path')
.data(data)
.enter()
.append('path')
.attr('d', arc)
// .attr('fill',function(d){ return colorscale(d.hp); })
.attr('fill', d => colors(d.hp))
.attr('stroke','#000')
.attr('stroke-width', 1)
.attr('class', 'triangle')
.attr('transform',function(d,i){ return "translate("+ (i * 20) +","+(i * 10)+")"; });

最佳答案

您可以定位符号,但它很棘手 - 符号大小代表面积,并且正如 rioV8 所指出的那样,符号按其中心定位。但是如果你能弄清楚三角形的属性,我们就可以相对容易地放置它。

在等边三角形的情况下,您需要知道给定边的长度以及该质心的高度(即三角形高度/3)。所以这些函数可能会有用:

// get length of a side/width of upright equilateral triangle from area:
function getWidth(a) {
return Math.sqrt(4 * a / Math.sqrt(3));
}
// get height of the triangle from length of a side
function getHeight(l) {
return Math.sqrt(3)*l/2;
}

使用质心的高度,我们可以将圆定位在我们想要的位置,例如:

y = SVGheight - SymbolHeight/3 - marginBottom;

这里不需要缩放。

每个符号的 x 值确实需要一些缩放以根据您的喜好排列它们。下面我任意使用范围为[width/10,0]的线性标度,这种情况下分母会改变水平偏斜,可能有更好的方法来微调这个

这样你就可以达到预期的效果:

enter image description here

为简单起见,下面我使用表示像素区域的数据(因为您没有显示任何数据)-如果缩放区域,则缩放必须计入高度和宽度计算我还在每个三角形的顶部添加了圆圈,以供可能的标签使用,因为我们知道三角形的尺寸,现在这很简单

var margin = { left:10, right:10, top:10, bottom:10 };

var width = 400 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;

var g = 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 + ")")


var data = [
{a: 40000},
{a: 30000},
{a: 20000},
{a: 10000}
];

function getWidth(a) {
return Math.sqrt(4 * a / Math.sqrt(3));
}
function getHeight(l) {
return Math.sqrt(3)*l/2;
}

data.forEach(function(d) {
d.w = getWidth(d.a);
d.h = getHeight(d.w);
})

var x = d3.scaleLinear()
.domain(d3.extent(data, function(d){ return d.w; }) )
.range([width/10,0]);


var arc = d3.symbol().type(d3.symbolTriangle)
.size(function(d){ return d.a; });

var colors = d3.scaleLinear()
.domain(d3.extent(data, function(d) {return d.a}))
.range(['#ffffff','#303030']);

var group = g.append('g')
.attr('transform','translate('+ width/2 +',0)')
.attr('class', 'triangle-container');

var line = group.selectAll('path')
.data(data)
.enter()
.append('path')
.attr('d', arc)
.attr('fill', d => colors(d.a))
.attr('class', 'triangle')
.attr('transform',function(d,i){ return "translate("+ x(d.w) +","+ (height - d.h/3 - margin.bottom ) +")"; });

var circles = group.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) { return x(d.w); })
.attr("cy", function(d) { return height - d.h - margin.bottom; })
.attr("r", 3);
 <script src='https://d3js.org/d3.v5.min.js' type='text/javascript'></script>

轴可能会带来一些挑战

关于d3.js - D3 三角形定位到一个精确的点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52107733/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com