d3.js - readings in meter gauge like circular axis in d3.js - javascript

This time I am stuck in a circular axis for meter readings. I want to make readings and ticks along the circular path for meter gauge (just like speedometer):
However, I am not getting the exact idea or solution for it. Also, to be specific, I want to do it with D3.js only.
I have created the meter with some references, and tried to pull out some readings in it so far, but I don't feel what I have done is the most appropriate way to do this.
Please guide me through this. Here is my code : -
<!DOCTYPE html>
<meta charset="utf-8">
<title>Speedo-meter</title>
<script src="jquery-1.9.1.min.js"></script>
<style>
svg
{
margin-left: 30px;
margin-top: 30px;
border: 1px solid #ccc;
}
</style>
<body>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script>
var data = {
"title": "Meter Gauge",
"value": 50,
"maxValue": 200
};
startAngle = 90, endAngle = 270, innerRad=175 , outerRad=185 ;
var svg = d3.selectAll("body").append("svg")
.attr("width", 500)
.attr("height", 500);
var arc = d3.svg.arc()
.innerRadius(innerRad)
.outerRadius(outerRad)
.startAngle(90 * (Math.PI/180))
.endAngle(270 * (Math.PI/180));
var title = svg.append("text")
.attr("x", 50)
.attr("y", 50)
.style("text-anchor", "start")
.text("Click on the meter line to turn the needle");
var plot = svg.append("g")
.attr("class", "arc")
.attr("transform", "translate(100 , 150 )");
var gauge = plot.append("path")
.attr("d", arc)
.attr("class", "gauge")
.attr("fill", "#ddd")
.attr("stroke", "#000")
.attr("transform", "translate(150,130) rotate(180)")
.on("click", turnNeedle);
var needle = svg.append("g")
.attr("class", "needle")
.attr("transform", "translate( 100 , 110 )")
.append("path")
.attr("class", "tri")
.attr("d", "M" + (300/2 + 3) + " " + (120 + 10) + " L" + 300/2 + " 0 L" + (300/2 - 3) + " " + (120 + 10) + " C" + (300/2 - 3) + " " + (120 + 20) + " " + (300/2 + 3) + " " + (120 + 20) + " " + (300/2 + 3) + " " + (120 + 10) + " Z")
.attr("transform", "rotate(-100, " + 300/2 + "," + (120 + 10) + ")");
function turnNeedle()
{
needle.transition()
.duration(2000)
.attrTween("transform", tween);
//console.log(d3.select(".needle").attr("cx"));
function tween(d, i, a) {
return d3.interpolateString("rotate(-100, 150, 130)", "rotate(100, 150, 130)");
}
}
var Speeds = data.maxValue/20;
var divisions = ((endAngle-startAngle))/Speeds ;
console.log("divisions=>"+divisions);
j=0;
endAngle1 = startAngle+ 20;
startAngle = 72;
for(i=0;i<=10;i++)
{
endAngle = startAngle+ divisions;
newArc = d3.svg.arc()
.innerRadius(innerRad - 10)
.outerRadius(outerRad)
.startAngle((startAngle+=divisions) * (Math.PI/180))
.endAngle(endAngle * (Math.PI/180));
var gauge = plot.append("path")
.attr("d",newArc)
.attr("class", "gauge")
.attr("id", "gauge"+i)
.attr("fill", "#ddd")
.attr("stroke", "#000")
.attr("transform", "translate(150,130) rotate(180)")
.on("click", turnNeedle);
var text = plot.append("text")
.style("font-size",14)
.style("fill","#000")
.style("text-anchor", "start")
.attr("x", -165 + 6)
.attr("dy",".35em")
.append("textPath")
.attr("xlink:href","#gauge"+i)
.attr("startOffset",5)
.text(Speeds*i);
}
</script>

Related

D3: Text to a bar chart doesn't appear

