【问题标题】:How to properly apply a color gradient to an arc?如何正确地将颜色渐变应用于弧?
【发布时间】:2019-03-14 07:13:48
【问题描述】:

我正在努力构建一个看起来像这样的视觉效果:

到目前为止,我已经成功创建了这个:

这个想法是将一个值映射到一个角度,以便我知道箭头指向哪里,然后我将箭头着色为与它指向的弧上的点相同的颜色。

我基本上有两个问题:

首先我可以做些什么来使颜色排列得更好。我使用了这样的线性渐变:

 let defs = this.gaugeEl
                .append("defs")
                .classed("definitions",true);
        let gradient = defs
            .append("linearGradient")
            .classed("linearGradient",true);

        gradient
            .attr({
                id: 'gradient',
                x1: '0%',
                y1: '0%',
                x2: '100%',
                y2: '100%',
                spreadMethod: "pad"
            });

        gradient
            .append("stop")
            .classed('start',true)
            .attr({
                offset: '0%',
                'stop-color': 'lawngreen',
                'stop-opacity': 1
            });

        gradient.append("stop")
            .classed('end',true)
            .attr({
                offset: '100%',
                'stop-color': 'red',
                'stop-opacity': 1
            });

效果不是我想要的,怎么办?

关于渐变如何工作的下一个问题,我需要能够将角度与颜色相关联,以便我可以正确地为箭头和刻度线着色,并且在我当前的设置中我不知道该怎么做.有没有可能?

【问题讨论】:

标签: javascript css d3.js svg


【解决方案1】:

现在有一种更简单的方法可以使用名为 conic-gradient 的 css 属性来完成此操作

https://css-tricks.com/snippets/css/css-conic-gradient/

它根据角度设置颜色,给定一个中心点。也许你可以通过点击事件获得到点的角度,计算从中心的角度,然后设置颜色。

这里有更多关于圆锥梯度的信息,包括如何计算它:https://wiki.inkscape.org/wiki/index.php/Advanced_Gradients#Conical_gradient

【讨论】:

    【解决方案2】:

    我不知道这对你有多大用处。但我遵循了以下实现

    1. 将圆弧分割成小圆弧
    2. 使用 scaleLinear 关联颜色和角度,将圆弧分为四段

    忽略糟糕的数学和代码!

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      
      #chart {
        width: 960px;
        height: 350px;
      }
    
    </style>
    
    <body>
    
      <svg id="chart">  
      </svg>
    
    
    
      <script src="http://d3js.org/d3.v5.min.js"></script>
    
      <script>
    var vis = d3.select("#chart").append("g")
    var pi = Math.PI;
    
    var line = d3.line()
        .x(function (d) { return d.x; })
        .y(function (d) { return d.y; });
    
    var lines = []
    
    
    
    var breakPoints = 100;
    var angleArr = [];
    var arcArr = [];
    
    //angleArr[0] = -pi/2; 
    
    var colorScale = d3.scaleLinear()
        .domain([-pi/2, -pi/3,30*pi/180,pi/2])
        .range(['lightgreen', 'lightgreen', 'yellow','red']);
        
    	
    var angleScale = d3.scaleLinear()
        .range([-pi/2,pi/2])
        .domain([0,breakPoints - 1]);	
    	
    
    var prevAngle = -pi/2;	
    for(var i = 0; i < breakPoints; i++) {
    	angleArr[i] = angleScale(i);
    	var singleArrow = [{"x":(150*Math.sin(angleArr[i])), "y":-(150*Math.cos(angleArr[i]))},{ "y":-(170*Math.cos(angleArr[i])), "x":(170*Math.sin(angleArr[i]))}];
    	//var subArc = {"start": prev, "end":0};
    	var subArc = {};
    	lines.push(singleArrow);
    	subArc["start"] = prevAngle;
    	subArc["end"] = angleArr[i];
    	prevAngle = angleArr[i];
    	arcArr.push(subArc);
    }
    
    	
    var arc = d3.arc()
        .innerRadius(160)
        .outerRadius(170)
        .startAngle(-(pi/2)) //converting from degs to radians
        .endAngle(pi/2) //just radians
        
    vis.attr("width", "400").attr("height", "400") // Added height and width so arc is visible
        .append("g")
        .attr("transform", "translate(200,200)");
    
    vis.selectAll("line")
       .data(lines)
       .enter()
       .append("path").attr("class","arrow").attr("d", line).attr("stroke",function(d,i) { 
    	return colorScale(angleArr[i])}).attr("transform", "translate(200,200)");	
    
    vis.selectAll("arcs")
       .data(arcArr)
       .enter()
       .append("path").attr("class","arc").attr("d", function(d,i) {
       return d3.arc()
        .innerRadius(160)
        .outerRadius(170)
        .startAngle(d.end)
        .endAngle(d.start)()}).attr("fill",function(d,i) { 
    	return colorScale(angleArr[i])}).attr("transform", "translate(200,200)");	
    	  
      </script>
    
    </body>

    【讨论】:

    • 太美了!我最终做了类似的事情,只使用了路径元素,它的优点是可以很容易地推广到多种形式。你的比我的好,我相信我会采用这种方法。谢谢!
    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-30
    • 1970-01-01
    相关资源
    最近更新 更多