I'm trying to show a label on each circle of the svg and change them every time the select box changes. Something shows up, but it's unreadable and I don't know what's wrong.
Here's the js bin: http://jsbin.com/legexovicu/edit?html,output
And this is the relevant code:
var pathContainers = svg.selectAll('g.line')
.data(operacion);
pathContainers.enter().append('g')
.attr('class', 'line')
.attr("style", function(d) {
return "stroke: " + color_hash[operacion.indexOf(d)][1];
});
pathContainers.selectAll('path')
.data(function (d) { return [d]; }) // continues the data from the pathContainer
.enter().append('path')
.attr('d', d3.svg.line()
.x(function (d) { return xScale(d.x); })
.y(function (d) { return yScale(d.y); })
);
pathContainers.selectAll('text')
.data(function (d) { return d; })
.enter().append('text')
.attr('x', function (d) { return xScale(d.x) + 20; })
.attr('y', function (d) { return yScale(d.y) + 25; })
.text( function (d) { return d.name; })
.attr("text-anchor", "middle")
.attr("font-family", "arial")
.attr("font-size", "5px")
.attr("fill", "white")
.attr('background','white');
// add circles
pathContainers.selectAll('circle')
.data(function (d) { return d; })
.enter().append('circle')
.attr('cx', function (d) { return xScale(d.x); })
.attr('cy', function (d) { return yScale(d.y); })
.attr('r', 2)
.style('fill', 'white')
.attr("title", function(d) { return d.name });
If I look the generated html, I see something like this:
<text x="70" y="75" text-anchor="middle" font-family="arial" font-size="5px" fill="white" background="white">Consti</text>
But I end up getting something illegible.
Add this to your texts:
.style("stroke-width", 1);
Here is your JSBin: http://jsbin.com/lujuhupata/1/edit?html,output
Related
Can i use style fill and class with fill also ?
bar.selectAll("rect")
.data(function(d) { return d.valores; })
.enter().append("rect")
.attr("class", function (d) { return ((d.star == true) ? "bar_star" : "bar"); }) //added line
.attr("x", function (d) { return x1(d.name); })
.attr("width", x1.rangeBand())
.attr("y", height)
.attr("height", 0)
.transition()
.duration(500)
.attr("y", function (d) { return y(d.value); })
.attr("height", function (d) { return height - y(d.value); })
.attr("value", function(d) { return d.name; })
.style("fill", function(d) { return color(d.name); }); //before
bar.on("mouseover", tip.show);
bar.on("mouseout", tip.hide);
My classes is :
.bar {
fill: orange;
}
.bar:hover {
fill: orangered ;
}
If I try directly in the
.on(mouseover)
it does not work.My fill is invisible.When I remove the line
.style("fill", function(d) { return color(d.name); });
Nothing works neither the tooltip nor the hover. What should I do ?
Thank you for answring,
Im having a bar charts with labels. After data refresh labels are not shown correctly. Not sure what Im doing wrong with newToolTip part.
Labels are not removed and stay on canvas after update data.
Thanks for help.
//function for button click event
function getValue(myDataArray) {
document.getElementById('choosenButton').innerHTML = 'chosen data: ' + myDataArray;
document.getElementById('choosenButton2').innerHTML = 'chosen data: ' + myDataArray;
//Scales pre chart1 set up for various dataarrays
var x = d3.scaleBand().domain(d3.range(0, eval(myDataArray).length))
.range([0, svgWidth])
.paddingInner(0.05);
var y = d3.scaleLinear()
.domain([0,d3.max(eval(myDataArray), function(d) { return (+d.balance)})])
.range([0, svgHeight]);
// add the x Axis
var xAxis = d3.scaleBand()
.domain(eval(myDataArray).map(function(d) { return d.name}))
.range([0, svgWidth])
.paddingInner(0.05);
//add y axis
var yAxis = d3.scaleLinear()
.domain([0, d3.max(eval(myDataArray), function(d) { return (+d.balance)})])
.range([svgHeight, 0]);
var bars = myCanvas1.selectAll('rect').data(eval(myDataArray));
var newToolTip = myCanvas1.selectAll('g').select('.tooltip').data(eval(myDataArray));
//exit data
bars.exit()
.transition()
.duration(duration1)
.attr('height', svgHeight - function(d) { return (+d.balance)})
.remove();
//enter new data
bars.enter()
.append('rect')
.style('fill', 'steelblue')
.on('mouseover',mouseover)
.on('mouseout', mouseout)
.attr('x', function(d, i) { return x(i); })
.attr('width', x.bandwidth())
.attr('y', function(d) { return (svgHeight - y(+d.balance));})
.attr('height', function(d) { return y(+d.balance); })
.merge(bars)
.transition()
.duration(duration1) //update
.attr('x', function(d, i) { return x(i); })
.attr('width', x.bandwidth())
.attr('y', function(d) { return (svgHeight - y(+d.balance)); } )
.attr('height', function(d) { return y(+d.balance); });
newToolTip.exit()
.transition()
.duration(duration1)
.remove();
newToolTip.enter()
.append('text')
.attr('class', 'tooltip')
.style('fill', 'red')
.attr('x', function(d, i) { return x(i); })
.attr('y', function(d) { return (svgHeight - y(+d.balance) - 20); } )
.text(function(d) { return +d.balance; });
newToolTip.attr('x', function(d, i) { return x(i); })
.style('fill', 'green')
.attr('y', function(d) { return (svgHeight - y(+d.balance) - 20); } )
.text(function(d) { return +d.balance; });
myCanvas1.selectAll('g.yaxis')
.transition()
.duration(duration1)
.call(d3.axisLeft(yAxis));
myCanvas1.selectAll('g.xaxis')
.transition()
.duration(duration1)
.call(d3.axisBottom(xAxis))
.selectAll('text')
.attr('dx', '-2.2em')
.attr('dy', '-.15em')
.attr('transform', 'rotate(-65)');
};
function mouseover() {
d3.select(this).attr('opacity', .5);
};
function mouseout() {
d3.select(this).attr('opacity', 1);
};
Here is working code:
var labelsGroup = myCanvas1.append("g")
var labels = labelsGroup
.selectAll(".tooltip")
.data(dataArray1)
.enter()
.append('text')
.attr('class', 'tooltip')
.attr('x', function(d, i) { return x(i); })
.attr('y', function(d) { return (svgHeight - y(+d.balance) - 20); } )
.text(function(d) { return +d.balance; });
and after click I upgrade chart with:
var newToolTip = labelsGroup.selectAll('.tooltip').data(eval(myDataArray));
newToolTip.exit()
.transition()
.duration(duration1)
.remove();
newToolTip.enter()
.append("text")
.attr('class', 'tooltip')
.style('fill', 'red')
.attr('x', function(d, i) { return x(i); })
.attr('y', function(d) { return (svgHeight - y(+d.balance) - 20); } )
.text(function(d) { return +d.balance; })
.style('opacity', 1);
newToolTip.attr('x', function(d, i) { return x(i); })
.style('fill', 'green')
.attr('y', function(d) { return (svgHeight - y(+d.balance) - 20); } )
.text(function(d) { return +d.balance; });
My tooltip should hide if the mouse is over the data 'white'.. But i don't know how to do this
Here is my code:
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); })
.call(d3.helper.tooltip()
.attr({class: 'tooltip2'})
.text(function(d, i){ return d.name + ': '+ (-((d.y0) - (d.y1))) ; })
);
dataseries:
State, White , FA Nicht gebucht, FA gebucht
07.10.2014,24,1,0
08.10.2014,24,1,0
13.10.2014,22,3,0
14.10.2014,24,1,0
15.10.2014,21,4,0
16.10.2014,15,10,1
17.10.2014,12,13,0
20.10.2014,17,8,0
Here is a JSFiddle of what I've done so far
The graph is not showing he nodes on load...I am not able to figure out what has gone wrong with the code...
var zoom = null; //the d3.js zoom object
var zoomWidgetObj = null; //the zoom widget draghandeler object
var zoomWidgetObjDoZoom = true;
var oldzoom = 0;
var w = 1060,
h = 800,
radius = d3.scale.log().domain([0, 312000]).range(["10", "50"]);
var color = d3.scale.category20();
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("idx", -1)
.attr("idsel", -1);
//d3.json(data, function(json) {
var force = self.force = d3.layout.force()
.nodes(data.nodes)
.links(data.links)
.distance(100)
.linkDistance(1)
.linkStrength(0.1)
.charge(-1000)
.size([w,h])
.start();
var link = vis.selectAll("line.link")
.data(data.links)
.enter().append("line")
.attr("class", "link")
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; })
.style("stroke-width", function(d) { return Math.sqrt(d.value); })
.on("mouseover", function(d) {
var selection = d3.select(this);
var initialWidth = Number( selection.style("stroke-width") );
selection.transition().style("stroke-width", initialWidth + Number(1) )
.style("stroke-opacity", 1.0).duration(5)
.style("stroke","green")
})
.on("mouseout", function(d) {
var selection = d3.select(this);
selection.transition().style("stroke-width", getLinkStroke( selection.data()[0]))
.style("stroke-opacity", conf.link_def_opacity)
.style("stroke", "black")});
var node = vis.selectAll("g.node")
.data(data.nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("r", 4.5)
.call(force.drag)
.on("mousedown", function(d) {
d.fixed = true;
d3.select(this).classed("sticky", true)})
.on("mouseover", mouseover)
.on("mouseout", mouseout);
node.append("circle")
.attr("class", function(d){ return "node type"+d.type})
.attr("r", function(d) { return radius(d.value) || 10 })
.call(force.drag)
.style("stroke", "gray")
.attr('stroke', '#fff')
.attr('stroke-width', '2.5px');
node.append("svg:image")
.attr("class", "circle")
.attr("xlink:href", function(d){ return d.img_href})
.attr("x", "-16px")
.attr("y", "-16px")
.attr("width", "32px")
.attr("height", "32px");
node.append("svg:title")
.text(function(d) { return d.name; });
node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", 16)
.attr("dy", ".35em")
.text(function(d) { return d.name });
node.select("circle").style("fill", function(d) { return d.name=="Salvation Army"?"white":"blue"; });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
function mouseover() {
d3.select(this).select("circle").transition()
.duration(75)
.attr("r", 16)
.style("fill", "red");
}
function mouseout() {
d3.select(this).select("circle").transition()
.duration(75)
.attr("r", 8);
}
One of your circles has a radius of NaN - this is most likely why they aren't rendering. Put a breakpoint where you're setting the radius and isolate the node / the cause of the NaN.
I'm looking at this other question and this example provided in that question, and I cannot quite get my own update function to work:
update = function() {
path = svg.append("svg:g").selectAll("path")
.data(force.links());
path.enter().append("svg:path")
.attr("class", "link")
.attr("fill", "none")
.attr("stroke", "#666")
.attr("stroke-width",
function(d) {
return (Math.floor(Math.log(d.value - min_val) / Math.log(2)) + 1) + "px"
})
.attr("marker-end", "url(#generic_arrow_marker)")
.on("mouseover",
function(d, i) {
if(d3.select(this).attr("stroke") != "#666") {
mousedOut = false;
}
})
.on("mouseout",
function(d, i) {
if(d3.select(this).attr("stroke") != "#666") {
mousedOut = true;
restoreGraph();
}
});
path.exit().remove();
circle = svg.append("svg:g").selectAll("circle")
.data(force.nodes());
circle.enter().append("svg:circle")
.attr("r",
function(d) {
return (20 + Math.floor(Math.log(d.pagerank) / Math.log(2)) * 2) + "px"
})
.attr("fill", "#ccc")
.attr("stroke", "#333")
.attr("stroke-width", "1.5px")
.on("mouseover", // select relevant data nodes on click
function(d, i) {
mousedOut = false;
d3.select(this).attr("class", "selected");
transitions(d);
$("span#user").text(d.name)
$("span#pagerank").text(d.pagerank)
})
.on("click",
function(d, i) {
incoming = !incoming;
transitions(d);
})
.on("mouseout",
function(d, i) {
mousedOut = true;
d3.select(this).attr("class", "");
restoreGraph();
})
.call(force.drag);
circle.exit().remove();
text = svg.append("svg:g").selectAll("g")
.data(force.nodes());
textEnter = text.enter().append("svg:g");
textEnter.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.attr("class", "shadow")
.text(function(d) { return d.name; })
textEnter.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; })
text.exit().remove();
force.start();
}
Whenever I call update(), it creates an entirely new copy of the existing D3 graph, even if I didn't change anything.
Ideas on what I might be doing wrong?
I figured it out as soon as I posted the question...
It was because I had svg.append("svg:g") for path, circle, and text.
I think I'll leave this question up in case it helps anyone else...