Right now i have a brush function and two lines. I could add tiptool without brush function but since i have brush now, it wont focus anymore. And also i have two lines, so its hard to choose a appropriate tiptool. I wanted to add the tiptool only on the upper margin. I am new in javascript. Anyone could help me with it? Thank you so much
var margin = {
top: 10,
right: 10,
bottom: 100,
left: 40
},
margin2 = {
top: 430,
right: 10,
bottom: 20,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var color = d3.scale.category10();
var parseDate = d3.time.format("%m/%e/%Y %H:%M").parse;
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height2, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x2)
.on("brush", brush);
var line = d3.svg.line()
.defined(function(d) {
return !isNaN(d.power);
})
.interpolate("cubic")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.power);
});
var line2 = d3.svg.line()
.defined(function(d) {
return !isNaN(d.power);
})
.interpolate("cubic")
.x(function(d) {
return x2(d.date);
})
.y(function(d) {
return y2(d.power);
});
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
d3.csv("pvdata2.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) {
return key !== "pvdate";
}));
data.forEach(function(d) {
d.date = parseDate(d.pvdate);
});
var sources = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
date: d.date,
power: +d[name]
};
})
};
});
x.domain(d3.extent(data, function(d) {
return d.date;
}));
y.domain([d3.min(sources, function(c) {
return d3.min(c.values, function(v) {
return v.power;
});
}),
d3.max(sources, function(c) {
return d3.max(c.values, function(v) {
return v.power;
});
})
]);
x2.domain(x.domain());
y2.domain(y.domain());
var focuslineGroups = focus.selectAll("g")
.data(sources)
.enter().append("g");
var focuslines = focuslineGroups.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return color(d.name);
})
.attr("clip-path", "url(#clip)");
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
var contextlineGroups = context.selectAll("g")
.data(sources)
.enter().append("g");
var contextLines = contextlineGroups.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line2(d.values);
})
.style("stroke", function(d) {
return color(d.name);
})
.attr("clip-path", "url(#clip)");
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
svg.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 45)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text("Power (kW)");
});
function brush() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.selectAll("path.line").attr("d", function(d) {
return line(d.values)
});
focus.select(".x.axis").call(xAxis);
focus.select(".y.axis").call(yAxis);
}
// Active point element
var activePoint = svg.append('circle')
.attr({
cx: 0,
cy: 0,
r: 5,
'pointer-events': 'none'
})
.style({
stroke: 'none',
fill: 'red',
'fill-opacity': 0
});
svg {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.y.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
.line {
fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Related
I have been trying to implement a Line-Bar Combo Chart but I'm not much successfull.
Here's my code
function renderNormalizedStackBarChart(inputData,dom_element_to_append_to, path_to_data) {
var margin = {top: 20, right: 231, bottom: 140, left: 40},
width = $(dom_element_to_append_to).width() - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var xscale = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var yScaleLeft = d3.scale.linear()
.rangeRound([height, 0]);
var yScaleRight = d3.scale.linear()
.rangeRound([height, 0]);
var colors = d3.scale.ordinal()
.range(["#63c172", "#ee9952", "#46d6c4", "#fee851", "#98bc9a"]);
var xaxis = d3.svg.axis()
.scale(xscale)
.orient("bottom");
var yAxisLeft = d3.svg.axis()
.scale(yScaleLeft)
.orient("left")
.tickFormat(d3.format(".0%"));
var yAxisRight = d3.svg.axis()
.scale(yScaleRight)
.orient("right")
.tickFormat(d3.format(".0%"));
var x = d3.time.scale()
.range([0, width - 25]);
/*category.selectAll("rect")
.data(function(d) { return d.responses; })
.enter().append("rect")
.attr("width", xscale.rangeBand())
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
.style("fill", function(d) { return colors(d.response); });*/
var temp = 0;
var line = d3.svg.line()
.x(function(d, i) {
console.log(temp);
var temp2 = temp;
temp += xscale.rangeBand();
return temp2;
})
.y(function(d) {
console.log(yScaleRight(d.value));
return yScaleRight(d.value);
})
.interpolate("linear")
;
var svg = d3.select(dom_element_to_append_to).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 + ")");
d3.tsv(path_to_data, function(error, data) {
//data = inputData;
var categories = d3.keys(data[0]).filter(function(key) { return key !== "CategoryNames"; });
var parsedata = categories.map(function(name) { return { "CategoryNames": name }; });
data.forEach(function(d) {
parsedata.forEach(function(pd) {
pd[d["CategoryNames"]] = d[pd["CategoryNames"]];
});
});
colors.domain(d3.keys(parsedata[0]).filter(function(key) { return key !== "CategoryNames" && key !== "Base"; }));
parsedata.forEach(function(pd) {
var y0 = 0;
pd.responses = colors.domain().map(function(response) {
var responseobj = {response: response, y0: y0, yp0: y0};
y0 += +pd[response];
responseobj.y1 = y0;
responseobj.yp1 = y0;
return responseobj;
});
pd.responses.forEach(function(d) { d.yp0 /= y0; d.yp1 /= y0; });
pd.totalresponses = pd.responses[pd.responses.length - 1].y1;
});
console.log(parsedata);
xscale.domain(parsedata.map(function(d) { return d.CategoryNames; }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis)
.selectAll("text")
.attr("y", 5)
.attr("x", 7)
.attr("dy", ".35em")
.attr("transform", "rotate(65)")
.style("text-anchor", "start");
svg.append("g")
.attr("class", "y axisLeft")
.call(yAxisLeft);
svg.append("g")
.attr("class", "y axisRight")
.attr("transform", function() { return "translate(" + width + "," + 0 + ")"; })
.call(yAxisRight);
var category = svg.selectAll(".category")
.data(parsedata)
.enter().append("g")
.attr("class", "category")
.attr("transform", function(d) { return "translate(" + xscale(d.CategoryNames) + ",0)"; });
category.selectAll("rect")
.data(function(d) { return d.responses; })
.enter().append("rect")
.attr("width", xscale.rangeBand())
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
.style("fill", function(d) { return colors(d.response); });
var convertedData = [];
parsedata.forEach(function(item) {
convertedData.push({response: item.CategoryNames, value: item.responses[0].yp1})
});
temp = xscale.rangeBand()/2;
console.log(convertedData);
svg.append("path")
.data(convertedData)
.attr("class", "line")
.attr("d", line(convertedData));
var legend = svg.selectAll(".legend")
.data(colors.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(82," + ((height - 18) - (i * 20)) + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", colors);
legend.append("text")
.attr("x", width + 10)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d) { return d; });
d3.selectAll("input").on("change", handleFormClick);
function handleFormClick() {
if (this.value === "bypercent") {
transitionPercent();
} else {
transitionCount();
}
}
function transitionPercent() {
yScaleLeft.domain([0, 1]);
var trans = svg.transition().duration(250);
var categories = trans.selectAll(".category");
categories.selectAll("rect")
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); });
yAxisLeft.tickFormat(d3.format(".0%"));
svg.selectAll(".y.axisLeft").call(yAxisLeft);
}
function transitionCount() {
yScaleLeft.domain([0, d3.max(parsedata, function(d) { return d.totalresponses; })]);
var transone = svg.transition()
.duration(100);
var categoriesone = transone.selectAll(".category");
categoriesone.selectAll("rect")
.attr("y", function(d) { return this.getBBox().y + this.getBBox().height - (yScaleLeft(d.y0) - yScaleLeft(d.y1)) })
.attr("height", function(d) { return yScaleLeft(d.y0) - yScaleLeft(d.y1); });
var transtwo = transone.transition()
.delay(150)
.duration(200)
.ease("bounce");
var categoriestwo = transtwo.selectAll(".category");
categoriestwo.selectAll("rect")
.attr("y", function(d) { return yScaleLeft(d.y1); });
yAxisLeft.tickFormat(d3.format(".2s"));
svg.selectAll(".y.axisLeft").call(yAxisLeft);
}
});
d3.select(self.frameElement).style("height", (height + margin.top + margin.bottom) + "px");
}
var inputData = [];
renderNormalizedStackBarChart(inputData,"#normalizedChart", "data/normalizedChart.tsv");
rect.bordered {
stroke: #E6E6E6;
stroke-width: 2px;
}
body {
font-size: 9pt;
font-family: Consolas, courier;
}
text.axis {
fill: #000;
}
.axisLeft path,
.axisLeft line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axisRight path,
.axisRight line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
.legend line {
stroke: #000;
shape-rendering: crispEdges;
}
path .line {
stroke: #000;
shape-rendering: crispEdges;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div class="row">
<form>
<label><input type="radio" name="mode" value="bypercent" checked> Percent</label>
<label><input type="radio" name="mode" value="bycount"> Number of Respondants</label>
</form>
<div id="normalizedChart"></div>
</div>
but all I'm getting is the graph shown in the image below. How to make the path appear as line.Here in the code InputData variable is of no use as I'm reading data through a tsv file.
You have to add the style to your fill : none to your path
svg.append("path")
.data(convertedData)
.attr("class", "line")
.attr("d", line(convertedData));
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
I have created a D3 visualization which contains both a scatterplot and a line chart. They share an x-axis, but each have their own y-axis. My problem involves how to properly implement a brush and update both y-axes.
As you can see here the y-axes are correct initially and also correct again once the brush is turned off. However during 'brushing' both y-axes are set to the 'left' one. I see why this is happening when I setup my brush here:
brush = d3.svg.brush()
.x(brushFilterXScale)
.y(brushFilterTransactionsYScale)
.on('brush', brushed);
I also have a brushFilterBalanceYScale which is the scale for the axis on the right. My question is how do I pass BOTH of these scales to brush so that I can update each y-axis properly?
I don't know of a straight-forward way to do this. You can, however, reverse map it in your brush event:
function brushed() {
var extent = brush.extent(), //<-- the extent
yDomain = [extent[0][1], extent[1][1]]; //<-- the y domain of the extent
y2.domain(
[
y2Brush.invert(yBrush(yDomain[0])), //<-- take the yDomain start, get it's pixel position, then invert that back into the domain of the y2Brush
y2Brush.invert(yBrush(yDomain[1]))
]
);
Here's a working example:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
font: 10px sans-serif;
}
.line {
fill: none;
stroke: steelblue;
clip-path: url(#clip);
}
circle {
clip-path: url(#clip);
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var margin = {
top: 10,
right: 40,
bottom: 100,
left: 40
},
margin2 = {
top: 430,
right: 40,
bottom: 20,
left: 40
},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var x = d3.scale.linear().range([0, width])
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height, 0]),
xBrush = d3.scale.linear().range([0,width]),
yBrush = d3.scale.linear().range([height2, 0]),
y2Brush = d3.scale.linear().range([height2, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left"),
yAxis2 = d3.svg.axis().scale(y2).orient("right"),
yAxisBrush = d3.svg.axis().scale(yBrush).orient("bottom");
xAxisBrush = d3.svg.axis().scale(xBrush).orient("bottom");
var brush = d3.svg.brush()
.x(xBrush)
.y(yBrush)
.on("brush", brushed);
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return y(d.y);
});
var lineBrush = d3.svg.line()
.interpolate("monotone")
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return yBrush(d.y);
});
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
var data1 = [],
data2 = [];
for (var i = 0; i < 100; i++) {
data1.push({
x: i,
y: Math.random() * 10
});
if (i % 3 === 0){
data2.push({
x: i,
y: Math.random() * 100
});
}
}
x.domain([0,100]);
y.domain([0, d3.max(data1.map(function(d) {
return d.y;
}))]);
y2.domain([0, d3.max(data2.map(function(d) {
return d.y;
}))]);
xBrush.domain(x.domain());
yBrush.domain(y.domain());
y2Brush.domain(y2.domain());
focus.append("path")
.datum(data1)
.attr("class", "line")
.attr("d", line);
var scatter = focus.append("g")
.selectAll("circle")
.data(data2);
scatter
.enter()
.append("circle")
.attr("cx", function(d){
return x(d.x);
})
.attr("cy", function(d){
return y2(d.y);
})
.attr("r", function(d){
d.r = Math.random() * 20;
return d.r;
})
.style("fill", "orange")
.style("opacity", "0.5");
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
focus.append("g")
.attr("transform", "translate(" + width + " ,0)")
.attr("class", "y2 axis")
.call(yAxis2);
context.append("path")
.datum(data1)
.attr("class", "line")
.attr("d", lineBrush);
context.append("g")
.selectAll("circle")
.data(data2)
.enter()
.append("circle")
.attr("cx", function(d){
return x(d.x);
})
.attr("cy", function(d){
return y2Brush(d.y);
})
.attr("r", function(d){
return d.r * 0.25;
})
.style("fill", "orange")
.style("opacity", "0.5");
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxisBrush);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
function brushed() {
var extent = brush.extent(),
yDomain = [extent[0][1], extent[1][1]];
y2.domain([y2Brush.invert(yBrush(yDomain[0])), y2Brush.invert(yBrush(yDomain[1]))]);
x.domain(brush.empty() ? xBrush.domain() : [extent[0][0], extent[1][0]]);
y.domain(brush.empty() ? yBrush.domain() : yDomain);
scatter
.attr("cx", function(d){
return x(d.x);
})
.attr("cy", function(d){
return y2(d.y);
})
focus.select(".line").attr("d", line);
focus.select(".x.axis").call(xAxis);
focus.select(".y.axis").call(yAxis);
focus.select(".y2.axis").call(yAxis2);
}
</script>
i got a normal line chart written in d3.js
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis {
position: fixed;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = 2000 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y%m%d").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
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.date); })
.y(function(d) { return y(d.temperature); });
var svg = d3.select("body").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 + ")");
d3.tsv("data.tsv", function(error, data) {
if (error) throw error;
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var cities = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, temperature: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Temperature (ยบF)");
var city = svg.selectAll(".city")
.data(cities)
.enter().append("g")
.attr("class", "city");
cities.forEach(function(d) {
console.log(d);
});
city.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
city.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
});
but the height is higher than the screen size, so i need to scroll
But now i need to see the Axes all the time.
So i need the x-Axis and the y-Axis with fixed position
I tried CSS position:fixed but it had no effect.
Please help me.
Try applying the style when you generate the axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.style("position", "fixed")
.call(xAxis);
window.onscroll = function() {myFunction()};
function myFunction() {
if(window.pageYOffset == 0)
{
d3.select("#test").nodes()[0].setAttribute("transform", "translate(200, " + 10 +")")
}
if (window.pageYOffset > 0) {
d3.select("#test").nodes()[0].setAttribute("transform", "translate(200, " + window.pageYOffset +")")
}
}
I am trying to draw bubbles on bar charts. On every bar there will be a bubble.That Bubbles will be generate from a different json file. Can you please provide me any suggestion. Thanks in advance.
Code below.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: #ccc;
}
.x.axis path {
display: none;
}
.node {
fill: #000;
z-index: 999;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var formatPercent = d3.format(".0%");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
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")
.tickFormat(formatPercent);
var svg1 = d3.select("body").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 + ")");
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
svg1.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg1.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
svg1.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.append("bubble")
.attr("class","bub");
var diameter = 30,
format = d3.format(",d"),
color = d3.scale.category20c();
var bubble = d3.layout.pack()
.sort(null)
.size([diameter, diameter])
.padding(1.5);
var svg = d3.select(".bub").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "bubble");
d3.json("flare.json", function(error, root) {
var node = svg.selectAll(".node")
.data(bubble.nodes(classes(root))
.filter(function(d) { return !d.children; }))
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return color(d.packageName); });
node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.className.substring(0, d.r / 3); });
});
// Returns a flattened hierarchy containing all leaf nodes under the root.
function classes(root) {
var classes = [];
function recurse(name, node) {
if (node.children) node.children.forEach(function(child) { recurse(node.name, child); });
else classes.push({packageName: name, className: node.name, value: node.size});
}
recurse(null, root);
return {children: classes};
}
d3.select(self.frameElement).style("height", diameter + "px");});
function type(d) {
d.frequency = +d.frequency;
return d;
}
</script>
//File for bar chart is below
data.tsv
letter frequency
A .08167
B .01492
C .02780
D .04253
//Json for bubble charts
flare.json
{
"name": "flare",
"children": [
{"name": "Swaraj", "size": 20}
]
}
I would like to display the bubble chart on bar graph.
Hello all I'm trying to repurpose the Focus+Context graph found here: Focus + Context Example to work with a bar graph instead. I've been able to get the bars in but I have some overlap problems. When you make a selection in the context area the focus area will sometimes display bars that interfere with the display of the scale. Here's my code, there are some parts I know I need to clean up so lets not focus on that. Can someone point me in the right direction here?
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
font: 10px sans-serif;
}
path {
fill: steelblue;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var focusGraph;
var dataTest = d3.csv("sp500.csv");
var margin = {top: 10, right: 10, bottom: 100, left: 40},
margin2 = {top: 430, right: 10, bottom: 20, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var parseDate = d3.time.format("%b %Y").parse;
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([0,height]),
y2 = d3.scale.linear().range([0,height2]);
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x2)
.on("brush", brushed);
var area = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
/*var area2 = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x2(d.date); })
.y0(height2)
.y1(function(d) { return y2(d.price); });*/
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
d3.csv("sp500.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.price = +d.price;
});
x.domain(d3.extent(data.map(function(d) { return d.date; })));
y.domain([0, d3.max(data.map(function(d) { return d.price; }))]);
x2.domain(x.domain());
y2.domain(y.domain());
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
focusGraph = focus.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x(d.date); })
.attr("y", function(d) { return height - y(d.price); })
.attr("width", 5)
.attr("height", function(d) { return y(d.price); });
context.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x2(d.date); })
.attr("y", function(d) { return height2 - y2(d.price); })
.attr("width", 5)
.attr("height", function(d) { return y2(d.price); });
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
});
function brushed() {
var data = d3.csv("sp500.csv");
x.domain(brush.empty() ? x2.domain() : brush.extent());
focusGraph.attr("x", function(d, i) { return x(d.date); });
focusGraph.attr("width", 20);
focus.select(".x.axis").call(xAxis);
}
</script>
That's because you simply forgot to set clip-path to the chart. So consider the following idea:
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// here we insert the new group that will be the container for the bars
var barsGroup = focus.append("g")
.attr('clip-path', 'url(#clip)');
And then you define the actual chart as within this new group:
focusGraph = barsGroup.selectAll("rect")
.data(data)
.enter().append("rect")
See the demo: http://jsfiddle.net/JGytk/