Tooltips Not Showing On Mouse Move And Mouse Over
I am using the below code to create a multi line chart with tool tips and have customized it a little bit to make the x axis ordinal and I have also har coded the data. Everything
Solution 1:
You was trying to access function invert() of x, however since it is not linear() but ordinal() now, it is not possible to invert it, and function invert() is missing for x = d3.scale.ordinal(), thus trying to call this function was causing an error and blocking the execution of the next lines of code, so just comment out:
var xDate = x.invert(mouse[0]),
bisect = d3.bisector(function(d) { return d.week; }).right;
idx = bisect(d.values, xDate);
in d3.selectAll(".mouse-per-line") and here you go, tooltip is working again:
<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<script>
var margin = {
top: 20,
right: 80,
bottom: 30,
left: 50
},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// var parseDate = d3.time.format("%Y%m%d").parse;
// var x = d3.scale.linear()
// .range([0, width]);
var x = d3.scale.ordinal()
.domain(["20170101","20170108","20170115","20170122","20170128"])
.rangePoints([0, width],0.5);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
// .ticks(5)
.orient("bottom")
// .tickValues(["2017-01-01", "2017-01-08", "2017-01-15", "2017-01-22", "2017-01-28"]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("linear")
.x(function(d) {
return x(d.week);
})
.y(function(d) {
return y(d.avg_test_drives);
});
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 + ")");
// var data = d3.tsv.parse(myData);
// console.log(data[0]);
// alert (JSON.stringify(data));
var data = [{"week": "20170101", "dealer": "68", "peers": "73","all dealers":"123"},
{"week": "20170108", "dealer": "121","peers":"112","all dealers":"131"},
{"week": "20170115", "dealer": "104","peers":"101","all dealers":"106"},
{"week": "20170122", "dealer": "123","peers":"131","all dealers":"122"},
{"week": "20170128", "dealer": "106","peers":"107","all dealers":"122"}]
// alert (JSON.stringify(data));
color.domain(d3.keys(data[0]).filter(function(key) {
return key !== "week";
}));
data.forEach(function(d) {
d.week = d.week;
});
var testdrives = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
week: d.week,
avg_test_drives: +d[name]
};
})
};
});
// x.domain(d3.extent(data, function(d) {
// return d.week;
// }));
y.domain([
d3.min(testdrives, function(c) {
return d3.min(c.values, function(v) {
return v.avg_test_drives;
});
}),
d3.max(testdrives, function(c) {
return d3.max(c.values, function(v) {
return v.avg_test_drives;
});
})
]);
var legend = svg.selectAll('g')
.data(testdrives)
.enter()
.append('g')
.attr('class', 'legend');
legend.append('rect')
.attr('x', width - 20)
.attr('y', function(d, i) {
return i * 20;
})
.attr('width', 10)
.attr('height', 10)
.style('fill', function(d) {
return color(d.name);
});
legend.append('text')
.attr('x', width - 8)
.attr('y', function(d, i) {
return (i * 20) + 9;
})
.text(function(d) {
return d.name;
});
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
// .ticks(5);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Test Drives");
var entity = svg.selectAll(".entity")
.data(testdrives)
.enter().append("g")
.attr("class", "entity");
// alert (JSON.stringify(entity));
entity.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return color(d.name);
});
entity.append("text")
.datum(function(d) {
return {
name: d.week,
value: d.values[d.values.length - 1]
};
})
.attr("transform", function(d) {
return "translate(" + x(d.value.week) + "," + y(d.value.avg_test_drives) + ")";
})
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) {
return d.week;
});
var mouseG = svg.append("g")
.attr("class", "mouse-over-effects");
mouseG.append("path") // this is the black vertical line to follow mouse
.attr("class", "mouse-line")
.style("stroke", "black")
.style("stroke-width", "1px")
.style("opacity", "0");
var lines = document.getElementsByClassName('line');
var mousePerLine = mouseG.selectAll('.mouse-per-line')
.data(testdrives)
.enter()
.append("g")
.attr("class", "mouse-per-line");
mousePerLine.append("circle")
.attr("r", 7)
.style("stroke", function(d) {
return color(d.week);
})
.style("fill", "none")
.style("stroke-width", "1px")
.style("opacity", "0");
mousePerLine.append("text")
.attr("transform", "translate(10,3)");
mouseG.append('svg:rect') // append a rect to catch mouse movements on canvas
.attr('width', width) // can't catch mouse events on a g element
.attr('height', height)
.attr('fill', 'none')
.attr('pointer-events', 'all')
.on('mouseout', function() { // on mouse out hide line, circles and text
d3.select(".mouse-line")
.style("opacity", "0");
d3.selectAll(".mouse-per-line circle")
.style("opacity", "0");
d3.selectAll(".mouse-per-line text")
.style("opacity", "0");
})
.on('mouseover', function() { // on mouse in show line, circles and text
d3.select(".mouse-line")
.style("opacity", "1");
d3.selectAll(".mouse-per-line circle")
.style("opacity", "1");
d3.selectAll(".mouse-per-line text")
.style("opacity", "1");
})
.on('mousemove', function() { // mouse moving over canvas
var mouse = d3.mouse(this);
d3.select(".mouse-line")
.attr("d", function() {
var d = "M" + mouse[0] + "," + height;
d += " " + mouse[0] + "," + 0;
return d;
});
d3.selectAll(".mouse-per-line")
.attr("transform", function(d, i) {
console.log(width/mouse[0])
/* var xDate = x.invert(mouse[0]),
bisect = d3.bisector(function(d) { return d.week; }).right;
idx = bisect(d.values, xDate);
*/
var beginning = 0,
end = lines[i].getTotalLength(),
target = null;
while (true){
target = Math.floor((beginning + end) / 2);
pos = lines[i].getPointAtLength(target);
if ((target === end || target === beginning) && pos.x !== mouse[0]) {
break;
}
if (pos.x > mouse[0]) end = target;
else if (pos.x < mouse[0]) beginning = target;
else break; //position found
}
d3.select(this).select('text')
.text(y.invert(pos.y).toFixed(2));
return "translate(" + mouse[0] + "," + pos.y +")";
});
});
</script>
</body>
Post a Comment for "Tooltips Not Showing On Mouse Move And Mouse Over"