Как рисовать градиентную дугу с помощью d3.js?

Я начал использовать d3.js. У меня есть следующее требование

Требования:

введите описание изображения здесь

Что я пробовал?

fiddle

Вопрос?

Как достичь градиента так же, как и изображение выше.

Любое предложение или идея будут благодарны.

Примечание

Я только что начал d3.js.

Ответы

Ответ 1

Изменить - изменили структуру данных и ссылку на скрипку, чтобы представить незаполненный фрагмент в начале.

Я бы использовал функцию pie в d3 для создания круговой диаграммы. Изображение выше в основном представляет собой пирог с двумя разными стилями градиента, применяемыми к кускам пирога. Красный линейный градиент и черно-белый радиальный градиент.

Я создал скрипку, приведенную ниже, чтобы показать вам пример. Ключевым моментом здесь является то, что вам необходимо структурировать данные, чтобы также включить процент, который не должен иметь примененный красный градиент. Используя приведенный выше пример, у нас есть три куска с красным, а остальные - незаполненные. Представьте, что данные установлены так:

    var data = [{
    percent: 10,
    pie: 0
}, {
    percent: 13,
    pie: 1
}, {
    percent: 13,
    pie: 1
}, {
    percent: 6,
    pie: 1
}, {
    percent: 56,
    pie: 0
}];

Итак, у нас есть процент, и мы также отмечаем, какие куски должны быть красными, а какой кусок должен быть незаполненным сектором, используя атрибут pie.

Вы можете использовать любой набор данных, который вы хотите, но я просто использую это в качестве примера.

Итак, следующая вещь - создать свой SVG-элемент:

 var width = 400;
    var height = 400;
    var radius = Math.min(width, height) / 2;

    var arc = d3.svg.arc()
     .outerRadius(radius - 10)
     .innerRadius(((radius - 10) / 5) * 4);


    var pie = d3.layout.pie()
    .sort(null)
    .value(function (d) { return d.percent });

    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

и после этого мы создадим два градиента для стилизации кусочков пирога. Итак, во-первых, это линейный красный градиент:

// append a defs tag to SVG, This holds all our gradients and can be used
//by any element within the SVG we append it to
var defs = svg.append("svg:defs")

//next we append a linear gradient 
var red_gradient = defs.append("svg:linearGradient")
  .attr("id", "gradient")
  .attr("x1", "0%")
  .attr("y1", "0%")
  .attr("x2", "0%")
  .attr("y2", "100%")
  .attr("spreadMethod", "pad");

//first dark red color
    red_gradient.append("svg:stop")
        .attr("offset", "0%")
        .attr("stop-color", "rgb(221,48,2)")
        .attr("stop-opacity", 1);
//second light red color
    red_gradient.append("svg:stop")
        .attr("offset", "100%")
        .attr("stop-color", "rgb(247, 78, 1)")
        .attr("stop-opacity", 1);

Затем добавим радиальный градиент для незаполненной части. Это немного сложнее, потому что нам нужно переместить градиент с преобразованием, чтобы получить правый радиальный центр. Если вы переводите его на половину ширины и высоты, я думаю, что это должно сработать.

var radial_gradient = defs.append("radialGradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("cx", '50%')
.attr("cy", '50%')
.attr("r", "75%")
.attr("fx", '50%')
.attr("fy", '50%')
.attr('gradientTransform', "translate(-200,-200)")
.attr("id", 'gradient2');
 radial_gradient.append("stop").attr("offset", "0%").style("stop-color", "black");
 radial_gradient.append("stop").attr("offset", "55%").style("stop-color", "white");
 radial_gradient.append("stop").attr("offset", "95%").style("stop-color", "black");

Как только мы установили градиенты, мы можем добавить pie:

   var g = svg.selectAll(".arc")
     .data(pie(data))
     .enter().append("g")
     .attr("class", "arc");

    // we create a function to append the different chucks of the pie. 
    // we check the pie attribute from the data and apply the correct gradient.

    g.append("path")
    .attr("d", arc)
    .style("fill", function (d) {
        if (d.data.pie === 1) {
            console.log('true' + d.data.pie);
            return "url(#gradient)"
        }
        else {
            console.log('false' + d.data.pie);
            return "url(#gradient2)"
        }
    })

JSFiddle: http://jsfiddle.net/staceyburnsy/afo292ty/2/