如何在d3.js中绘制指南针形状并为每个三角形着色不同?

时间:2019-06-22 14:43:33

标签: javascript html d3.js svg

我已经使用线生成器在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 个答案:

答案 0 :(得分:3)

我要这样做的方法是,为单个箭头创建路径数据(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>

答案 1 :(得分:2)

一个简单的解决方案是在50%处使用linearGradient和终止色会议,像这样:

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>