score:3
Accepted answer
first question, set a unique id to each "mouse-per-line" so you can toggle it's opacity:
var mouseperline = mouseg.selectall('.mouse-per-line')
.data(datanest1)
.enter()
.append("g")
.attr("class", "mouse-per-line")
.attr("id", function(d){
return "mouse-per-line-" + d.key;
});
in your legend click handler:
d3.select("#mouse-per-line-" + d.key)
.style("opacity", newopacity);
second question, instead of transform
to move the rect, set the x
and width
attributes. you can make it dynamic by:
mouseg.append('svg:rect') // append a rect to catch mouse movements on canvas
.attr('x', x(datanest1[0].values[0].x))
.attr('width', x(datanest1[0].values[datanest1[0].values.length - 1].x) - x(datanest1[0].values[0].x))
...
updated code:
var data1 = [
{x: "name1", y: 2.5, label: "a"},
{x: "name2", y: 3.5, label: "a"},
{x: "name3", y: 4.7, label: "a"},
{x: "name1", y: 4.7, label: "b"},
{x: "name2", y: 3.5, label: "b"},
{x: "name3", y: 4.9, label: "b"},
];
var margin = {top: 20, right: 150, bottom: 60, left: 80},
width = 1160 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal().
rangebands([0, width], 0.4, 0.8);
var y = d3.scale.linear()
.range([height, 0]);
var xaxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yaxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
var svg = d3.select("#linechart").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 + ")");
x.domain(data1.map(function(d) { return d.x; }));
y.domain([0, d3.max(data1, function(d) { return d.y; })]);
svg.append("g").
attr("class", "x axis").
attr("transform", "translate(-70," + height + ")").
call(xaxis);
svg.append("g").
attr("class", "y axis").
call(yaxis);
var datanest1 = d3.nest()
.key(function(d) {return d.label;})
.entries(data1);
//console.log(datanest1)
var color = d3.
scale.
ordinal().
range(['red', 'blue']).
domain(d3.keys(data1[0]).
filter(function(key) {return key === 'label';}));
var legendspace = width/datanest1.length;
datanest1.foreach(function(d,i) {
svg.append("path")
.attr("class", "line1")
.style("stroke", function() {
return d.color = color(d.key); })
.attr("id", 'tag'+d.key.replace(/\s+/g, '')) // assign id **
.attr("d", line(d.values));
svg.append("text")
.attr("x", width - margin.left + 50)
.attr("y", legendspace/4 + i*(legendspace/6))
.attr("class", "linelegend1")
.attr("id", 'taglegend'+d.key.replace(/\s+/g, '')) // assign id **
.style("fill", function() {
return d.color = color(d.key); })
.on("click", function(){
console.log(d);
// determine if current line is visible
var active = d.active ? false : true,
newopacity = active ? 0 : 1;
// hide or show the elements based on the id
d3.select("#tag"+d.key.replace(/\s+/g, ''))
//.remove();
.transition().duration(500)
.style("opacity", newopacity);
//d3.selectall(".mouse-per-line circle")
// .style("opacity", newopacity);
//d3.selectall(".mouse-per-line text")
// .style("opacity", newopacity);
// update whether or not the elements are active
d.active = active;
d3.select("#mouse-per-line-" + d.key)
.style("opacity", newopacity);
})
.text(d.key);
});
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('line1');
var mouseperline = mouseg.selectall('.mouse-per-line')
.data(datanest1)
.enter()
.append("g")
.attr("class", "mouse-per-line")
.attr("id", function(d){
return "mouse-per-line-" + d.key;
});
mouseperline.append("circle")
.attr("r", 7)
.style("stroke", function(d) {
return color(d.key);
})
.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('x', x(datanest1[0].values[0].x))
.attr('width', x(datanest1[0].values[datanest1[0].values.length - 1].x) - x(datanest1[0].values[0].x))
.attr('height', height)
.attr('fill', 'grey')
.style('opacity', '0.4')
.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 xquater = y.invert(d3.mouse(this)[0]),
bisect = d3.bisector(function(d) { return d.x; }).right;
idx = bisect(d.values, xquater);
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 +")";
});
});
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<meta charset='utf-8'>
<title>charts</title>
</head>
<body>
<div align="center" id="linechart">
</div>
<style>
.axis {
font-family: helvetica;
font-size: 1em;
font-weight: bold;
color: #444444;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispedges;
}
.line2{
fill: none;
stroke: red;
stroke-width: 1.5px;
}
.line1{
fill: none;
stroke: blue;
stroke-width: 1.5px;
}
</style>
</body>
</html>
Source: stackoverflow.com
Related Query
- How to remove tooltips on line when click button d3.js
- How to show D3 chart using Bootstrap modal popup when click on button and download it as image format
- d3.js tree: How do I remove a node's siblings when I click on it?
- D3.JS how to load 3 csv files and change data on line chart with button click event?
- D3.js How to hide/show line when click select options?
- How to show a tooltip with value when mouseover a svg line graph using d3.js?
- d3.js: How to remove nodes when link-data updates in a force layout
- How to avoid overlapping tooltips of multi-series line chart d3.js
- How to trigger click of both elements, when clicking overlapping area
- How can I remove a line from the 110m TopoJson world map?
- How to let line or path follow the shape when shape are move
- d3: tooltips on multi series line chart at each line when mouse hover event
- Using D3.js, How can I detect when a point on an animating line is reached?
- How to remove axis line overflow in c3js line graph
- How to remove white line in d3.js legnd
- How can I display tooltips from multiple maps when mousover on one of the maps in D3js
- How can I handle data filtering on a button click on D3.js?
- How can I remove spurious line on zoomable sunburst?
- How to customize nvd3's tooltips and remove labels from x axis
- How to remove fade when hovering in networkD3 graph in R
- D3 events - How to allow button click in d3 element?
- Unable to supdate chart when switching dataset on button click
- How to remove event listener of an element when I remove the corresponding element in the midst of the event being triggered in D3?
- D3 Transition. Working with multiple lines on line graph and would like to transition smoothly between lines when button is pressed
- Button with text label: How do I keep the hover color even when over text label?
- Fill same line color in to circle on Multi Line chart when mouse over and remove color from circle when mouse out
- How to continue line when data is null or zero?
- Using d3 - How do I select specific data from array to highlight when I click a button?
- How to fix d3.js axis mis match when using clip paths for linear filtered line charts
- How to remove empty rows in tables when they are zero, and how to allow selection in only one table at a time?
More Query from same tag
- Getting data from a d3 CSV parse request back to the code body
- SVG CSS classes overriding each other in d3
- D3.js changing Integer axis to String
- How to use d3+react?
- Rendering GeoJson file in D3 v4 is not scaling properly
- Can't make a zoom on D3 graph
- d3.js - Force Layout and Node Positions
- How to define repeat and layer in vega-lite api
- Converting Observable notebook code to plain Javascript
- D3 Chaining Animations using a for loop
- D3 graph not updating on click
- Issues with populating arrays from csv(dsv) parsing
- What does the syntax d._children = d.children; stand for in d3.js?
- d3.js: Histogram not rendering if domain does not start with 0 (means [0, *])
- Unable to create Manhattan plot with d3
- d3.js dynamic data reload possibly related to exit().remove()
- External javascript cannot run in D3JS
- Getting transition values in D3
- D3.js Pie chart tween in ES6 - Uncaught TypeError
- Putting images as axis ticks in d3.js
- D3.js line chart - positioning the dots
- D3: How to detect the end of the .each()
- Very basic syntax error, lines not drawing in d3
- d3: Append caption/title to table
- Designing rich list
- I am making a d3.js graph as a csv file How should I manipulate the data?
- How to generate SVG using dimple in Node.js
- d3 bar chart with custom x axis and bar width
- Separating color of y-axis and y-labels in a D3 bar chart
- D3 append (insert) existing SVG string (or element) to a DIV