c3js d3 dash-stroke only one side of rect element - javascript

i have a rect element and i want to set up a dash stroke only in the right side, currently i've added the lines with css like this:
.c3-event-rect {
stroke: #ccc;
stroke-dasharray: 1,3;
stroke-width: 1px;
}
with javascritp is something like
d3.selectAll('.c3-event-rect')
.style('stroke-dasharray', ('2,3'))
.style('stroke', '#dedede')
but the dashed is covered all the sides
i've tried this post here but i don't get the result that i want

To achieve your expected result, use dashed line to the right of rectangle
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200);
//Draw the Rectangle
var rectangle = svgContainer.append("rect")
.attr("x", 10)
.attr("y", 10)
.attr("width", 50)
.attr("height", 100);
svgContainer.append("line")
.style("stroke", "black")
.attr("x1", 60)
.attr("y1", 10)
.attr("x2", 60)
.attr("y2", 110)
.style("stroke-dasharray", ("2, 3"))
http://codepen.io/nagasai/pen/zBREmV

You just need to break up the 50 which forms the space into smaller dashes. Something like this perhaps.
rect { fill: none; stroke: black; }
.right { stroke-dasharray: 50,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,100 }
<svg height="300">
<rect x="0.5" y="0.5" width="50" height="50" class="right"/>
</svg>
or if you only want 1 side dashed add a zero at the beginning so the solid and dashed areas swap.
rect { fill: none; stroke: black; }
.right { stroke-dasharray: 0,50,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,100 }
<svg height="300">
<rect x="0.5" y="0.5" width="50" height="50" class="right"/>
</svg>
Alternatively draw the shape as 2 paths, one which is the solid 3 sided shape and the other which is a vertical dashed line.

Related

Log scale was not plotting for line graph with domains (min:0.97,max:0.99)

