Как нарисовать форму компаса в d3.js и покрасить каждый треугольник по-разному? - PullRequest
1 голос
/ 22 июня 2019

Я нарисовал эту форму в d3.js, используя генератор линий - идея состоит в том, чтобы сделать ее похожей на компас.

Левое изображение: что у меня есть
Правильное изображение: что я хочу (только средний красный / черный, а не весь компас).

enter image description here enter image description here

То, что я использовал, чтобы сделать это:

function drawArrowCompass() { //draw arrow

    var dataArrow = [
        [35, 50],
        [50, 0],
        [65, 50],
        [50, 100],
        [35, 50]
    ];
    var lineGenerator = d3.line();
    var pathString = lineGenerator(dataArrow);

    var compassArrow = d3.select("#noun_compass");

    //draw arrow(s)
    compassArrow.append("path")
        .attr('d', pathString);

}

С соответствующим HTML:

<div id="compass">
        <svg width="100" height="100" id="noun_compass"></svg>
</div>

Однако, как я это сделал, я не вижу способа добавить два разных цвета к пути. Кто-нибудь знает, как я могу нарисовать такую ​​форму в d3.js? Заранее спасибо !!

Ответы [ 2 ]

3 голосов
/ 22 июня 2019

Способ, которым я бы это сделал, - создать данные пути (атрибут d) для одной стрелки, где начало пути находится у основания стрелки, а затем создать два пути с теми же данными, но с разным преобразованием.Это надежно и позволяет легко вносить изменения в положение, ориентацию и количество стрелок.

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    body {
      margin: 0;
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <input type="range" min="0" max="360" value="0" id="slider" oninput="updateAngle(this.value)">
  <script>
    // Feel free to change or delete any of the code you see in this editor!
    var svg = d3.select("body").append("svg")
      .attr("width", 200)
      .attr("height", 200)
      .attr('viewBox', '-50 -50 100 100')

    var path_d = "M 0,0 L 0,-10 L 50,0 L 0,10 Z";

    function updateAngle(value) {
      var angle = parseInt(value);
      var data = [{
        angle: angle,
        color: 'black'
      }, {
        angle: (180 + angle) % 360,
        color: 'red'
      }];

      paths = svg.selectAll('path')
        .data(data);

      paths.enter()
        .append('path')
        .attr('d', path_d)
        .merge(paths)
        .style('fill', d => d.color)
        .attr('transform', d => `rotate(${d.angle})`);

      paths.exit().remove();
    }

    updateAngle(0);
  </script>
</body>
2 голосов
/ 22 июня 2019

Простое решение заключается в использовании linearGradient со встречей стоп-цветов на 50%, например:

var gradient = svg.append("defs")
  .append("linearGradient")
  .attr("id", "gradient");
gradient.append("stop")
  .attr("offset", "50%")
  .attr("stop-color", "red");
gradient.append("stop")
  .attr("offset", "50%")
  .attr("stop-color", "black");

Учитывая, что вы жестко закодировали точки, образующие путь, вы должны повернуть его, чтобы сохранить направление градиента, например:

var svg = d3.select("svg");
var gradient = svg.append("defs")
  .append("linearGradient")
  .attr("y1", "0%")
  .attr("y2", "100%")
  .attr("x1", "50%")
  .attr("x2", "50%")
  .attr("id", "gradient");
gradient.append("stop")
  .attr("offset", "50%")
  .attr("stop-color", "red");
gradient.append("stop")
  .attr("offset", "50%")
  .attr("stop-color", "black");
drawArrowCompass();

function drawArrowCompass() {
  var dataArrow = [
    [35, 50],
    [50, 0],
    [65, 50],
    [50, 100],
    [35, 50]
  ];
  var lineGenerator = d3.line();
  var pathString = lineGenerator(dataArrow);
  var compassArrow = d3.select("#noun_compass");
  compassArrow.append("path")
    .attr('d', pathString)
    .attr("fill", "url(#gradient)")
    .attr("transform", "rotate(80, 50, 50)");
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="compass">
  <svg width="100" height="100" id="noun_compass"></svg>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...