NVD3 Chart responsive issue - javascript

NVD3 Responsive issue
I have code from my second page where I used the exactly same chart like here. But on that page it is responsive and I am trying to figure out why the chart is not responsive here.
var colors = ["rgba(74, 210, 255, .8)", "rgba(85, 172, 238, .8)", "rgba(205, 32, 31, .8)"];
d3.scale.colors = function() {
return d3.scale.ordinal().range(colors);
};
var colors = d3.scale.colors();
/*var colors = d3.scale.category20();*/
var keyColor = function(d, i) {return colors(d.key)};
var chart;
nv.addGraph(function() {
chart = nv.models.stackedAreaChart()
.useInteractiveGuideline(true)
.x(function(d) { return d[0] })
.y(function(d) { return d[1] })
.showControls(false)
.showYAxis(true)
.showLegend(false)
.rightAlignYAxis(true)
.controlLabels({stacked: "Stacked"})
.color(keyColor)
.duration(500);
chart.xAxis.tickFormat(function(d) { return d3.time.format('%a')(new Date(d)) });
chart.yAxis.tickFormat(d3.format('f'));
chart.legend.margin({
top: 30
});
d3.select('#chart1')
.datum(histcatexplong)
.transition().duration(1000)
.call(chart)
.each('start', function() {
setTimeout(function() {
d3.selectAll('#chart1 *').each(function() {
if(this.__transition__)
this.__transition__.duration = 1;
})
}, 0)
});
nv.utils.windowResize(chart.update);
return chart;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class="slide1">
<div class="col-xs-12" id="margin-chart">
<svg id="chart1" style="width: 100%; height: 300px;"></svg>
</div>
</div>

You need to call chart.update() when your slideToggle function finishes to make nvd3 redraw the chart to the new dimensions.
I.e.:
$('#chart').slideToggle(function() {
chart.update();
});

I used the .animate function.
$("#slide").click(function () {
if ($('.slide1').hasClass('showtable')) {
$('.slide1.showtable').animate({height: 300}, 500).removeClass('showtable');
} else {
$('.slide1').animate({height: 0}, 500)
$('.slide1').addClass('showtable');
}
});
.slide1 {
position: relative;
width: 100%;
overflow: hidden;
right: 25px;
}
.slide1.showtable {
height: 0;
}

Related

How to select existing chart and update it in NVD3.js

Please take a look at the below sample from NDV3.js chart library:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.min.js"></script>
<link href="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.css" rel="stylesheet" type="text/css">
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html, body, #chart1, svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
.dashed {
stroke-dasharray: 5,5;
}
</style>
</head>
<body class='with-3d-shadow with-transitions'>
<div style="position:absolute; top: 0; left: 0;">
<button onclick="updateChart();">Update Chart</button>
<script>
var updateChart = function() {
// GET CHART HERE
chart.update();
}
</script>
</div>
<div id="chart1"></div>
<script>
// Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required
var chart;
var data;
var legendPosition = "top";
nv.addGraph(function() {
chart = nv.models.lineChart()
.options({
duration: 300,
useInteractiveGuideline: true
})
;
// chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately
chart.xAxis
.axisLabel("Time (s)")
.tickFormat(d3.format(',.1f'))
.staggerLabels(true)
;
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(function(d) {
if (d == null) {
return 'N/A';
}
return d3.format(',.2f')(d);
})
;
data = sinAndCos();
d3.select('#chart1').append('svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function sinAndCos() {
var sin = [];
for (var i = 0; i < 100; i++) {
sin.push({x: i, y: i % 10 == 5 ? null : Math.sin(i/10) }); //the nulls are to show how defined works
}
return [
{
area: true,
values: sin,
key: "Sine Wave",
color: "#ff7f0e",
strokeWidth: 4,
classed: 'dashed'
}
];
}
</script>
</body>
</html>
This sample is working fine. Please look at the "updateChart" function. The problem is that I have to keep a reference to my chart and update it there. Is there an alternative for that like select it by "d3.select(...)" and update it?
This may be a late reply. Nevertheless...
Tried the below solution where the chart is still maintained as an instance and the update button's onclick triggers an update to the data.
(Added a toggle to return different data to demonstrate update functionality)
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.min.js"></script>
<link href="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.css" rel="stylesheet" type="text/css">
</head>
<body class='with-3d-shadow with-transitions'>
<div style="position:absolute; top: 0; left: 0;">
<button onclick="update();">Update Chart</button>
</div>
<div id="chart1">
<svg></svg>
</div>
<script>
var chart;
var toggle = true;
var chartData;
nv.addGraph(function () {
chart = nv.models.lineChart()
.options({
duration: 300,
useInteractiveGuideline: true
});
chart.xAxis
.axisLabel("Time (s)")
.tickFormat(d3.format(',.1f'))
.staggerLabels(true);
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(function (d) {
if (d == null) {
return 'N/A';
}
return d3.format(',.2f')(d);
});
var data = sinAndCos();
chartData = d3.select('#chart1 svg').datum(data);
chartData.transition().duration(500).call(chart);
d3.select('#chart1').append('svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function update() {
var data = sinAndCos();
chartData.datum(data).transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
};
function sinAndCos() {
var sin = [],
sin2 = [];
for (var i = 0; i < 100; i++) {
sin2.push({
x: i,
y: i % 10 == 5 ? null : Math.sin(i / 10) * 0.25 + 0.5
});
sin.push({
x: i,
y: i % 10 == 5 ? null : Math.sin(i / 10)
});
}
if (toggle) {
toggle = !toggle;
return [{
area: false,
values: sin2,
key: "Sine 2 Wave",
color: "#2ca02c",
strokeWidth: 4,
classed: 'dashed'
}];
} else {
toggle = !toggle;
return [{
area: true,
values: sin,
key: "Sine Wave",
color: "#ff7f0e",
strokeWidth: 4,
classed: 'dashed'
}];
}
}
</script>
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html,
body,
#chart1,
svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
.dashed {
stroke-dasharray: 5, 5;
}
</style>
</body>
</html>

Bar chart to take account of negative values

I have the following data in a csv file called BarData.csv:
Fruit,dt,amount
Apple,12/28/2016,-1256
Apple,12/29/2016,-500
Apple,12/30/2016,3694
Apple,12/31/2016,5586
Apple,1/1/2017,4558
Apple,1/2/2017,6696
Apple,1/3/2017,7757
Apple,1/4/2017,8528
Apple,1/5/2017,5543
Apple,1/6/2017,3363
Apple,1/7/2017,5464
Pear,12/25/2017,250
Pear,12/26/2017,669
Pear,12/27/2017,441
Pear,12/28/2017,159
Pear,12/29/2017,357
Pear,12/30/2017,775
Pear,12/31/2017,669
The following html, css, and javascript is in one .html file:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>BAR SINGLE FUNCTION</title>
<script src="http://d3js.org/d3.v3.js"></script>
<style type="text/css">
#radioDiv {
top: 45px;
font-family: verdana;
font-size: 8px;
width: 455px;
}
#TOPbarChart {
position: absolute;
top: 50px;
left: 30px;
width: 750px;
height: 195px;
}
.axis--y path,
.axis--x path {
display: none;
}
.axis--x line,
.axis--y line {
stroke: black;
fill: none;
stroke-width: 2px
}
.yAxis text,
.xAxis text {
font: 7pt Verdana;
stroke: none;
fill: black;
}
.title,
.titleX {
font-family: Verdana;
font-size: 10px;
}
</style>
</head>
<body>
<div id="radioDiv">
<label>
<input id="radioFrt" type="radio" name="frt" value="Apple" class="radioB" checked> APPLE
</label>
<label>
<input type="radio" name="frt" value="Pear" class="radioB"> PEAR
</label>
</div>
<div id="TOPbarChart"></div>
<script type="text/javascript">
var currentFruit = "Apple";
var currentColr = "#00a5b6";
var barDataCSV_Dly = "BarData.csv";
//
//
// radio button
document.getElementById("radioFrt").checked = true;
d3.selectAll('input[name="frt"]').on("change", function change() {
currentFruit = this.value;
TOPbarChart(currentFruit, currentColr);
});
//FORMATS
var parseDate = d3.time.format("%m/%d/%Y").parse;
//
// BASIC SIZING
//
function barChartBasics() {
var margin = {
top: 25,
right: 35,
bottom: 25,
left: 70
},
width = 550 - margin.left - margin.right,
height = 155 - margin.top - margin.bottom,
colorBar = d3.scale.category20(),
barPaddingFine = 1,
barPaddingThick = 2;
return {
margin: margin,
width: width,
height: height,
colorBar: colorBar,
barPaddingFine: barPaddingFine,
barPaddingThick: barPaddingThick
};
}
// create svg element
var basics = barChartBasics();
var svg = d3.select("#TOPbarChart")
.append("svg")
.attr({
"width": basics.width + basics.margin.left + basics.margin.right,
"height": basics.height + basics.margin.top + basics.margin.bottom,
id: "svgTOPbarChart"
});
// create svg group
var plot = svg
.append("g")
.attr({
"transform": "translate(" + basics.margin.left + "," + basics.margin.top + ")",
id: "svgPlotTOPbarChart"
});
var axisPadding = 2;
var leftAxisGroup = svg
.append('g')
.attr({
transform: 'translate(' + (basics.margin.left - axisPadding) + ',' + (basics.margin.top) + ')',
'class': "yAxis axis--y",
id: "yAxisGTOPbarChart"
});
var bottomAxisGroup = svg
.append('g')
.attr({
'class': "xAxis axis--x",
id: "xAxisGTOPbarChart"
});
var titleTxt = svg.append("text")
.attr({
x: basics.margin.left + 12,
y: 20,
'class': "title",
'text-anchor': "start"
})
// create scales with ranges
var xScale = d3.time.scale().range([0, basics.width]);
var yScale = d3.scale.linear().range([basics.height, 0]);
function TOPbarChart(
frt, colorChosen) {
// get the data
d3.csv(barDataCSV_Dly, function(rows) {
TOPbarData = rows.map(function(d) {
return {
"Fruit": d.Fruit,
"dt": parseDate(d.dt),
"amount": +d.amount
};
}).filter(function(row) {
if (row['Fruit'] == frt) {
return true;
}
});
// create domains for the scales
xScale.domain(d3.extent(TOPbarData, function(d) {
return d.dt;
}));
var amounts = TOPbarData.map(function(d) {
return d.amount;
});
var yMax = d3.max(amounts);
var yMin = d3.min(amounts);
var yMinFinal = 0;
if (yMin < 0) {
yMinFinal = yMin;
}
yScale.domain([yMinFinal, yMax]);
// introduce the bars
// var plot = d3.select("#svgPlotTOPbarChart")
var sel = plot.selectAll("rect")
.data(TOPbarData);
sel.enter()
.append("rect")
.attr({
x: function(d, i) {
return xScale(d.dt);
},
y: function(d) {
return yScale(d.amount);
},
width: (basics.width / TOPbarData.length - basics.barPaddingFine),
height: function(d) {
return basics.height - yScale(d.amount);
},
fill: colorChosen,
'class': "bar"
});
// this little function will create a small ripple affect during transition
var dlyRipple = function(d, i) {
return i * 100;
};
sel
.transition()
.duration(dlyRipple) //1000
.attr({
x: function(d, i) {
return xScale(d.dt);
},
y: function(d) {
return yScale(d.amount);
},
width: (basics.width / TOPbarData.length - basics.barPaddingFine),
height: function(d) {
return basics.height - yScale(d.amount);
},
fill: colorChosen
});
sel.exit().remove();
// add/transition y axis - with ticks and tick markers
var axisY = d3.svg.axis()
.orient('left')
.scale(yScale)
.tickFormat(d3.format("s")) // use abbreviations, e.g. 5M for 5 Million
.outerTickSize(0);
leftAxisGroup.transition().duration(1000).call(axisY);
// add/transition x axis - with ticks and tick markers
var axisX = d3.svg.axis()
.orient('bottom')
.scale(xScale);
bottomAxisGroup
.attr({
transform: 'translate(' + (basics.margin.left + ((basics.width / TOPbarData.length) / 2)) + ',' + (basics.margin.top + basics.height) + ')',
})
.transition().duration(1000).call(axisX.ticks(5));
titleTxt.text("Daily: last " + TOPbarData.length + " days");
// console.log(TOPbarData.length)
});
}
//
//
//
//
TOPbarChart(currentFruit, currentColr);
//
//
//
//
</script>
</body>
</html>
When all the data is positive everything is pretty much ok - but when some of the data is negative we can see the result in this plunker demo:
http://plnkr.co/edit/1hudJYkRq2MnuIlwxXZi?p=preview
How do I amend the code so that:
- the negative bars are shown?
- the base of the positive bars moves vertically up when negative numbers are included?
- the vertical movement is also included in the transition?
Above is more than 1 question but help on any would be appreciated.
The key is to play with the y and height attributes of the bars to position them correctly.
For y, change it to:
y: function(d) {
return yScale(Math.max(0, d.amount));
},
And for the height, change it to:
height: function(d) {
return Math.abs(yScale(d.amount) - yScale(0));
},
You can then style the negative bars to make them a different color.
Check the updated Plunkr - http://plnkr.co/edit/q7dQsPW0PiPuwFTy8gLN?p=preview
Edit:
For the coloring part, you can achieve it with a 1 liner if you want to reduce lines and want more simplicity.
Instead of:
fill: function(d) {
var col = colorChosen
if (d.amount < 0) {
col = "#FF0000";
}
return col;
},
});
You can do:
fill: function(d) {
return d.amount < 0 ? "#FF0000" : colorChosen;
},

D3.js v4 circle radius transition not working as expected

Using D3.js v4, I'm trying to update the radius of a circle on button click.
The problem is that, instead of smooth transitions between the radii the circle is redrawn (going from 'radius1' to 0 and only then to 'radius2') upon each update.
Here's the complete code:
https://jsfiddle.net/4r6hp9my/
Here's the circle update code snippet:
var circles = svg.selectAll('circle').data(dataset);
var enter = circles
.enter()
.append('circle')
.attrs({
cx: w/2,
cy: h/2,
fill: colorsScale,
r: function(d,i){
if(i == myCounter){
var x = rScale(d)
return x;
}
}
});
d3.select('#theButton')
.on('click',function(){
myCounter++
if(myCounter == dataset.length){
myCounter = 0;
};
updateData()
});
function updateData(){
circles
.merge(enter)
.transition()
.attr('r',function(d,i){
if(i == myCounter){
return rScale(d);
}
});
labels
.text(function(d,i){
if(i == myCounter){
return d;
}
});
};
As mentioned by echonax, the issue is you're creating multiple circles based on the dataset. To get the smooth transition, draw only one circle, and update the radius based on 'myCounter'. An example:
var dataset = [2184,2184,3460,2610,2610,2452,842,1349,2430];
var myCounter = 0;
//svg dimensions
var h = 200;
var w = 200;
var svg = d3.select('body')
.append('svg')
.attrs({
width: w,
height: h
})
.classed('middle',true);
//color mapping
var colorsScale = d3.scaleLinear()
.domain([d3.min(dataset),d3.max(dataset)])
.range(['#FFB832','#C61C6F']);
//radius mapping
var rScale = d3.scaleLinear().domain([0, d3.max(dataset)]).range([0,50])
//labels
var label = svg.append("text").attrs({
x: w/2,
y: 20
}).text(function(){ return dataset[myCounter] });
//draw the circles
var circle = svg.append('circle')
.attrs({
cx: w/2,
cy: h/2,
fill: function() { return colorsScale(dataset[myCounter]) },
r: function() { return rScale(dataset[myCounter]) }
});
//button click
d3.select('#theButton')
.on('click',function(){
updateData()
});
function updateData(){
myCounter++;
if ( myCounter > dataset.length - 1 ) myCounter = 0;
circle.transition().attr('r',function(){ return rScale(dataset[myCounter]) }).attr('fill', function() { return colorsScale(dataset[myCounter]) });
label.text(function(){ return dataset[myCounter] });
};
html, body{
height: 100%;
}
.middle{
margin: 100px auto;
}
#theButton{
position: absolute;
left:50px;
top:50px;
}
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<button id="theButton" type="button">Click Me!</button>
Based on your data, there are a couple of times that the circle won't change as the data is the same, but the transition should work when it does.

How to remove lines in between cartogram Maps in d3.js

I am new to d3.js. Trying to understand the cartogram example give in http://prag.ma/code/d3-cartogram/ . Here they gave example for USA map. I am trying the same for World Map to see how things works. My cartogram map has lines in between. My data has values for only few countries so I am setting the rest of the country's value as low or 0.
<!DOCTYPE html>
<html>
<head>
<title>Cartograms with d3 & TopoJSON</title>
<meta charset="utf-8">
<meta property="og:image" content="placeholder.png">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="lib/colorbrewer.js"></script>
<script src="lib/topojson.js"></script>
<script src="cartogram.js"></script>
<style type="text/css">
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.4em;
padding: 0;
margin: 0;
}
#container {
width: 960px;
margin: 20px auto;
}
h1 {
font-size: 200%;
margin: 0 0 15px 0;
}
h2 {
font-size: 160%;
margin: 0 0 10px 0;
}
p {
margin: 0 0 10px;
}
form, form > * {
margin: 0;
}
#status {
color: #999;
}
#map-container {
height: 700px;
text-align: center;
position: relative;
margin: 20px 0;
}
#map {
display: block;
position: absolute;
background: #fff;
width: 100%;
height: 100%;
margin: 0;
}
path.state {
stroke: #666;
stroke-width: .5;
}
path.state:hover {
stroke: #000;
}
form {
font-size: 120%;
}
select {
font-size: inherit;
}
#placeholder {
position: absolute;
z-index: -1;
display: block;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div id="container">
<h1>Cartograms with d3 & TopoJSON</h1>
<form>
<p>
<label>Scale by <select id="field"></select></label>
<span id="status"></span>
</p>
</form>
<div id="map-container">
<svg id="map"></svg>
</div>
</div>
<script>
var margin = 1,
width = 970 - margin,
height = 700 - margin;
if (!document.createElementNS) {
document.getElementsByTagName("form")[0].style.display = "none";
}
var percent = (function() {
var fmt = d3.format(".2f");
return function(n) { return fmt(n) + "%"; };
})(),
fields = [
{name: "(no scale)", id: "none"},
{name: "Internet_Users", id: "internet", key: "Internet_Users", format : percent},
{name: "GDP", id: "gdp", key: "GDP"},
{name: "Literacy_rates", id: "literacy", key: "Literacy_rates", format : percent},
{name: "female_male", id: "fm", key: "female_male"},
{name: "Population", id: "pop", key: "Population"},
],
fieldsById = d3.nest()
.key(function(d) { return d.id; })
.rollup(function(d) { return d[0]; })
.map(fields),
field = fields[0],
colors = colorbrewer.RdYlBu[3]
.reverse()
.map(function(rgb) { return d3.hsl(rgb); });
var body = d3.select("body"),
stat = d3.select("#status");
var fieldSelect = d3.select("#field")
.on("change", function(e) {
field = fields[this.selectedIndex];
location.hash = "#" + [field.id]
});
fieldSelect.selectAll("option")
.data(fields)
.enter()
.append("option")
.attr("value", function(d) { return d.id; })
.text(function(d) { return d.name; });
var map = d3.select("#map").attr("width", width + margin)
.attr("height", height + margin),
zoom = d3.behavior.zoom()
.translate([-38, 32])
.scale(.95)
.scaleExtent([0.5, 10.0])
.on("zoom", updateZoom),
layer = map.append("g")
.attr("id", "layer"),
states = layer.append("g")
.attr("id", "states")
.selectAll("path");
updateZoom();
function updateZoom() {
var scale = zoom.scale();
layer.attr("transform",
"translate(" + zoom.translate() + ") " +
"scale(" + [scale, scale] + ")");
}
var proj = d3.geo.mercator().scale(145).translate([width / 2, height / 1.5]),
topology,
geometries,
rawData,
dataById = {},
carto = d3.cartogram()
.projection(proj)
.properties(function(d) {
return dataById[d.id];
})
.value(function(d) {
return +d.properties[field];
});
window.onhashchange = function() {
parseHash();
};
d3.json("data/world_countries_topo.json", function(topo) {
topology = topo;
// console.log("T",topology)
geometries = topology.objects.countries.geometries;
d3.csv("data/parallel_score.csv", function(data) {
rawData = data;
dataById = d3.nest()
.key(function(d) { return d.Id; })
.rollup(function(d) { return d[0]; })
.map(data);
init();
});
});
function init() {
var features = carto.features(topology, geometries),
path = d3.geo.path()
.projection(proj);
states = states.data(features)
.enter()
.append("path")
.attr("class", "state")
.attr("id", function(d) {
return d.Id;
})
.attr("fill", "#000")
.attr("d", path);
states.append("title");
parseHash();
}
function reset() {
stat.text("");
body.classed("updating", false);
var features = carto.features(topology, geometries),
path = d3.geo.path()
.projection(proj);
states.data(features)
.transition()
.duration(750)
.ease("linear")
.attr("fill", "#fafafa")
.attr("d", path);
states.select("title")
.text(function(d) {
return d.Id;
});
}
function update() {
var start = Date.now();
body.classed("updating", true);
var key = field.key
var fmt = (typeof field.format === "function")
? field.format
: d3.format(field.format || ","),
value = function(d) {
if(d.properties == undefined){}
else {
return +d.properties[key];
}
},
values = states.data()
.map(value)
.filter(function(n) {
return !isNaN(n);
})
.sort(d3.ascending),
lo = values[0],
hi = values[values.length - 1];
console.log("L",lo)
console.log("H",hi)
var color = d3.scale.linear()
.range(colors)
.domain(lo < 0
? [lo, 0, hi]
: [lo, d3.mean(values), hi]);
// normalize the scale to positive numbers
var scale = d3.scale.linear()
.domain([lo, hi])
.range([1, 1000]);
// tell the cartogram to use the scaled values
carto.value(function(d) {
if( value(d) == undefined) {
return lo
}
else {
console.log("SCale", (value(d)))
return scale(value(d));
}
});
// generate the new features, pre-projected
var features = carto(topology, geometries).features;
// update the data
states.data(features)
.select("title")
/*.text(function(d) {
return [d.properties.Id, fmt(value(d))].join(": ");
});*/
states.transition()
.duration(750)
.ease("linear")
.attr("fill", function(d) {
if(d.properties == undefined){
return color(lo)
}
else {
return color(value(d));
}
})
.attr("d", carto.path);
var delta = (Date.now() - start) / 1000;
stat.text(["calculated in", delta.toFixed(1), "seconds"].join(" "));
body.classed("updating", false);
}
var deferredUpdate = (function() {
var timeout;
return function() {
var args = arguments;
clearTimeout(timeout);
stat.text("calculating...");
return timeout = setTimeout(function() {
update.apply(null, arguments);
}, 10);
};
})();
var hashish = d3.selectAll("a.hashish")
.datum(function() {
return this.href;
});
function parseHash() {
var parts = location.hash.substr(1).split("/"),
desiredFieldId = parts[0],
field = fieldsById[desiredFieldId] || fields[0];
fieldSelect.property("selectedIndex", fields.indexOf(field));
if (field.id === "none") {
reset();
} else {
deferredUpdate();
location.replace("#" + [field.id].join("/"));
hashish.attr("href", function(href) {
return href + location.hash;
});
}
}
</script>
</body>
</html>
Here is the link of my map: My Map
Can Someone please explain me why I am getting this line.
Thanks.
We had the same problem a year or so back and it is due to the arcs in the topojson file moving from 180 or 360 back to 0, basically wrapping at the ends of the map.
We needed to manually go into the map file and edit it using QGIS.
This resolved the issue of the lines.
You will also find if you are using the Cartogram code that the map of the world is far to detailed than you will need given you will be distorting the map anyway. If you are generating the cartogram in real time then you will face delays in the code.
You should probably reduce the complexity of the map too.
Here is an example of the JSON we used to create real time hexagonal cartograms in the browser.
Simplified World Map JSON