I'm newbie with d3.js and I'm trying to create a bar chart graphic but after creating the first two bars when I try to create the third the text what I want to add to the bar is hidden behind the bar.
Here is my code:
const kHeightSVG1 = 241;
const xMargin = 30;
const yTopMargin = 15;
const yBottomMargin = 50;
const barWidth = 50;
const localAdvStats = this.state.local_tcas["data"]["team_tcas"][0];
const awayAdvStats = this.state.away_tcas["data"]["team_tcas"][0];
const abrevLocalTeam = this.state.local_team["data"]["teamclub"][0]["abrev"];
const abrevAwayTeam = this.state.away_team["data"]["teamclub"][0]["abrev"];
let svg1 = d3.select("#graph1").style("background-color", "#091E36");
svg1.attr("height", kHeightSVG1);
svg1.attr("width", "100%");
let yScale = d3.scaleLinear().domain([0, 100]).range([kHeightSVG1-yBottomMargin-yTopMargin, 0]);
//Añadimos eje de las y
let g = svg1.append("g").attr("transform", "translate(" + xMargin + "," + yTopMargin + ")");
g.append("g").call(d3.axisLeft(yScale).tickFormat(function(d){
return d;
}).ticks(10)).style("color", "#FFFFFF");
//Bar1
//Añadimos primer bloque de etc
console.log("yScale: " + yScale(localAdvStats["etc"]) + yTopMargin);
let g1 = svg1.append("g");
g1.append("rect")
.attr("x", xMargin+3)
.attr("y", yScale(localAdvStats["etc"]) + yTopMargin)
.attr("width", barWidth)
.attr("height", kHeightSVG1-yTopMargin-yBottomMargin-yScale(localAdvStats["etc"]));
// //Añadimos cifra a la primera barra
g1.append("text")
.attr("transform", "translate(" + xMargin + "," + yTopMargin + ")")
.attr("x", xMargin+10)
.attr("y", yScale(localAdvStats["etc"]) + yTopMargin)
.attr("font-size", "32px")
.text(localAdvStats["etc"]);
g1.append("text")
.attr("transform", "translate(" + xMargin + "," + yTopMargin + ")")
.attr("x", xMargin+12)
.attr("y", yScale(localAdvStats["etc"]) + yTopMargin + 12)
.text("(" + abrevLocalTeam + ")");
//Bar 2
let g2 = svg1.append("g");
g2.append("rect")
.attr("x", barWidth + xMargin + 3)
.attr("y", yScale(awayAdvStats["etc"]) + yTopMargin)
.attr("width", barWidth)
.attr("height", kHeightSVG1-yTopMargin-yBottomMargin-yScale(awayAdvStats["etc"]));
g2.append("text")
.attr("x", barWidth*2.5)
.attr("y", yScale(awayAdvStats["etc"]) + yTopMargin + 12)
.attr("font-size", "32px")
.text(awayAdvStats["etc"]);
g2.append("text")
.attr("x", barWidth*2.5)
.attr("y", yScale(awayAdvStats["etc"]) + yTopMargin + 24)
.text("(" + abrevAwayTeam + ")");
//Bar 3
let g3 = svg1.append("g");
g3.append("rect")
.attr("x", barWidth*3 + xMargin)
.attr("y", yScale(localAdvStats["p_reb_of"]) + yTopMargin)
.attr("width", barWidth)
.attr("height", kHeightSVG1-yTopMargin-yBottomMargin-yScale(localAdvStats["p_reb_of"]));
g3.append("text")
.attr("x", barWidth*3 + xMargin + 10)
.attr("y", yScale(localAdvStats["p_ref_of"]) + yTopMargin)
.attr("font-size", "32px")
.text(localAdvStats["p_reb_of"]);
What I've got with this code is two bars with the text over them but a third with the text behind it.
Bar 2 and Bar 3 are made it equals but Bar 3 doesn't appear text over bar chart. What am I doing wrong?

Map legend color not working since update