I was trying to plot linechart with the linear scale for x-axis and log scale for y-axis, I was able to get ticks on x-axis and unable to get ticks on y-axis, approximate domain for y-axis for which I was trying to plot is (min:0.97, max:0.99).
For more information
I am sharing the code snippet for what I was trying to implement using d3js.
<div class="chart">
<svg id="lineChart" width="700" height="400"></svg>
</div>
var data =[{"x":0,"y":0.9978130459785461},{"x":0.008500000461935997,"y":0.9978128337965614},{"x":0.017000000923871994,"y":0.9978125548636445},{"x":0.025499999523162842,"y":0.9978121495279796},{"x":0.03400000184774399,"y":0.9978114984883847},{"x":0.042500000447034836,"y":0.9878106612451595},{"x":0.050999999046325684,"y":0.9878096376589295},{"x":0.05950000137090683,"y":0.9878084275193106},{"x":0.06800000369548798,"y":0.9878070306571847},{"x":0.07649999856948853,"y":0.9878055064026502},{"x":0.08500000089406967,"y":0.987803675684732},{"x":0.09350000321865082,"y":0.9778017168930565},{"x":0.10199999809265137,"y":0.9777995106789062},{"x":0.11050000041723251,"y":0.9777972353041961},{"x":0.11900000274181366,"y":0.9777947712404012},{"x":0.1274999976158142,"y":0.9777920584884845},{"x":0.13600000739097595,"y":0.9777892157479598},{"x":0.1445000022649765,"y":0.9777860636906962},
];
var lineChart = d3.select("#lineChart");
var WIDTH = 700;
var HEIGHT = 400;
var MARGINS = {top: 30,right:50, bottom:30, left:50};
var xMin = d3.min(data, function(d) {
return d.x;
});
var xMax = d3.max(data, function(d) {
return d.x;
});
var yMin = d3.min(data, function(d) {
return d.y;
});
var yMax = d3.max(data, function(d) {
return d.y;
});
var xScale = d3.scale.linear().range([MARGINS.left, WIDTH-MARGINS.right]).domain([xMin,xMax]);
var yScale = d3.scale.log().range([HEIGHT-MARGINS.top, MARGINS.bottom]).domain([yMin,yMax]);
var xAxes = d3.svg.axis().scale(xScale);
var yAxes = d3.svg.axis().scale(yScale).orient("left");
lineChart.append("g")
.attr("transform", "translate(0," + (HEIGHT-MARGINS.bottom) + ")")
.attr("class","x")
.call(xAxes);
lineChart.append("g")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.attr("class","y")
.call(yAxes);
var line = d3.svg.line()
.x(function(d){return xScale(d.x);})
.y(function(d){return yScale(d.y);});
lineChart.append("path")
.attr("d", line(data))
.attr("stroke", "green")
.attr("stroke-width", 2)
.attr("fill", "none");
.chart {
width:700px;
height:400px;
margin: 0 auto;
}
#lineChart {
margin: 0 auto;
background-color: #ffffff;
box-shadow: 0px 0px 20px #000000;
}
.x, .y {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x text, .y text {
stroke: none;
fill: #000;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size: 13px;
}
codepen snippet:- https://codepen.io/shanmuks/pen/ZEQBpYm

d3js zoom + drag causes conflict

I am trying to apply the zoom behaviour to a svg where certain elements in the svg are already bound with drag behaviour. without the zoom behaviour drag works fine, without the drag behaviour zoom works fine. When I have both of them it conflicts. When I drag a circle all the other circles starts to drag with it.
Here is the fiddle.
can anyone help me to figure out the issue?
<svg height="600" width="600" style="background: black">
<g>
<rect x="0" y="0" , width="600" height="40" style="fill:gold;"></rect>
<circle id='drag' cx="15" cy="20" init-cx="15" init-cy="20" r="10"
style="stroke: white; stroke-width: 2px; fill:blue"/>
</g>
<g id="playground">
<g>
<circle class='top' cx="180" cy="120" r="30" style="stroke: white; stroke-width: 2px; fill:white"/>
</g>
<g>
<circle class='top' cx="200" cy="220" r="30" style="stroke: white; stroke-width: 2px; fill:white"/>
</g>
<g>
<circle class='top' cx="320" cy="150" r="50" style="stroke: white; stroke-width: 2px; fill:white"/>
</g>
</g>
var zoom = d3.behavior.zoom()
.scaleExtent([-1, 8])
.on("zoom", function () {
var graph = d3.select('svg');
graph
.select('#playground')
.selectAll('circle')
.select(function () {
return this.parentNode;
})
.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
});
var move = d3.behavior.drag()
.on('drag', function () {
console.log('dragging');
var curr = d3.select(this)
.attr({
cx: d3.mouse(this)[0],
cy: d3.mouse(this)[1]
})
})
.on('dragend', function () {
var curr = d3.select(this);
d3.select('#playground')
.append('circle')
.attr({
cx: curr.attr('cx'),
cy: curr.attr('cy'),
r: curr.attr('r')
})
.style({
fill: 'white',
stroke: 'red',
'stroke-width': '2px'
})
;
curr.attr({
cx: curr.attr('init-cx'),
cy: curr.attr('init-cx')
});
})
;
d3.select('#drag').call(move);
d3.select('.top')
.call(d3.behavior.drag().on('drag', function () {
d3.select(this)
.attr({
cx: d3.mouse(this)[0],
cy: d3.mouse(this)[1]
})
;
}));
d3.select('svg').call(zoom);
I have implemented individual dragging of nodes working along with overall zooming and panning functionality. Used stopPropagation of the event in dragstart event of circles.
Hope this helps.
var move = d3.behavior.drag()
.on("dragstart", function() {
d3.event.sourceEvent.stopPropagation();
});
Working JSFiddle

D3 : map with topojson doesn't render properly

I'm trying to draw svg map with d3 from topojson file, but all I got is messed up lines.
I'm using most of the code I found on http://www.tnoda.com/blog/2013-12-07. When I use topojson files from that site, everything works fine. I tought maybe the problem is in my topojson file, but when I import it in mapshaper, I get normal map.
plnkr: http://plnkr.co/edit/TYiT5AoI29nEHC3Fre6D?p=preview
Here is my code:
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<script src="//code.jquery.com/jquery-2.0.0.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
</head>
<body>
<div id="map"></div>
<script src="script.js"></script>
</body>
</html>
script.js
var m_width = $("#map").width(),
width = 800,
height = 500
var projection = d3.geo.mercator()
.scale(105)
.translate([width / 2, height / 1.5]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("#map").append("svg")
.attr("width", m_width)
.attr("height", m_width * height / width);
var g = svg.append("g");
d3.json("zupanije.max.topo.json", function(error, us) {
g.append("g")
.attr("id", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter()
.append("path")
.attr("id", function(d) { return d.id; })
.attr("d", path)
});
styles.css
#map {
background-color: #fff;
border: 1px solid #ccc;
}
.background {
fill: none;
pointer-events: all;
}
#states{
cursor: pointer;
fill: #cde;
stroke: #fff;
stroke-linejoin: round;
stroke-linecap: round;
}
#states .active {
fill: #89a;
}
pre.prettyprint {
border: 1px solid #ccc;
margin-bottom: 0;
padding: 9.5px;
}
I was having the exact same problem and spent hours re-converting my SHP file to GeoJSON/Topojson in command line with different settings. The solution is quite simple!
- Get QGIS here: https://www.qgis.org/en/site/forusers/download.html
- open your SHP file or GeoJSON file
- Select the layer you want to export
- Go to Layer > Save as
- Format: Geojson
- CSR: WGS 84, EPSG: 4326
- Save.
Enjoy!

