gpt4 book ai didi

javascript - d3.js:饼图布局 - 调整 Angular 以创建快门效果

转载 作者:行者123 更新时间:2023-12-01 17:43:21 25 4
gpt4 key购买 nike

我的任务是使用 d3.js 重新创建一个交互式饼图 - 我的饼图各部分的 Angular 不是从饼图的中间开始的(见下图)并且稍微偏离。绘制我想要的快门效果的最佳方法是什么?您可以在下面看到我的代码到了什么地方。

JS fiddle : http://jsfiddle.net/vh6nwtpb/3/

我想要获得的效果: enter image description here

JS代码

  // Data Used for this example...
var dataSet1 = [
{legendLabel: "Legend String 1", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#252d38", seghovcolour: "#005190"},
{legendLabel: "Legend String 2", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#173c59", seghovcolour: "#005190"},
{legendLabel: "Legend String 3", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#223343", seghovcolour: "#005190"},
{legendLabel: "Legend String 4", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#20364b", seghovcolour: "#005190"},
{legendLabel: "Legend String 5", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#1d3853", seghovcolour: "#005190"},
{legendLabel: "Legend String 6", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#015190", seghovcolour: "#005190"},
{legendLabel: "Legend String 7", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#144162", seghovcolour: "#005190"},
{legendLabel: "Legend String 8", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#0f436a", seghovcolour: "#005190"},
{legendLabel: "Legend String 9", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#0f4873", seghovcolour: "#005190"},
{legendLabel: "Legend String 10", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#0d4b7c", seghovcolour: "#005190"},
{legendLabel: "Legend String 11", magnitude: 9.09, link: "https://www.uk-cpi.com/", segcolour: "#0f5086", seghovcolour: "#005190"}
];

function drawPie( pieName, dataSet, selectString, colors, margin, outerRadius, innerRadius, sortArcs ) {
var colorScale = d3.scale.category20c();
var canvasWidth = 620;
var canvasHeight = 0;
var innerRadius = 150;
var outerRadius = 300;
var pieWidthTotal = outerRadius * 2;
var pieCenterX = outerRadius + margin/2;
var pieCenterY = outerRadius + margin/2;
var legendVerticalOffset = outerRadius - margin;
var legendTextOffset = 20;
var textVerticalSpace = 20;
var pieDrivenHeight = outerRadius*2 + margin*2;
var legendTextDrivenHeight = (dataSet.length * textVerticalSpace) + margin*2;

// Autoadjust Canvas Height
if (pieDrivenHeight >= legendTextDrivenHeight)
{
canvasHeight = pieDrivenHeight;
}
else
{
canvasHeight = legendTextDrivenHeight;
}

var x = d3.scale.linear().domain([0, d3.max(dataSet, function(d) { return d.magnitude; })]).rangeRound([0, pieWidthTotal]);
var y = d3.scale.linear().domain([0, dataSet.length]).range([0, (dataSet.length * 20)]);

// HOVER COLOUR
var synchronizedMouseOver = function() {
var arc = d3.select(this);
var indexValue = arc.attr("index_value");

var arcSelector = "." + "pie-" + pieName + "-arc-" + indexValue;
var selectedArc = d3.selectAll(arcSelector);
var colorValue = selectedArc.attr("color_hover");
selectedArc.style("fill", colorValue);
};

var synchronizedMouseOut = function() {
var arc = d3.select(this);
var indexValue = arc.attr("index_value");

var arcSelector = "." + "pie-" + pieName + "-arc-" + indexValue;
var selectedArc = d3.selectAll(arcSelector);
var colorValue = selectedArc.attr("fill");
selectedArc.style("fill", colorValue);

};


var tweenPie = function (b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) {
return arc(i(t));
};
}

// Create a drawing canvas...
var canvas = d3.select(selectString)
.append("svg:svg") //create the SVG element inside the <body>
.data([dataSet]) //associate our data with the document
.attr("width", canvasWidth) //set the width of the canvas
.attr("height", canvasHeight) //set the height of the canvas
.append("svg:g") //make a group to hold our pie chart
.attr("transform", "translate(" + pieCenterX + "," + pieCenterY + ")") // Set center of pie

// Define an arc generator. This will create <path> elements for using arc data.
var arc = d3.svg.arc()
.innerRadius(innerRadius) // Causes center of pie to be hollow
.outerRadius(outerRadius);

// Define a pie layout: the pie angle encodes the value of dataSet.
// Since our data is in the form of a post-parsed CSV string, the
// values are Strings which we coerce to Numbers.
var pie = d3.layout.pie()
.value(function(d) { return d.magnitude; })
.sort(function(a, b) {if (sortArcs==1) { return b.magnitude - a.magnitude; } else { return null; } });

// Select all <g> elements with class slice (there aren't any yet)
var arcs = canvas.selectAll("g.slice")
// Associate the generated pie data (an array of arcs, each having startAngle,
// endAngle and value properties)
.data(pie)
// This will create <g> elements for every "extra" data element that should be associated
// with a selection. The result is creating a <g> for every object in the data array
// Create a group to hold each slice (we will have a <path> and a <text> // element associated with each slice)
.enter().append("svg:a")
.attr("xlink:href", function(d) { return d.data.link; })
.append("svg:g")
.attr("class", "slice") //allow us to style things in the slices (like text)
// Set the color for each slice to be chosen from the color function defined above
// This creates the actual SVG path using the associated data (pie) with the arc drawing function
.style("stroke", "White" )
.attr("d", arc);

arcs.append("svg:path")

// Set the color for each slice to be chosen from the color function defined above
// This creates the actual SVG path using the associated data (pie) with the arc drawing function


.attr("fill", function(d, i) { return d.data.segcolour; })
.attr("color_hover", function(d, i) { return d.data.seghovcolour; })


.attr("index_value", function(d, i) { return "index-" + i; })
.attr("class", function(d, i) { return "pie-" + pieName + "-arc-index-" + i; })
.style("stroke", "White" )
.attr("d", arc)
.on('mouseover', synchronizedMouseOver)
.on("mouseout", synchronizedMouseOut)
.transition()
.ease("")
.duration(2000)
.delay(function(d, i) { return i * 0; })
.attrTween("d", tweenPie);

// Add a magnitude value to the larger arcs, translated to the arc centroid and rotated.
arcs.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
//.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; })
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius; // Set Outer Coordinate
d.innerRadius = innerRadius; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")";
})
.style("fill", "White")
.style("font", "normal 12px Arial")
.text(function(d) { return d.data.magnitude; });

// Computes the angle of an arc, converting from radians to degrees.
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}

};

最佳答案

为了达到预期的效果,每 block 的内弧必须偏移几个弧度。

不幸的是,仅使用 D3 是不可能的。问题是我们只能指定 start and end angles整个弧线。我们不能仅指定内弧或外弧的开始和结束 Angular 。

如果我们检查 D3's arc source code responsible for drawing the arc ,我们可以调整这条线:

else context.arc(0, 0, r0, a10, a00, cw);

到:

else {
var offsetDegrees = 10,
offsetRadians = offsetDegrees * Math.PI / 180;
context.arc(0, 0, r0, a10 + offsetRadians, a00 + offsetRadians, cw);
}

并达到预期的效果。

不幸的是,此更改会扰乱圆弧质心的计算以及可能的许多其他功能。

更改源代码从来都不是一个好的做法,这种效果应该在 d3-shape 库中提出或作为 D3 插件实现。

关于javascript - d3.js:饼图布局 - 调整 Angular 以创建快门效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38956648/

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