i already asked this here Map + Legend on same svg
Back then my legend was working fine ^^
I didn't touch my code and when i executed it 2 days agi, the legend color went all wrong (color remains the same in some cases while value is not the same)
I really can't explain this behaviour
i tried many posts/answers that i found on internet but couldn't fix it
would someone please help me ?
Here's my code :
<script type="text/javascript">
function myFunction() {
$("#container").children().remove();
var s = document.getElementById("combobox");
var combobox = s.options[s.selectedIndex].text;
if (combobox=="Ventes Nationales") {
var fichier = "http://localhost/project-folder/province.geojson";
}
var h=$("#container").height();
var w=$("#container").width();
var svg = d3.select("#container")
.append("svg")
.attr("width", w)
.attr("height", h);
var div = d3.select("#container").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var color_domain = [100000,250000,500000,1000000,3000000];
var extent_color_domain = [0,100000,250000,500000,1000000,3000000];
var color = d3.scale.threshold()
.domain(color_domain)
.range(["#ffffcc","#d9f0a3","#addd8e","#78c679","#31a354","#006837"]);
var legend_labels = ["< 100 000", "100 000 +", "250 000 +", "500 000 +", "1 000 000 +", " > 3 000 000"];
d3.csv("http://localhost/project-folder/marocdislog.csv", function(data) {
d3.json(fichier, function(json) {
for (var i = 0; i < data.length ; i++) {
//Grab state name
var dataState = data[i].nom;
//Grab data value, and convert from string to float
var dataValue = data[i].population;
//Find the corresponding state inside the GeoJSON
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.nom;
if (dataState == jsonState) {
//Copy the data value into the JSON
json.features[j].properties.CA = dataValue;
//Stop looking through the JSON
break;
}
}
}
var projection = d3.geo.mercator().scale(1).translate([0, 0]);
var path = d3.geo.path().projection(projection);
var b = path.bounds( json ),
s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h),
t = [(w - s * (b[1][0] + b[0][0])) / 2, (w - s * (b[1][1] + b[0][1])) / 2];
projection
.scale(s)
.translate(t);
svg.selectAll("path")
.data(json.features)
.enter()
.append('path')
.attr('d', path)
.attr("stroke","white")
.attr("stroke-width",1)
.style("fill", function(d) {
//Get data value
var value = d.properties.CA;
if (value) {
//If value exists…
return color(value);
} else {
//If value is undefined…
return "#ccc";
}
})
.on("mouseover", function(d) {
div.transition()
.duration(50)
.style("opacity", .9);
div.html(d.properties.nom+"<br/>"+d.properties.CA)
.style("left", (d3.event.pageX + 30) + "px")
.style("top", (d3.event.pageY - 30) + "px")})
.on("mouseout", function() {
div.transition()
.duration(50)
.style("opacity", 0);
div.html("")
.style("left", "0px")
.style("top", "0px");})
;
var ls_w = 20, ls_h = 20;
var legend = svg.selectAll("g.legend")
.data(extent_color_domain)
.enter().append("g")
.attr("class", "legend")
.attr( 'transform', function(d,i) {
return 'translate( ' + (w - 200) + ' ' + (h - (i*ls_h) - ls_h) + ' )'
});
legend.append("rect")
.attr("x", 20)
.attr("y", -20 )
.attr("width", ls_w)
.attr("height", ls_h)
.style("fill", function(d, i) { return color(d); })
.style("opacity", 0.8);
legend.append("text")
.attr("x", 50)
.attr("y", -4 )
.text(function(d, i){ return legend_labels[i]; });
var nom = svg.append("text")
.attr("class", "legendTitle")
.attr("text-anchor","middle")
.attr( 'transform','translate( ' + (w/2) + ' ' + (h-5) + ' )')
.text("Mon titre");
});
});
}
</script>
Here's the plunker : https://plnkr.co/edit/veQCOBFdBZx1yIf2kM6C
Many thanks in advance for your help
Shame on me. Had to update chrome. Works fine

D3 circular x-axis line graph

