score:2
The problem is the way you track the clicked state. Specifically, this variable for the line...
//Determine if current line is visible
var active = blueLine.active ? false : true;
... and this variable for the circles:
// Determine if dots are visible
var active = blackDot.active ? false : true;
The line (actually, a <path>
element) has an id named blueLine
. Because of that, the element itself is a property of the window
object, that is, a global variable. For instance, have a look at this:
console.log(window.foo)
<div id="foo"></div>
Thus, blueLine.active
works, even if you never declared blueLine
anywhere in the code.
However, while the line has an id, your circle's don't (be it blackDot
or not). Also, the line in question is just one and therefore can have an id, but you have several circles and, because of that, an id cannot be used (more on that below).
So, the solution is tracking the clicked state another way. For instance, using a property of the datum:
.on("click", function(d){
// Determine if dots are visible
var active = d.active ? false : true;
Here is the code with that change:
var data = [{
x: 0,
y: 0
}, {
x: 5,
y: 30
}, {
x: 10,
y: 40
},
{
x: 15,
y: 60
}, {
x: 20,
y: 70
}, {
x: 25,
y: 100
}
];
const margin = {
left: 20,
right: 20,
top: 20,
bottom: 80
};
const svg = d3.select('svg');
svg.selectAll("*").remove();
const width = 200 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;
const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);
var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.x;
})])
.range([0, width])
.nice();
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.y;
})])
.range([0, height])
.nice();
const xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickPadding(5)
.tickSize(-height)
const yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickPadding(5)
.tickSize(-width);
svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(20,${height-margin.top-60})`)
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,20)")
.call(yAxis);
var lineFunction = d3.line()
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return y(d.y);
})
.curve(d3.curveLinear);
//defining and plotting the lines
var path = g.append("path")
.attr("class", "path1")
.attr("id", "blueLine")
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");
// plot a circle at each data point
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d) {
return y(d.y);
})
.attr("r", 3)
.attr("class", "blackDot")
.attr("clip-path", "url(#clip)");
//************* Legend ***************
var legend = svg.selectAll(".legend")
.data(data)
.enter().append("g")
legend.append("rect")
.attr("x", width + 65)
.attr("y", 50)
.attr("width", 18)
.attr("height", 4)
.style("fill", "blue")
legend.append("text")
.attr("x", width + 60)
.attr("y", 50)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function() {
// Determine if current line is visible
var active = blueLine.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.select("#blueLine").style("opacity", newOpacity);
// Update whether or not the elements are active
blueLine.active = active;
})
.text(function(d) {
return "Value";
});
var pointLegend = svg.selectAll(".pointLegend")
.data(data)
.enter().append("g")
pointLegend.append("circle")
.attr("r", 3)
.attr("cx", width + 70)
.attr("cy", 70);
pointLegend.append("text")
.attr("x", width + 60)
.attr("y", 70)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function(d) {
// Determine if dots are visible
var active = d.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.selectAll(".blackDot").style("opacity", newOpacity);
// Update whether or not the elements are active
d.active = active;
})
.text(function(d) {
return "Point";
});
.xy_chart {
position: relative;
left: 50px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="xy_chart"></svg>
Bear in mind that, while setting a single id to several elements is not advisable, it will work, as you can see in the demo below, where I just take your code as it is and set the blackDot
id to the circles:
var data = [{
x: 0,
y: 0
}, {
x: 5,
y: 30
}, {
x: 10,
y: 40
},
{
x: 15,
y: 60
}, {
x: 20,
y: 70
}, {
x: 25,
y: 100
}
];
const margin = {
left: 20,
right: 20,
top: 20,
bottom: 80
};
const svg = d3.select('svg');
svg.selectAll("*").remove();
const width = 200 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;
const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);
var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.x;
})])
.range([0, width])
.nice();
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.y;
})])
.range([0, height])
.nice();
const xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickPadding(5)
.tickSize(-height)
const yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickPadding(5)
.tickSize(-width);
svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(20,${height-margin.top-60})`)
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,20)")
.call(yAxis);
var lineFunction = d3.line()
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return y(d.y);
})
.curve(d3.curveLinear);
//defining and plotting the lines
var path = g.append("path")
.attr("class", "path1")
.attr("id", "blueLine")
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");
// plot a circle at each data point
g.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d) {
return y(d.y);
})
.attr("r", 3)
.attr("id", "blackDot")
.attr("class", "blackDot")
.attr("clip-path", "url(#clip)");
//************* Legend ***************
var legend = svg.selectAll(".legend")
.data(data)
.enter().append("g")
legend.append("rect")
.attr("x", width + 65)
.attr("y", 50)
.attr("width", 18)
.attr("height", 4)
.style("fill", "blue")
legend.append("text")
.attr("x", width + 60)
.attr("y", 50)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function() {
// Determine if current line is visible
var active = blueLine.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.select("#blueLine").style("opacity", newOpacity);
// Update whether or not the elements are active
blueLine.active = active;
})
.text(function(d) {
return "Value";
});
var pointLegend = svg.selectAll(".pointLegend")
.data(data)
.enter().append("g")
pointLegend.append("circle")
.attr("r", 3)
.attr("cx", width + 70)
.attr("cy", 70)
pointLegend.append("text")
.attr("x", width + 60)
.attr("y", 70)
.attr("dy", ".35em")
.style("text-anchor", "end")
.on("click", function() {
// Determine if dots are visible
var active = blackDot.active ? false : true,
newOpacity = active ? 0 : 1;
// Hide or show the elements
d3.selectAll(".blackDot").style("opacity", newOpacity);
// Update whether or not the elements are active
blackDot.active = active;
})
.text(function(d) {
return "Point";
});
.xy_chart {
position: relative;
left: 50px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="xy_chart"></svg>
But, again, it's not recommended setting the same id to several elements: ids must be unique.
score:0
You can check out this example.
note the : .style("visibility", "hidden") in tooltip options.
Source: stackoverflow.com
Related Query
- How to hide and show points on a line graph
- How can I show a graph using d3 force layout with initial positions set and no movement at all?
- How to show a tooltip with value when mouseover a svg line graph using d3.js?
- d3.js line and area graph - want to add a extra line defined by two points and representing a threshold/minimum value (for ease of viewing)
- How to make a mouseover interactive line graph with multiple data series and 2 y axes?
- D3 line chart does not show tool tip and data points properly
- D3 Line and Path - graph line doesn't show
- How to show edges in force directed graph using d3.js and Angular?
- how to change C3JS vertical tooltip line color and hide y axies line
- How to set x and y Threshold line in C3 line graph
- How to show the unhighlighted/ not selected data points on scatter plots when using brush/group in dc.js? And is multiple brushes possible in dc.js
- Iterative/chained transitions along line graph with discrete points and delay
- How can I append text to and render that text from a line in a force directed graph in D3.js?
- D3 line graph show positive and negative numbers
- How to synchronize scatter points and line chart during an update to the data?
- How to get a dashed line on Y axis and how to display the value beside the graph in d3
- dc.js graph won't show line and y axis values
- How to show and hide a nodes text with button click and mouseover/mouseout ? D3/JS
- How to count events using year and plot line graph in d3.js v3
- How to draw straight line in d3.js (horizontally and vertically)
- Hide Tick Labels in D3 on Line Graph
- d3.js change color and size on line graph dot on mouseover
- How to draw a line / link between two points on a D3 map based on latitude / longitude?
- d3.js: How to add labels to scatter points on graph
- How to mark discrete points on a time series graph using D3 / Rickshaw?
- nvd3.js-Line Chart with View Finder: rotate axis labels and show line values when mouse over
- How to show and hides nodes when you move the mouse over a node in D3 Javascript
- how to style style line chart points in c3js
- D3.js: How to combine 2 datasets in order to create a map and show values on.mouseover?
- How to display and hide links and nodes when clicking on a node in D3 Javascript
More Query from same tag
- d3 selection.attributes.key.nodevalue doesn't return the current DOM values
- JS based influxdb graph editors like Grafana, Influga, are there reusable libraries?
- Why can't I access my JavaScript array by index outside of the d3 then function?
- D3 graph seems to extend beyond x-axis (clipping issue with brush effect)
- Trying to make reusable javascript function, but the data is not returning
- Make D3 Stacked Bar Chart fill parent SVG container
- D3 v4 - add transition to just zoom and not pan/drag
- D3 circles too big after reappearing
- DC.js, crossfilter - generic grouping with varying number of columns
- Hand Stringarray to django template and use it in d3
- Convert d3 chart (svg) to an image and display it
- D3.Drag Behavior with nested data
- C3: Adding y2 axis on the fly
- Updating bar chart in d3 generating multiple charts
- d3js bar chart upside-down and sliding brushes
- Why does my inline style not work CSS
- How add vertical line to bar char in d3js?
- What is the best way to fill D3 node circles with images?
- Updating d3 bar chart labels with new data of variable length
- Uncaught TypeError: Cannot read property 'type' of undefined with d3.js
- Responsive charts using D3pie
- How to parse a csv into a dataTable quickly and efficiently using D3 v6
- Determine if object of (x,y) points fall inside of SVG paths
- How can we load color from a sequential scale into a map in D3 v5?
- How to allow the browser to redirect to another page when clicked on each of a country in the map?
- D3 horizontal bar chart will not transition to new dataset
- Python & D3.js Dashboard Crossfilter Heat Map
- Add a Toggle function to d3 tree chart v4
- How do I modify the D3.js script to show my json's (contains SAP CDS Views) data correctly?
- plot these points xy in c3.js