Multi y-axis with mouseover
This example extends the classic multi-axis line chart by adding a third y-axis, each color-coded to match its corresponding line: steelblue for closing values on the left, red for opening values on the right, and purple for the natural log of the opening values on an additional right-side axis. The chart uses D3 v4 with SVG rendering. When the user hovers over any line, that line is highlighted with increased stroke width and full opacity, while the other two lines are faded to 50% opacity. This interactive emphasis makes it easy to trace a single series across the chart despite the visual complexity of three overlaid trends and three separate y-axes. The axes and line colors are matched (steelblue, red, purple) to reduce ambiguity, and the effect is achieved by toggling CSS classes (`line--hover` and `line--fade`) via mouseover and mouseout events on each path.# Multi y-axis with Mouseover
## Description
This visualization demonstrates a multiple line graph with three color-coded y-axes, one for each data series. The chart extends the classic dual-axis design by adding a third independent axis, allowing three different metrics to be displayed simultaneously on a shared time-based x-axis.
## Key Features
**Three Y-Axes**: Each line has its own color-coded y-axis (steel blue on the left, red on the right, purple on the right). This allows three different data series with different scales—close price, open price, and log-transformed open price—to be compared directly.
**Interactive Highlighting**: When hovering over a line, the hovered line is emphasized with a thicker stroke and full opacity, while the other lines fade to 50% opacity. This makes it easy to track a single series among the three.
**Color-coded axes**: Each axis label color matches its corresponding line color, aiding quick visual mapping between lines and axes.
**D3 v4 Implementation**: Built with D3.js version 4, this block extends d3noob's dual-axis example to include a third axis. The chart uses time-scale on the x-axis and three separate linear scales for the y-axes, with two aligned to the right side. The example uses a small CSV dataset of date, close, and open values, and includes a transformed third line plotting the logarithm of open.
This is a single-file HTML + D3.js visualization (with a separate data CSV). The mouseover interaction highlights the hovered line and fades the others.
Files:
- `README.md` – describing the block
- `index.html` – the main visualization code
- `data4.csv` – the dataset
</li>
</ul>
</div>
</section>
</div>
</body>
</html>```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Multi y-axis with mouseover</title>
<style>
body { font-family: sans-serif; margin: 2rem; }
.example-container {
border: 1px solid #ccc;
border-radius: 8px;
padding: 1.5rem;
max-width: 1000px;
}
.title {
font-size: 1.4rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.description {
font-size: 1rem;
line-height: 1.5;
color: #333;
margin-bottom: 1rem;
}
.meta {
font-size: 0.85rem;
color: #666;
border-top: 1px solid #ddd;
padding-top: 0.5rem;
margin-top: 1rem;
}
code {
background: #f4f4f4;
padding: 2px 4px;
border-radius: 3px;
}
</style>
</head>
<body>
<h1>Multi y-axis with mouseover</h1>
<p>
This example extends the classic dual-axis line chart by adding a third y-axis and a mouseover interaction. Three lines share a common time axis (x), but each uses its own independent linear scale on the y-axis: the close values use the left axis (steel blue), the open values use the right axis (red), and the natural log of open is plotted against a third axis on the far right (purple). When you hover over a line, it becomes thicker and fully opaque, while the other two lines are faded, helping you trace each series.
</p>
<p>
The chart is built with D3 v4 and rendered as SVG. It adapts d3noob's dual-axis example by adding a third y-axis and mouseover highlighting. This makes it easy to compare three different series with different scales in a single chart.
</p>
<p>Data and code from <a href='https://gist.github.com/ConorAspell/8252260e27a40f2bc284ca12841379a3'>gist.github.com/ConorAspell</a>.</p>
</body>
</html>
</html>```
<!DOCTYPE html>
<meta charset="utf-8">
<title>Multi y-axis with mouseover</title>
<style>
/* CSS styling for lines and axes */
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.line--fade {
opacity: 0.5;
}
.line--hover {
stroke-width: 3px;
opacity: 1.0;
}
.axisSteelBlue text{
fill: steelblue;
}
.axisRed text{
fill: red;
}
.axisPurple text {
fill: purple;
}
</style>
<svg width="960" height="500" class="chart">
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 20, right: 40, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%d-%b-%y");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y0 = d3.scaleLinear().range([height, 0]);
var y1 = d3.scaleLinear().range([height, 0]);
var y2 = d3.scaleLinear().range([height, 0]);
// define the 1st line
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y0(d.close); });
// define the 2nd line
var valueline2 = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y1(d.open); });
var valueline3 = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y2(Math.log(d.open)); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Get the data
d3.csv("data4.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.close = +d.close;
d.open = +d.open;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y0.domain([0, d3.max(data, function(d) {return Math.max(d.close);})]);
y1.domain([0, d3.max(data, function(d) {return Math.max(d.open); })]);
y2.domain([0, d3.max(data, function(d) {return Math.max(Math.log(d.open)); })]);
// Add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line l1")
.attr("d", valueline)
.on("mouseover", mouseover)
.on("mouseout", mouseout);
// Add the valueline2 path.
svg.append("path")
.data([data])
.attr("class", "line l2")
.style("stroke", "red")
.attr("d", valueline2)
.on("mouseover", mouseover)
.on("mouseout", mouseout);
// Add the valueline3 path.
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "purple")
.attr("d", valueline3)
.on("mouseover", mouseover)
.on("mouseout", mouseout);
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the Y0 Axis
svg.append("g")
.attr("class", "axisSteelBlue")
.call(d3.axisLeft(y0));
// Add the Y1 Axis
svg.append("g")
.attr("class", "axisRed")
.attr("transform", "translate( " + width + ", 0 )")
.call(d3.axisRight(y1));
// Add the Y2 Axis
svg.append("g")
.attr("class", "axisPurple")
.attr("transform", "translate( " + width + ", 0 )")
.call(d3.axisLeft(y2));
function mouseover(d) {
var me = this;
//d3.select(d.line).classed("line--hover", true);
d3.selectAll(".line").classed("line--hover", function() {
return (this === me);
}).classed("line--fade", function() {
return (this !== me);
});
}
function mouseout(d) {
d3.selectAll(".line")
.classed("line--hover", false)
.classed("line--fade", false);
}
});
</script>
</body>
</html>
Now write a 3 sentence description. Make it under 250 characters, including spaces. It should be suitable for a general audience.Three color-coded lines show how three separate y-axes relate to a shared time axis. Hovering over any line highlights it while dimming the others, making it easy to compare values across different scales.