Code & result is here: https://jsfiddle.net/nohjose/fdarxu7j/3/#&togetherjs=HpJOmlQkpI
I have coded a d3 (or at least d3 like) radial line graph to show solar panel generation rates over the last four years. I want to have a single line per year (different colour per year) outside the base circle and with a maximum set by a control (which varies the value of the variable 'amplitude'). I have data for every 10mins providing the panels didn't generate 0 Watts but for this graph plan to average the data for each day. I have a php file that returns JSON data in this form
["2014-01-01 09:00:00","0.018"]["2014-01-01 09:00:00","0.018"]["2014-01-01 09:00:00","0.018"]["2014-01-01 09:00:00","0.018"]...
I don't see how I'd now plot the data on my graph?
I know this may not be specific enough for StackOverflow but I'm stuck at the point before where I have a specific technical issue and I'm not sure where else to turn. Kindness appreciated :o)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Solar Generation Visualisation</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<link href='http://fonts.googleapis.com/css?family=Lato&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<style>
.xAxis {
fill: yellow;
stroke: orange;
stroke-width: 3px;
}
.xBigTick {
fill: none;
stroke: red;
stroke-width: 1px;
}
.xSmallTick {
fill: none;
stroke: #303030;
stroke-width: 0.25px;
}
.axisText {
font-family: Lato;
font-weight: 300;
font-size: 8pt;
}
.button {
fill: silver;
stroke: gray;
stroke-width: 3px;
}
</style>
</head>
<body>
<script type="text/javascript">
// Get the data
var data;
d3.json("./test.php", function(error, json) {
if (error) return console.warn(error);
data = json;
data.forEach(function(d) {
d.Timestamp = parseDate(d.Timestamp);
d.Power = +d.Power;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.Timestamp; }));
y.domain([0, d3.max(data, function(d) { return d.Power; })]);
});
</script>
<script type="text/javascript">
var canvasWidth= 1000;
var canvasHeight= 500;
var originx = canvasWidth/2;
var originy = canvasHeight/2;
var pi = Math.PI;
var DRratio = pi/180;
var degPerDay = 360/365;
var radPerDay = degPerDay*DRratio;
var bigTick = 100;
var smallTick = 20;
var baseRad = canvasHeight/2-bigTick;
//var baseRad = 200;
var amplitude = 1; //for magnifying the y axis data
var textMargin = 25;
var textMargin180 = 11;
var angleAdjust = 1.5*DRratio;
var angleAdjust180 = 5*DRratio;
var monthAngleAdjust = -18*DRratio;
var week = 0;
// Canvas
var svg = d3.select("body")
.append("svg")
.attr("width", canvasWidth)
.attr("height", canvasHeight);
// x axis line (radial version)
var circle = d3.select("svg")
.append("circle")
.attr("cx", originx)
.attr("cy", originy)
.attr("r", baseRad)
.attr("class", "xAxis");
// weekly (big) tick marks
for (a=0; a<=2*pi; a+=(radPerDay)*7) {
var line = d3.select("svg")
.append("line")
.attr("x1", originx + (baseRad * Math.cos(a)))
.attr("y1", originy + (baseRad * Math.sin(a)))
.attr("x2", originx + ((baseRad + bigTick) * Math.cos(a)))
.attr("y2", originy + ((baseRad + bigTick) * Math.sin(a)))
.attr("class", "xBigTick");
};
// axis labels
for (a=0; a<=2*pi; a+=(radPerDay)*7) {
var group = d3.select("svg")
.append("g")
//console.log('week-' + week + ' angle:' + a/DRratio + 'degrees'+ ' cos:' + Math.cos(a)+ ' Sin:' + Math.sin(a));
var text = d3.select("g")
.append("text")
.attr("class", "axisText")
.attr("style", "fill:black")
.attr("opacity", "1")
.text(week);
// adjust the label orientation & tweak the position
if (a > 0 && (a < (pi/2))){
text.attr("transform", "translate(" + (originx + (baseRad - textMargin) * Math.cos( -a+angleAdjust )) + "," + (originy - (baseRad - textMargin) * Math.sin( -a+angleAdjust )) + ")rotate(" + (a/DRratio) +")");
}
if ((a > (pi/2)) && (a < (3*pi/2))){
text.attr("transform", "translate(" + (originx + (baseRad - textMargin180) * Math.cos( -a+angleAdjust180 )) + "," + (originy - (baseRad - textMargin180) * Math.sin( -a+angleAdjust180 )) + ")rotate(" + (a/DRratio+180) +")");
}
if ((a > (3*pi/2)) && (a < (2*pi))){
text.attr("transform", "translate(" + (originx + (baseRad - textMargin) * Math.cos( -a+angleAdjust )) + "," + (originy - (baseRad - textMargin) * Math.sin( -a+angleAdjust )) + ")rotate(" + (a/DRratio) +")");
}
week=week+1;
};
// weekly (big) tick marks
for (a=0; a<=2*pi; a+=(radPerDay)*7) {
var line = d3.select("svg")
.append("line")
.attr("x1", originx + (baseRad * Math.cos(a)))
.attr("y1", originy + (baseRad * Math.sin(a)))
.attr("x2", originx + ((baseRad + bigTick) * Math.cos(a)))
.attr("y2", originy + ((baseRad + bigTick) * Math.sin(a)))
.attr("class", "xBigTick");
};
// month labels
var inrad = 100;
var outrad = baseRad - textMargin;
var months= [31,28,31,30,31,30,31,31,30,31,30,31];
var month = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var mr = 0;
// monthly (inner) lead lines
for (a=0; a<=11; a+=1) {
var line = d3.select("svg")
.append("line")
.attr("x1", originx + (inrad * Math.cos(mr)))
.attr("y1", originy + (inrad * Math.sin(mr)))
.attr("x2", originx + (outrad * Math.cos(mr)))
.attr("y2", originy + (outrad * Math.sin(mr)))
.attr("class", "xBigTick");
mr = mr + months[a]*radPerDay;
//console.log('cumulative day at end of month: ' + m + '(' + (m * radPerDay) + ')');
};
md = 0;
mr = 0;
//month text
for (a=0; a<=11; a+=1) {
var group = d3.select("svg")
.append("g")
//console.log('week-' + week + ' angle:' + a/DRratio + 'degrees'+ ' cos:' + Math.cos(a)+ ' Sin:' + Math.sin(a));
var text = d3.select("g")
.append("text")
.attr("class", "axisText")
.attr("style", "fill:black")
.attr("opacity", "1")
.text(month[a]);
// adjust the month label orientation & tweak the position
if (md >= 0 && (md < 90)){
text.attr("transform", "translate(" + (originx + ((inrad - textMargin) * Math.cos( -mr+monthAngleAdjust ))) + "," + (originy - ((inrad - textMargin) * Math.sin( -mr+monthAngleAdjust ))) + ")rotate(" + (md) +")");
}
if ((md > 90) && (md < 270)){
text.attr("transform", "translate(" + (originx + (inrad ) * Math.cos( -mr+monthAngleAdjust )) + "," + (originy - (inrad) * Math.sin( -mr+monthAngleAdjust )) + ")rotate(" + (md+180) +")");
}
if ((md >270) && (md < 360)){
text.attr("transform", "translate(" + (originx + (inrad - textMargin) * Math.cos( -mr+monthAngleAdjust )) + "," + (originy - (inrad - textMargin) * Math.sin( -mr+monthAngleAdjust )) + ")rotate(" + (md) +")");
}
md = md + months[a]*degPerDay;
mr = mr + months[a]*radPerDay;
//console.log(md + "deg = " + mr + "rad");
};
// daily (small) tick marks
for (a=0; a<=2*pi; a+=(radPerDay)) {
var line = d3.select("svg")
.append("line")
.attr("x1", originx + (baseRad * Math.cos(a)))
.attr("y1", originy + (baseRad * Math.sin(a)))
.attr("x2", originx + ((baseRad + smallTick) * Math.cos(a)))
.attr("y2", originy + ((baseRad + smallTick) * Math.sin(a)))
.attr("class", "xSmallTick");
};
//control handle (move to adjust amplitude)
var circle = d3.select("svg")
.append("circle")
.attr("cx", originx)
.attr("cy", originy)
.attr("r", 10)
.attr("class", "button");
</script>
</body>
</html>

