Skip to content

Instantly share code, notes, and snippets.

@gustavderdrache
Created July 27, 2013 16:31
Show Gist options
  • Save gustavderdrache/6095367 to your computer and use it in GitHub Desktop.
Save gustavderdrache/6095367 to your computer and use it in GitHub Desktop.

Highlighting Line Segments

This graph is structured as follows:

  • There is a single SVG <path> element at the root containing the basic line graph.
  • Above that, the highlighted lines are SVG <line> elements representing important segments.
  • Above that are the symbols (SVG <path> elements generated by d3.js' d3.svg.symbol generator) for the data points.

I have a number of objections to this approach:

  1. Which data point is emphasized? The first, or the second?

  2. Even with a transition, it is difficult to come up with a good color that draws over even black.

    Against the green or blue we're using for data series, it would be even harder to see.

  3. The SVG <line> elements don't convey additional information in a non-visual sense.

    We would have to make significant effort to emphasize what these <line> nodes represent

<!DOCTYPE html>
<html>
<head>
<title>Highlighting Line Segments</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<script>
var data = [1, 2, 4, 6, 3, 6, 7, 9, 5, 1];
var highlights = [[1, 2], [5, 6]];
var svg = d3.select('body')
.append('svg')
.attr({width: 960, height: 400});
var g = svg.append('g')
.attr('transform', "translate(10, 10)");
var width = 940;
var height = 380;
var x = d3.scale.linear()
.domain([0, data.length - 1])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 10])
.range([height, 0]);
var line = d3.svg.line()
.x(function (d, i) { return x(i); })
.y(function (d) { return y(d); });
var sym = d3.svg.symbol().size(128);
g.selectAll('path')
.data([data])
.enter()
.append('svg:path')
.attr({
d: line,
fill: 'none',
stroke: '#000',
'stroke-width': '4px'
});
g.selectAll('line')
.data(highlights)
.enter()
.append('svg:line')
.attr({
x1: function (d) { return x(d[0]); },
y1: function (d) { return y(data[d[0]]); },
x2: function (d) { return x(d[1]); },
y2: function (d) { return y(data[d[1]]); },
fill: 'none',
stroke: '#f00',
opacity: 0,
'stroke-width': '4px'
})
.transition()
.delay(500)
.duration(500)
.attr({
opacity: 1
});
g.selectAll('path.symbol')
.data(data)
.enter()
.append('svg:path')
.attr({
d: sym,
fill: '#fff',
stroke: '#000',
'stroke-width': '4px',
transform: function (d, i) {
return "translate(" + x(i) + ", " + y(d) + ")";
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment