2016-08-15 4 views
3

d3.js가 포함 된 대화 형 원형 차트를 다시 작성해야합니다. - 원형 차트의 세그먼트에 대한 각도가 중간에 시작되지 않습니다. 원형 차트 (아래 이미지 참조)가 약간 벗어났습니다. 내가 원하는 셔터 효과를 그릴 수있는 가장 좋은 방법은 무엇입니까? 아래 코드를 통해 내가 어디 있는지 알 수 있습니다.d3.js : 원형 차트 레이아웃 - 셔터 효과를 만들기위한 각도 조절

JS 바이올린 :는 원하는 효과를 달성하기 위해 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; 
    } 

    }; 

답변

0

을 : http://jsfiddle.net/vh6nwtpb/3/

효과가 나는 얻기 위해 노력하고있어 각 조각의 내부 호가 꺼져 있어야합니다. 몇 라디안 단위로 설정됩니다.

불행히도 D3에서만 가능합니다. 문제는 전체 호의 start and end angles 만 지정할 수 있다는 것입니다. 내부 원호 또는 외부 원호의 시작 및 끝 각도를 지정할 수 없습니다.

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

행 : 우리 D3's arc source code responsible for drawing the arc을 선택하면

, 우리는 행 조정할 수

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

을 원하는 효과를 달성한다.

불행하게도,이 변경은 호 중심 (arc centroid)과 아마도 다른 기능의 계산을 망칠 것입니다.

소스 코드를 변경하는 것은 결코 좋은 습관이 아니며,이 효과는 d3-shape 라이브러리에서 제안되거나 D3 플러그인으로 구현되어야합니다.