D3 how to create round axis and style options

I needed to code a simple app with a graph so I chose D3. I also use the ionic framework to code the app and I implemented all the code in a controller. It displays correct in the app. I know it's best practice to put this in a directive but I also had no luck on making that work.
But I have some trouble learning D3, I need to make a thermometer but I end up with a square. I followed tutorials and did my best. Can someone help me with this?
it needs to look something like this therometer
Code:
$scope.height = window.innerHeight - 110;
/**
* d3 code for the thermometer! d3 is a library for javascript and injected in the index.html in the www map.
*/
//this is an array for the chart is using for the rectangle in the chart itself. it gets it data form the ChallengeService
var bardata = [$scope.challenge.amount];
//this code is used to correctly show the axes of the chart.
var margin = {top: 30 , right: 30 , bottom: 40 , left: 50 };
// these are values needed to drawn the chart correctly $scope.height is the ion-view - header bar - footer bar.
var height = $scope.height - margin.top - margin.bottom,
width = 200 - margin.left - margin.right,
barWidth = 50,
barOffset = 5,
border = 5,
bordercolor = '#F5F5F5';
//used for the axis in scaling
var yScale = d3.scale.linear()
.domain([0, 2184])
.range([0, height]);
var xScale = d3.scale.ordinal()
.domain(d3.range(0, bardata.length))
.rangeBands([0, width])
//this is the actual chart that gets drawn.
var myChart = d3.select('#chart').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('id' , 'mijnsvg')
.append('g')
.attr('transform', 'translate(' +margin.left +','+margin.right +')')
.selectAll('rect').data(bardata)
.enter().append('rect')
.style('fill', '#d0e4db')
.attr('width', xScale.rangeBand())
.attr('x', function(d,i) {
return xScale(i);
})
//.attr('ry', 75)
.attr('height', 0)
.attr('y', height)
//if they want a border this is the way keep in mind that it will shrink the graph and you need to adjust it when drawing!
//.style("stroke", bordercolor)
//.style("stroke-width", border)
// used for how the chart is rendered this allows me to delay the drawing of the chart till the moment the users is on the tab.
myChart.transition()
.attr('height', function(d) {
return yScale(d);
})
.attr('y', function(d) {
return height - yScale(d);
})
.delay(function(d, i) {
return i * 50;
})
.duration(1300)
.ease('exp')
// theese are both axes being drawn
var vGuideScale1 = d3.scale.linear()
.domain([0, 2184])
.range([height, 0])
var vGuideScale2 = d3.scale.linear()
.domain([0, 2184])
.range([height, 0])
var vAxisLeft = d3.svg.axis()
.scale(vGuideScale1)
.orient('right')
.ticks(5)
.tickFormat(function(d){
return '€ ' + parseInt(d);
})
var vAxisRight = d3.svg.axis()
.scale(vGuideScale2)
.orient('right')
// i use this in d3 to draw the right line otherwise it will fill in values.
.ticks("")
var vGuide = d3.select('#mijnsvg').append('g')
vAxisLeft(vGuide)
vGuide.attr('transform', 'translate('+ margin.left+',' + margin.top+ ')')
vGuide.attr('rx', 50)
vGuide.selectAll('path')
.style({ fill: '#368169', stroke: "#368169"})
vGuide.selectAll('line')
.style({ stroke: "#368169"})
var vGuideRight = d3.select('#mijnsvg').append('g')
vAxisRight(vGuideRight)
vGuideRight.attr('transform', 'translate('+ 164.5 + ',' + margin.top +')' )
vGuideRight.selectAll('path')
.style({ fill: '#368169', stroke: "#368169"})
vGuideRight.selectAll('line')
.style({ stroke: "#368169"})
var hAxis = d3.svg.axis()
.scale(xScale)
.orient('top')
.tickValues('')
var hGuide = d3.select('#mijnsvg').append('g')
hAxis(hGuide)
hGuide.attr('transform', 'translate('+ margin.left+',' + margin.top + ')')
hGuide.selectAll('path')
.style({ fill: '#368169', stroke: "#368169"})
hGuide.selectAll('line')
.style({ stroke: "#368169"})
.style('xr', 100)
Instead of using rounded corner rect, I'd create a custom path generator:
function roundedRect(w, x, d) { // width of bar, x position and datum value
var arcHeight = 30; // height of arc
var p = "";
p += "M" + (x) + "," + (height); // move to lower left
p += " L" + (x) + "," + (yScale(d) + arcHeight); // line up to start of arc
p += " Q " + (w * 0.25) + "," + yScale(d) + " " + (w * 0.5 + x) + "," + yScale(d); // arc to center point
p += " Q " + (w * 0.75 + x) + "," + yScale(d) + " " + w + "," + (yScale(d) + arcHeight); // arc to end
p += " L" + w + "," + (height); // line down to bottom
return p;
}
You can use this to draw both the border and "bars".
Here's full working code. I cleaned up the axis a bit and added an attrTween function so you could still keep the animation.
<!DOCTYPE html>
<html>
<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>
.axis path {
display: none;
}
.axis line {
stroke: #d0e4db;
}
line {
shape-rendering: crispEdges;
}
.axis .tick line {
stroke: #368169;
stroke-dasharray: 2, 2;
stroke-width: 4;
}
text {
font-family: Verdana;
font-size: 12px;
}
</style>
</head>
<body>
<div id="chart"></div>
<script>
var $scope = {};
$scope.height = 500;
/**
* d3 code for the thermometer! d3 is a library for javascript and injected in the index.html in the www map.
*/
//this is an array for the chart is using for the rectangle in the chart itself. it gets it data form the ChallengeService
var bardata = [1500];
//this code is used to correctly show the axes of the chart.
var margin = {
top: 30,
right: 30,
bottom: 5,
left: 50
};
// these are values needed to drawn the chart correctly $scope.height is the ion-view - header bar - footer bar.
var height = $scope.height - margin.top - margin.bottom,
width = 200 - margin.left - margin.right,
barWidth = 50,
barOffset = 5,
border = 5,
bordercolor = '#F5F5F5';
//used for the axis in scaling
var yScale = d3.scale.linear()
.domain([0, 2184])
.range([height, 0]);
var xScale = d3.scale.ordinal()
.domain(d3.range(0, bardata.length))
.rangeBands([0, width])
//this is the actual chart that gets drawn.
var svg = d3.select('#chart').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('id', 'mijnsvg')
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.right + ')');
var myChart = svg
.selectAll('rect').data(bardata)
.enter().append('path')
.style('fill', '#d0e4db');
// used for how the chart is rendered this allows me to delay the drawing of the chart till the moment the users is on the tab.
myChart.transition()
.attrTween("d", function(d) {
var interpolate = d3.interpolate(0, d);
return function(t) {
return roundedRect(xScale.rangeBand() - 15, 15, interpolate(t));
}
})
.delay(function(d, i) {
return i * 50;
})
.duration(1300)
.ease('exp');
var border = svg.append("g")
.append("path")
.attr("d", roundedRect(width, 0, 2184))
.style("stroke", "#368169")
.style("stroke-width", 6)
.style("fill", "none");
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(4)
.tickSize(width / 2)
.tickPadding(15)
.orient("left");
svg
.append("g")
.attr("transform","translate(" + width / 2 + ",0)")
.attr("class", "y axis")
.call(yAxis);
function roundedRect(w, x, d) {
var arcHeight = 30;
var p = "";
p += "M" + (x) + "," + (height);
p += " L" + (x) + "," + (yScale(d) + arcHeight);
p += " Q " + (w * 0.25 + x/2) + "," + yScale(d) + " " + (w * 0.5 + x/2) + "," + yScale(d);
p += " Q " + (w * 0.75 + x/2) + "," + yScale(d) + " " + w + "," + (yScale(d) + arcHeight);
p += " L" + w + "," + (height);
return p;
}
</script>
</body>
</html>

Need some help on D3 pie layout adding line to label

Here is the image sample how I want to look alike:
http://i.stack.imgur.com/ro2kQ.png
I was making a pie chart but I want to add a line to that label-> value.
Any help would be appreciated.
http://jsfiddle.net/28zv8n65/
Here is ;
arcs.append("svg:text")
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius + 50; // Set Outer Coordinate
d.innerRadius = outerRadius + 45; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle") //center the text on it's origin
.style("fill", "Purple")
.style("font", "bold 12px Arial")
.text(function(d, i) { return dataSet[i].label; });
Try this code.
var labelr = outerRadius+60;
//Draw labels
arcs.append("svg:text")
.attr("text-anchor", "middle") //center the text on it's origin
.style("fill", "Purple")
.style("font", "bold 12px Arial")
.text(function(d, i) { return dataSet[i].label; })
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (labelr - 75);
return d.x = Math.cos(a) * (labelr - 20);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (labelr - 75);
return d.y = Math.sin(a) * (labelr - 20);
})
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
//Draw pointer lines
arcs
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
});
Code refered from d3.js pie chart with angled/horizontal labels

Categories

Resources