adding tooltips to pie chart using d3.js

I am embarking on a journey to learn to visualize data using d3.js, and so far I am finding the "Interactive Data Visualization" by Scott Murray very helpful. I was following through some of the example codes in book chapter 11, and was wondering how I would add the tooltip to the pie chart (the book already describes this procedure using the bar chart). Anyways, just been tinkering around with the codes for past couple of hours and would like to see if anyone can lend me a hand on this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Pie layout</title>
<script type="text/javascript" src="d3/d3.v3.js"></script>
<style type="text/css">
text {
font-family: sans-serif;
font-size: 12px;
fill: white;
}
#tooltip {
position: absolute;
width: 200px;
height: auto;
padding: 10px;
background-color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-mox-box-shadow: 4px 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rbga(0, 0, 0, 0.4)
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
</style>
</head>
<body>
<div id="tooltip" class="hidden">
<p><strong>Important Label Heading</strong></p>
<p><span id="value">100</span>%</p>
</div>
<script type="text/javascript">
//Width and height
var w = 300;
var h = 300;
var dataset = [ 5, 10, 20, 45, 6, 25 ];
var outerRadius = w / 2;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie();
// Easy colors accessible via a 10-step ordinal scale
var color = d3.scale.category10();
// Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// Set up groups
var arcs = svg.selectAll("g.arc")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
.on("mouseover", function(d){
d3.select("#tooltip")
.select("#value")
.text(d);
d3.select("tooltip").classed("hidden",false);
})
.on("mouseout", function() {
// Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
});
// Draw arc paths
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
// Labels
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text(function(d) {
return d.value;
});
</script>
</body>
</html>
I know this is bit to digest, but what I want to know more specifically is how to set the x and y value for the tool-tip. Thank you in advance.
I prefer to use the opacity to show/hide the tooltip. Here is the FIDDLE. This should get you going.
d3.select("#tooltip")
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
.style("opacity", 1)
.select("#value")
.text(d.value);
I'm adding mouse move event on FernOfTheAndes's answer, This will makes it more pretty usecase. Hope this will be helpful
.on("mouseover", function(d) {
d3.select("#tooltip").style('opacity', 1)
.select("#value").text(d.value);
})
.on("mousemove", function(d) {
d3.select("#tooltip").style("top", (d3.event.pageY - 10) + "px")
.style("left", (d3.event.pageX + 10) + "px");
})
.on("mouseout", function() {
d3.select("#tooltip").style('opacity', 0);
});

Why does my d3 force-directed graph not display edges?

I created a simple force-directed graph using d3: http://goo.gl/afHTD
Why are the edges of the graph not showing? Here is my entire HTML file. You could also see it and tinker with it by going to view source on my linked page of course. It is based on the example from the d3 website.
<!DOCTYPE html>
<html>
<head>
<title>Force-Directed Layout</title>
<script type="text/javascript" src="d3.v2.js"></script>
<style type="text/css">
div.node {
border-radius: 6px;
width: 12px;
height: 12px;
margin: -6px 0 0 -6px;
position: absolute;
}
div.link {
position: absolute;
border-bottom: solid #999 1px;
height: 0;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
}
</style>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("newJson.json", function(json) {
force
.nodes(json.nodes)
.links(json.links)
.start();
var link = svg.selectAll("line.link")
.data(json.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll("circle.node")
.data(json.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag);
node.append("title")
.text(function(d) { return d.name; });
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
</script>
</body>
</html>
Shouldn't var link... display the edges? My JSON file is also pretty simple:
{"nodes":
[{"name":"Myriel","group":1},
{"name":"Napoleon","group":1},
{"name":"Napoleon","group":2}],
"links":
[{"source":1,"target":0,"value":1},
{"source":1,"target":0,"value":1},
{"source":1, "target":2, "value":1}]}
You need to apply a stroke style via CSS. Your current node and link styles are restricted to HTML DIV elements, while the nodes and links are actually represented as SVG circle and line elements, respectively. Try this:
.node {
fill: #000;
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #aaa;
stroke-width: 1.5px;
}

Categories