Skip to content

Instantly share code, notes, and snippets.

@tomshanley
Last active December 3, 2017 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomshanley/938d9d36a878d18ca8a13d0cbc3ece2f to your computer and use it in GitHub Desktop.
Save tomshanley/938d9d36a878d18ca8a13d0cbc3ece2f to your computer and use it in GitHub Desktop.
Area segment fill using gradient
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;top:0;right:0;bottom:0;left:0; }
path { stroke-width: 3px }
</style>
</head>
<body>
<script>
const height = 500
const width = 500
const margin = {"top": 20, "bottom": 20, "left": 20, "right": 20}
const data1 = [2, 5, 6, 7, 3, 8, 3, 4]
const data2 = [6, 2, 2, 2, 2, 2, 4, 9]
let combinedData = []
for (var i = 0; i < data1.length; i++) {
let o = {}
o.data1 = data1[i]
o.data2 = data2[i]
combinedData.push(o)
}
let xScale = d3.scaleLinear()
.domain([0, combinedData.length-1])
.range([0, width])
let yScale = d3.scaleLinear()
.domain([0, 10])
.range([height, 0])
let area = d3.area()
.x(function (d, i) { return xScale(i) })
.y0(function (d) { return yScale(d.data1) })
.y1(function (d) { return yScale(d.data2) })
.curve(d3.curveCatmullRom.alpha(0.5));
let line1 = d3.line()
.x(function (d, i) { return xScale(i) })
.y(function (d) { return yScale(d.data1) })
.curve(d3.curveCatmullRom.alpha(0.5));
let line2 = d3.line()
.x(function (d, i) { return xScale(i) })
.y(function (d) { return yScale(d.data2) })
.curve(d3.curveCatmullRom.alpha(0.5));
let svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
let g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var defs = g.append("defs");
var gradient = defs.append("linearGradient")
.attr("id", "area-gradient")
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "100%")
.attr("y2", "0%");
let offset1 = 0.2
let offset2 = 0.4
const lineWidth = 0.014 / 2
let stopsData = [
{ "offset": 0, "stopColour": "#FFFFFF" },
{ "offset": offset1-lineWidth, "stopColour": "#FFFFFF" },
{ "offset": offset1-lineWidth, "stopColour": "#000" },
{ "offset": offset1+lineWidth, "stopColour": "#000" },
{ "offset": offset1+lineWidth, "stopColour": "#777777" },
{ "offset": offset2-lineWidth, "stopColour": "#777777" },
{ "offset": offset2-lineWidth, "stopColour": "#000" },
{ "offset": offset2+lineWidth, "stopColour": "#000" },
{ "offset": offset2+lineWidth, "stopColour": "#FFFFFF" },
{ "offset": 1, "stopColour": "#FFFFFF" }
]
gradient.selectAll("stop")
.data(stopsData)
.enter()
.append("stop")
.attr("offset", function(d){ return d.offset })
.attr("stop-color", function(d){ return d.stopColour })
let areaFill = g.append("path")
.datum(combinedData)
.style("fill", "url(#area-gradient)")
.style("opacity", 0)
.attr("d", area)
let path1 = g.append("path")
.datum(combinedData)
.style("stroke", "red")
.style("fill", "none")
.attr("d", line1)
let path2 = g.append("path")
.datum(combinedData)
.style("stroke", "blue")
.style("fill", "none")
.attr("d", line2)
let rect = g.append("rect")
.attr("width", width)
.attr("height", height)
.style("opacity", 0)
.on("mouseover", function(){
areaFill.style("opacity", 1)
})
.on("mouseout", function(){
areaFill.transition().style("opacity", 0)
})
.on("mousemove", function(d){
let x = d3.mouse(this)[0]
let middle = x/width
let offset1 = (middle - 0.1) < 0 ? 0 : (middle - 0.1)
let offset2 = (middle + 0.1) > 1 ? 1 : (middle + 0.1)
let o1 = width * offset1
let o2 = width * offset2
let stopsData = [
{ "offset": 0, "stopColour": "#FFFFFF" },
{ "offset": offset1-lineWidth, "stopColour": "#FFFFFF" },
{ "offset": offset1-lineWidth, "stopColour": "#000" },
{ "offset": offset1+lineWidth, "stopColour": "#000" },
{ "offset": offset1+lineWidth, "stopColour": "#777777" },
{ "offset": offset2-lineWidth, "stopColour": "#777777" },
{ "offset": offset2-lineWidth, "stopColour": "#000" },
{ "offset": offset2+lineWidth, "stopColour": "#000" },
{ "offset": offset2+lineWidth, "stopColour": "#FFFFFF" },
{ "offset": 1, "stopColour": "#FFFFFF" }
]
gradient.selectAll("stop")
.data(stopsData)
.attr("offset", function(d){ return d.offset })
.attr("stop-color", function(d){ return d.stopColour })
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment