博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
d3 曲线区域填充
阅读量:5260 次
发布时间:2019-06-14

本文共 4722 字,大约阅读时间需要 15 分钟。

本篇以一个简单的demo示范一下在d3中实现曲线的区域填充。

clip-path

clip-path:创建一个只有元素的部分区域可以显示的剪切区域。显示clip-path内部的区域,而外部的区域不可见。

区域填充也主要以clip-path为基础来实现。

区域填充

1.1 先画一条曲线

            

1487780-20190612235026747-1355400728.png

2.2 添加一条水平的阈值线

// 水平阈值            svg.append('line')                .attr('x1', 0)                .attr('y1', yScale(45))                .attr('x2', width)                .attr('y2', yScale(45))                .attr('stroke', '#FFA354')                .attr('stroke-width', 1.5)                .attr('stroke-dasharray', '6,4');

1487780-20190612235230508-1554525238.png

3.3 填充阈值线上面部分

// 添加一个clipPath svg.append("clipPath")                .attr("id", "clip-th")                .append("rect")                .attr("x", 0)                .attr("y", padding.top)                .attr("width", width)                .attr("height", yScale(45) - yScale(ymax));// 再次添加一条曲线并填充区域                        svg.append("path")                .datum(data)                .attr("fill", "steelblue")                .attr("fill-opacity", 0.5)                .attr("stroke", "none")                .attr("d", curveLine)                .attr('clip-path', "url(#clip-th)");

1487780-20190612235651152-684619750.png

1487780-20190612235707448-1389804085.png

  • path填充的时候会把首尾点连起来,并不是我们想要的效果。所以我们再首尾都添加一个点,来控制填充区域。

4.4 修改数据,重新绘制填充区域

data.unshift({                date: new Date(2019, 3, 24),                value: 0            });            data.push({                date: new Date(2019, 4, 1),                value: 0            });                        svg.append("path")                .datum(data)                .attr("fill", "steelblue")                .attr("fill-opacity", 0.5)                .attr("stroke", "none")                .attr("d", curveLine)                .attr('clip-path', "url(#clip-th)");

1487780-20190613000215480-1713936130.png

  • 目的是达到了但是效果并不是很理想。由于额外的添加了两个点生成的曲线和原曲线产生了偏差。个人觉得比较理想的做法是
    再添加一条红线所示的正常直线path。然后将两个直线和曲线组合起来进行填充。

1487780-20190613000720871-1334358938.png

5.5 再次修改数据,重新绘制

// 红线所示直线数据var data2 = [{                date: new Date(2019, 3, 24),                value: 23.24            }, {                date: new Date(2019, 3, 24),                value: 0            }, {                date: new Date(2019, 4, 1),                value: 0            }, {                date: new Date(2019, 4, 1),                value: 85.47            }];// 添加直线生成器var line = d3.line()                .x(function(d) {                    return xScale(d.date);                })                .y(function(d) {                    return yScale(d.value);                });// 绘制两个pathcontainer.append("path")                .datum(data)                .attr("fill", "none")                .attr("d", curveLine);                            container.append("path")                .datum(data2)                .attr("fill", "none")                .attr("d", line);// 将两个path合并var combined = "";            container.selectAll("path")                .each(function() {                    combined += d3.select(this).attr("d");                });                            container.selectAll("path").remove();                                    // 绘制合并后的path            container.append("path")                .attr("stroke", "none")                .attr("d", combined)                .attr("fill", "steelblue")                .attr("fill-opacity", 0.5)                .attr("fill-rule", "evenodd")                .attr('clip-path', "url(#clip-th)");

1487780-20190613001120413-258823735.png

  • 我们就能看到完全的区域填充了。切记要使用fill-rule来约定填充的区域。

6.6 添加两条垂直的阈值

// 垂直阈值线            svg.append('line')                .attr('x1', xScale(new Date(2019, 3, 26)))                .attr('y1', yScale(ymax))                .attr('x2', xScale(new Date(2019, 3, 26)))                .attr('y2', yScale(0))                .attr('stroke', '#FFA354')                .attr('stroke-width', 1.5)                .attr('stroke-dasharray', '6,4')            svg.append('line')                .attr('x1', xScale(new Date(2019, 3, 28)))                .attr('y1', yScale(ymax))                .attr('x2', xScale(new Date(2019, 3, 28)))                .attr('y2', yScale(0))                .attr('stroke', '#FFA354')                .attr('stroke-width', 1.5)                .attr('stroke-dasharray', '6,4')// clip-pathsvg.append("clipPath")                .attr("id", "clip-th2")                .append("rect")                .attr("x", xScale(new Date(2019, 3, 26)))                .attr("y", yScale(45))                .attr("width", xScale(new Date(2019, 3, 28)) - xScale(new Date(2019, 3, 26)))                .attr("height", yScale(0) - yScale(45));container.append("path")                .attr("stroke", "none")                .attr("d", combined)                .attr("fill", "yellowgreen")                .attr("fill-opacity", 0.5)                .attr("fill-rule", "evenodd")                .attr('clip-path', "url(#clip-th2)");

1487780-20190613001342414-1856794644.png

  • 这下就大功告成了!

转载于:https://www.cnblogs.com/chenjy1225/p/11013643.html

你可能感兴趣的文章
Not enough free disk space on disk '/boot'(转载)
查看>>
android 签名
查看>>
vue项目中使用百度统计
查看>>
android:scaleType属性
查看>>
SuperEPC
查看>>
mysql-5.7 innodb 的并行任务调度详解
查看>>
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
Js时间处理
查看>>
Java项目xml相关配置
查看>>
三维变换概述
查看>>
vue route 跳转
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。...
查看>>
Linux中防火墙centos
查看>>
mysql新建用户,用户授权,删除用户,修改密码
查看>>
FancyCoverFlow
查看>>
JS博客
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
ASP.NET WebApi 基于OAuth2.0实现Token签名认证
查看>>