Цветовой градиент D3 не образует математический круг вокруг центра области

Я пытаюсь сделать график радиальной области с цветовым градиентом, чтобы отразить это. Однако кажется, что градиент никогда не хочет идеально сидеть на одной линии / на правильной стороне с кругом (см. Изображение ниже).

Я пытался ограничить ширину и высоту svg, чтобы они были равны, но безрезультатно. При каждом обновлении (со случайными данными) центральное кольцо для градиента смещается и деформируется в другую форму, но никогда не лежит на средняя линия, где она должна быть.

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

Я убедился, что svg квадратный

 var width = window.innerWidth ,   height = window.innerHeight;

  width = height =   d3.min([width,height])

  var data = d3.range(0,100).map(d=>Math.random())

Учитывая градиент следующие свойства

 var linearGradient = defs.append("radialGradient")
.attr("id", "rad-gradient")
.attr("cx", "50%")    //The x-center of the gradient, same as a typical SVG circle
.attr("cy", "50%")    //The y-center of the gradient
.style("r", "50%");

и моя площадь математически как

var area = d3.area()
 .x1(function(d,i) { return width/2+Math.cos(i\*angle)*(h(d)) })     .x0(function(d,i) { return > width/2+Math.cos(i\*angle)*(h(mean)) })    .y0(function(d,i) {> return height/2+Math.sin(i\*angle)*(h(mean)) })    .y1(function(d,i) { return height/2+Math.sin(i\*angle)*(h(d)) })

И добавил созданный градиент к пути svg

svg.append("path")
    .data([data])
    .attr("class", "area")
    .attr("d", area)
    .style("fill", "url(#rad-gradient)")

person user2589273    schedule 29.06.2017    source источник
comment
Возможно, вам следует закрыть путь к диаграмме. Используйте .interpolate("basis-closed"), например   -  person Alexey G    schedule 29.06.2017
comment
Я использую кардинальную замкнутую интерполяцию, хотя, поскольку этот эффект существует и с ней, и без нее, в псевдокоде ее не было. Я придумал простое решение с использованием путей отсечения, которое, кажется, работает (я полагаю, что оно соответствовало эллипсоиду, поскольку соотношение ширины и высоты чистого пути не было квадратным).   -  person user2589273    schedule 29.06.2017


Ответы (1)


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

Затем вы можете использовать clipPath, чтобы извлечь из круга только тот путь, который вы хотите использовать. Немного повозившись с выравниванием радиуса градиента, мы получаем желаемый эффект.

// previous definition for area path appended as a clip path
clip = defs.append("clipPath")
  .attr('id','clip')
  .append("path")
  .data([data])
  .attr("class", "area")
  .attr("d", area)

//extracting this path from a circle with the desired gradient
svg.append("circle")

  .attr("cx", width/2)
  .attr("cy", height/2)
        .attr("r", rmax)
        .attr("clip-path","url(#clip)")
      .style("fill", "url(#linear-gradient)")

вырезанный путь из круга

person user2589273    schedule 29.06.2017