how to change the color after filtering stacked bar chart in dc.js

I tried for change the color of bar after crossfilter,it works crossfilter but i want to change the coloe of bar which is filterd.i tried for below code.
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
<head>
<style>
div{
background:#faebcc;
}
</style>
<link href="{% static 'dc/css/dc.css' %}" rel="stylesheet" media="screen">
<link href="{% static 'dc/css/example-styles.css' %}" rel="stylesheet" media="screen">
</head>
<body>
<div class="container">
<div class="col-lg-6">
<h3>Map wise selection of US</h3>
<div id="us-chart" STYLE="width: 100%;"></div>
</div>
<div class=col-lg-6>
<h3>Top 10 Counties</h3>
<div id="const"></div>
</div>
</div>
<div class="container">
<h2>Age wise population of US</h2>
<div id="chart" class="col-lg-8"></div>
</div>
<div class="container" style="margin-top: 25px" class="col-lg-12">
<div class=col-lg-12>
<h3>States of US</h3>
<div id="chart-row-Population_Density">
</div>
</div>
</div>
<!-- <div class="container" class="col-lg-12">
<div id="industry-chart" ></div>
</div>-->
<div class="container" class="col-lg-12">
<div id="county_linet" ></div>
</div>
<!--<div class="container" class="col-lg-8">
<div id="round-chart" ></div>
</div>-->
<script type="text/javascript" src="{% static 'dc/js/d3.js' %}"></script>
<script type="text/javascript" src="{% static 'dc/js/crossfilter.js' %}"></script>
<script type="text/javascript" src="{% static 'dc/js/dc.js' %}"></script>
<script type="text/javascript" src="{% static 'dc/js/bootstrap.min.js' %}"></script>
<script type="text/javascript" src="{% static 'dc/js/d3.js' %}"></script>
<script type="text/javascript" src="{% static 'dc/js/index.js' %}"></script>
<script type="text/javascript">
var numberFormat = d3.format(".2f");
var stacked = dc.barChart("#chart");
var constRowChart=dc.rowChart("#const");
var usChart = dc.geoChoroplethChart("#us-chart");
var industryChart = dc.bubbleChart("#industry-chart");
var roundChart = dc.bubbleChart("#round-chart");
var barchart= dc.barChart("#chart-row-Population_Density");
var chart=dc.pieChart("#p");
var lineChart = dc.lineChart("#county_linet");
d3.csv("{% static 'healthdata1.csv' %}", function(error, csv) {
function resize() {
// adjust things when the window size changes
width = parseInt(d3.select('#us-chart').style('width'));
width = width - margin.left - margin.right;
height = width * mapRatio;
// update projection
projection
.translate([width / 2, height / 2])
.scale(width);
// resize the map container
usChart
.width(width)
.height(height);
// resize the map
usChart.selectAll('.state').attr('d', path);
}
var dateFormat = d3.time.format("%Y");
var numberFormat = d3.format(",f");
var data = crossfilter(csv);
var barTip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
return "<span style='color: #f0027f'>" + d.data.key + "</span> : " + d.y.toFixed(0);
});
var states = data.dimension(function (d) {
return d["State_Id"];
});
var stateRaisedSum = states.group().reduceSum(function (d) {
return d["Population"];
});
var industries = data.dimension(function (d) {
return d["County_Name"];
});
var inds= industries.group().reduceSum(function (d){
return d["poverty"];
});
var stateDim=data.dimension(function (d){
return d["State_Name"];
});
var density = data.dimension(function (d) {
return d["County_Name"];
});
var const_total= density.group().reduceSum(function (d){
return d["Population"];
});
var Population_tot= stateDim.group().reduceSum(function (d){
return d["Population"];
});
var statsByIndustries = industries.group().reduce(
function (p, v) {
p.amountRaised += +v["Population_Density"];
p.deals += +v["Poverty"];
return p;
},
function (p, v) {
p.amountRaised -= +v["Population_Density"];
// if (p.amountRaised < 0.001) p.amountRaised = 0; // do some clean up
p.deals -= +v["Poverty"];
return p;
},
function () {
return {amountRaised: 0, deals: 0}
}
);
var rounds = data.dimension(function (d) {
return d["County_Name"];
});
var statsByRounds = rounds.group().reduce(
function (p, v) {
p.amountRaised += +v["Poverty"];
p.deals += +v["Population"];
return p;
},
function (p, v) {
p.amountRaised -= +v["Poverty"];
//if (p.amountRaised < 0.001) p.amountRaised = 0; // do some clean up
p.deals -= +v["Population"];
return p;
},
function () {
return {amountRaised: 0, deals: 0}
}
);
var margin = {top: 10, left: 10, bottom: 10, right: 10}
, width = parseInt(d3.select('#us-chart').style('width'))
, width = width - margin.left - margin.right
, mapRatio = .6
, height = width * mapRatio;
var projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
d3.select(window).on('resize', resize);
d3.json("{% static 'us-states.json' %}", function(error, statesJson) {
usChart.width(width)
.height(height)
.dimension(states)
.projection(projection)
.group(stateRaisedSum)
.colors(d3.scale.quantize().range(["#E2F2FF", "#C4E4FF", "#9ED2FF", "#81C5FF", "#6BBAFF", "#51AEFF", "#36A2FF", "#1E96FF", "#0089FF", "#0061B5"]))
.colorDomain([0, 200])
.colorCalculator(function (d) { return d ? usChart.colors()(d) : '#ccc'; })
.overlayGeoJson(statesJson.features, "state", function (d) {
return d.properties.name;
})
.title(function (d) {
return "State: " + d.key + "\nTotal Population: " + d.value;
});
industryChart.width(1100)
.height(400)
.margins({top: 10, right: 50, bottom: 30, left: 60})
.dimension(industries)
.group(statsByIndustries)
.colors(d3.scale.category10())
.keyAccessor(function (p) {
return p.value.amountRaised;
})
.valueAccessor(function (p) {
return p.value.deals;
})
.radiusValueAccessor(function (p) {
return p.value.amountRaised;
})
.x(d3.scale.linear().domain([0, 5000]))
// .y(d3.scale.linear().domain([0.10, 500]))
.r(d3.scale.linear().domain([0, 50000]))
.minRadiusWithLabel(10)
.elasticY(true)
.yAxisPadding(100)
.elasticX(true)
.xAxisPadding(200)
.maxBubbleRelativeSize(0.08)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true)
.renderLabel(true)
.renderTitle(true)
.title(function (p) {
return p.key
+ "\n"
+ "Population Density: " + numberFormat(p.value.amountRaised) + "\n"
+ "Percentage of Poverty: " + numberFormat(p.value.deals);
});
industryChart.yAxis().tickFormat(function (s) {
return s + " deals";
});
industryChart.xAxis().tickFormat(function (s) {
return s + "M";
});
barchart.width(1100)
.height(350)
.margins({ top: 10, left: 50, right: 10, bottom: 80 })
.transitionDuration(750)
.xAxisLabel('States of US')
.yAxisLabel('Population')
.dimension(stateDim)
.group(Population_tot)
.centerBar(false)
.brushOn(false)
.title(function (d) {
""
})
.gap(5)
.elasticY(true)
.colors(['#00FF00'])
.xUnits(dc.units.ordinal)
.x(d3.scale.ordinal())
.y(d3.scale.linear().domain([0, 600]))
.renderHorizontalGridLines(false)
.yAxis().tickFormat(d3.format("s"));
barchart.renderlet(function (chart) {
chart.selectAll("g.x text").attr('dx', '-30').attr('dy', '-7').attr('transform', "rotate(-60)");
});
var eventsByDate = stateDim.group().reduce(
function (p, v) {
// ++p.Count;
p.Age_19_Under += +v["Age_19_Under"];
p.Age_19_64 += +v["Age_19_64"];
p.Age_65_84 += +v["Age_65_84"];
p.Age_85_and_Over += +v["Age_85_and_Over"];
return p;
},
function (p, v) {
// --p.Count;
p.Age_19_Under -= -v["Age_19_Under"];
p.Age_19_64 -= -v["Age_19_64"];
p.Age_65_84 -= -v["Age_65_84"];
p.Age_85_and_Over += -v["Age_85_and_Over"];
return p;
},
function () {
return {
// Count: 0,
Age_19_Under: 0,
Age_19_64: 0,
Age_65_84: 0,
Age_85_and_Over:0
};
}
);
var colorRenderlet = function (chart) {
chart.selectAll("rect.bar")
.on("click", function (d) {
function setAttr(selection, keyName) {
selection.style("fill", function (d) {
if (d[keyName] == "Age_19_Under") return "#63D3FF";
else if (d[keyName] == "Age_19_64") return "#FF548F";
else if (d[keyName] == "Age_65_84") return "#9061C2";
else if (d[keyName] == "Age_85_and_Over") return "#00FF00";
});
}
setAttr(_chart.selectAll("g.stack").selectAll("rect.bar"), "layer");
setAttr(_chart.selectAll("g.dc-legend-item").selectAll("rect"), "name")
});
};
stacked
.margins({top: 50, right: 20, left: 50, bottom: 50})
.width(1100)
.height(350)
.gap(5)
.dimension(states)
.group(eventsByDate,"Age(Under 19)")
.valueAccessor(function (d) {
return d.value.Age_19_Under;
})
.stack(eventsByDate, "Age(19-64)", function (d) {
return d.value.Age_19_64;
})
.stack(eventsByDate, "Age(65-84)", function (d) {
return d.value.Age_65_84;
})
.stack(eventsByDate, "Age(85 and Over)", function (d) {
return d.value.Age_85_and_Over;
})
.y(d3.scale.linear().domain([0, 600]))
.xUnits(dc.units.ordinal)
.x(d3.scale.ordinal())
.centerBar(true)
.elasticY(true)
.brushOn(false)
.transitionDuration(750)
.renderlet(colorRenderlet)
.legend(dc.legend().x(100).y(0).itemHeight(13).gap(5));
stacked.renderlet(function (chart) {
chart.selectAll("g.x text").attr('dx', '-30').attr('dy', '-7').attr('transform', "rotate(-60)");
});
roundChart.width(1100)
.height(400)
.margins({top: 10, right: 50, bottom: 30, left: 60})
.dimension(rounds)
.group(statsByRounds)
.colors(d3.scale.category10())
.keyAccessor(function (p) {
return p.value.amountRaised;
})
.valueAccessor(function (p) {
return p.value.deals;
})
.radiusValueAccessor(function (p) {
return p.value.amountRaised;
})
.x(d3.scale.linear().domain([0, 5000]))
.r(d3.scale.linear().domain([0, 50000]))
.minRadiusWithLabel(15)
.elasticY(true)
.yAxisPadding(150)
.elasticX(true)
.xAxisPadding(300)
.maxBubbleRelativeSize(0.07)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true)
.renderLabel(true)
.renderTitle(true)
.title(function(p){
return p.key
+ "\n"
+ "Amount Raised: " + numberFormat(p.value.amountRaised) + "M\n"
+ "Number of Deals: " + numberFormat(p.value.deals);
});
roundChart.yAxis().tickFormat(function (s) {
return s + " deals";
});
roundChart.xAxis().tickFormat(function (s) {
return s + "M";
});
constRowChart.width(300)
.height(300)
.margins({top: 20, left: 120, right: 10, bottom: 20})
.transitionDuration(750)
.dimension(density)
.group(const_total)
.renderLabel(true)
.gap(1)
.title(function (d) {
return "";
})
.elasticX(true)
.colors(d3.scale.category20c())
.xAxis().ticks(3).tickFormat(function (s) {
return s;
});
constRowChart.data(function (group) {
return group.top(10);
});
lineChart.width(860)
.height(350)
.margins({top: 10, right: 10, bottom: 90, left: 50})
.dimension(industries)
.group(inds)
.xAxisLabel('States of US')
.yAxisLabel('Poverty in US')
.transitionDuration(750)
.elasticY(true)
.brushOn(false)
.colors(['#00FFFF'])
.xUnits(dc.units.ordinal)
.x(d3.scale.ordinal())
.y(d3.scale.linear().domain([100, 1600]))
.renderHorizontalGridLines(false)
//.yAxis().tickFormat(d3.format("s"))
/* .valueAccessor(function (d) {
return d.value;
})*/
.title(function(d){
return " "+ d.key +" : "+d.value.toFixed(2);
})
//.x(d3.scale.linear().domain([4, 27]))
.xAxis();
lineChart.renderlet(function (chart) {
chart.selectAll("g.x text").attr('dx', '-30').attr('dy', '-7').attr('transform', "rotate(-60)");
});
dc.renderAll();
d3.selectAll(".bar").call(barTip);
d3.selectAll(".bar").on('mouseover', barTip.show)
.on('mouseout', barTip.hide);
});
});
</script>
</body>
{% endblock %}
So what can i do for this?
This is starting to be a lot of code (congrats!), and I'm not quite sure what the question is. If you're asking what colors the filtered-out bars, I think you'll find your answer in the CSS.
If you're wondering why a renderlet isn't working, try setting a breakpoint in the renderlet and seeing whether the selectAll is returning the selection you expect.

Categories