Skip to content

Instantly share code, notes, and snippets.

@cgroll
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgroll/a0baaf92251afb2d16c4 to your computer and use it in GitHub Desktop.
Save cgroll/a0baaf92251afb2d16c4 to your computer and use it in GitHub Desktop.
Multi-line block with missing values

This is a d3 chart representing multiple time series paths, where missing values are breaking the paths.

You can view a rendered version of this gist at bl.ocks.org.

function mlineChart() {
var outerWidth = 960;
var outerHeight = 500;
var y = d3.scale.log();
var yAxisLabel = "";
function mlineChartInner(selection) {
selection.each(function(data){
// define margins
var margin = {top: 20, right: 80, bottom: 30, left: 150};
// graphics size without axis
var width = outerWidth - margin.left - margin.right;
var height = outerHeight - margin.top - margin.bottom;
var svg = d3.select(this).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 + ")");
var x = d3.time.scale()
.range([0, width]);
y = y.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")
.ticks(5);
var parseDate = d3.time.format("%Y-%m-%d").parse;
var line = d3.svg.line()
.defined(function(d) { return !isNaN(d.gdp); })
.interpolate("basis")
.x(function(d) { return x(d.idx); })
.y(function(d) { return y(d.gdp); });
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "idx"; }));
data.forEach(function(d) {
d.idx = parseDate(d.idx);
});
var tseries = color.domain().map(function(name) {
countryData = data.map(function(d) {
return {idx: d.idx, gdp: +d[name]};
})
return {name: name,
values: countryData
};
});
x.domain(d3.extent(data, function(d) { return d.idx; }));
y.domain([
d3.min(tseries, function(c) { return d3.min(c.values, function(v) { return v.gdp; }); }),
d3.max(tseries, function(c) { return d3.max(c.values, function(v) { return v.gdp; }); })
]);
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(yAxisLabel);
var gdp = svg.selectAll(".gdp")
.data(tseries)
.enter().append("g")
.attr("class", "gdp");
gdp.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
})
}
mlineChartInner.width = function(value) {
if (!arguments.length) return outerWidth;
outerWidth = value;
return mlineChartInner;
};
mlineChartInner.height = function(value) {
if (!arguments.length) return outerHeight;
outerHeight = value;
return mlineChartInner;
};
mlineChartInner.y = function(value) {
if (!arguments.length) return y;
y = value;
return mlineChartInner;
};
mlineChartInner.yAxisLabel = function(value) {
if (!arguments.length) return yAxisLabel;
yAxisLabel = value;
return mlineChartInner;
};
return mlineChartInner;
}
idx BR DE US
1962-12-31 229.30286512437993 NA 3279.847682222698
1963-12-31 249.81937267525998 NA 3409.2535616487735
1964-12-31 270.5971235206717 NA 3609.9894994132137
1965-12-31 271.1335322289991 NA 3879.634758987967
1966-12-31 271.9748253456187 NA 4199.058901057487
1967-12-31 310.83529938661604 NA 4379.433646211674
1968-12-31 370.04114717388 NA 4750.4360922898695
1969-12-31 412.00850429246634 NA 5080.319198124847
1970-12-31 441.3565057674224 NA 5280.974624363576
1971-12-31 499.9595643842608 NA 5690.311399081065
1972-12-31 589.2271929448656 3599.9227119065013 6329.125786229267
1973-12-31 748.8759295108167 4679.567597052115 7340.426065533109
1974-12-31 970.3270684879265 5799.341880719011 8037.949676827828
1975-12-31 1169.5536454723958 6730.185541715934 8600.61146075292
1976-12-31 1348.8458554176366 7140.066028103141 9079.04617203539
1977-12-31 1480.1905207591387 7680.292400333419 9698.53046420326
1978-12-31 1659.7854890643039 8879.836986345166 10890.159271647331
1979-12-31 1949.7020741086164 11069.431092647033 12438.123052145473
1980-12-31 2180.597449054458 13021.026407704185 13619.920660882619
1981-12-31 2079.2795805880287 12559.540641721003 14559.383186084424
1982-12-31 2001.4421874323805 11138.550463383071 14269.772235170483
1983-12-31 1709.856363380952 10029.733936048005 14818.664041979862
1984-12-31 1620.7081454525671 9889.928878797436 16390.8943166959
1985-12-31 1569.3311142468945 9850.015022771056 17710.337169468505
1986-12-31 1790.6719328592344 11249.34566555451 19490.933269800964
1987-12-31 2038.8167549728864 14250.16356675534 21660.723087427028
1988-12-31 2250.683489101661 18640.104070736023 23579.149889706885
1989-12-31 2749.303390614975 19778.999509391182 24129.881087096743
1990-12-31 2699.480477119376 21330.140841059732 24528.63498868993
1991-12-31 2869.8214516711114 22910.973069442614 24720.624693604812
1992-12-31 2778.438816523024 25848.499966560907 26220.950943270618
1993-12-31 2741.0072737850155 25980.081030464215 27081.057182442157
1994-12-31 3039.02985807059 27519.02537250676 28280.415146738338
1995-12-31 3731.316086414115 29549.94418495954 29490.817825154543
1996-12-31 4460.847389920484 30880.788261334674 30601.65197112317
1997-12-31 5049.685084457657 30161.190700728657 31429.771448183077
1998-12-31 4870.6934805001565 27948.92519939022 31941.13411108418
1999-12-31 4129.39658226453 26839.036449653515 33669.769780494426
2000-12-31 3858.475965422518 26170.00710763633 35739.586487263776
2001-12-31 3290.0748813152604 24749.962278555795 36448.153495558916
2002-12-31 3051.278096249819 23679.626748199647 37218.8427269532
2003-12-31 2949.1091800149575 26210.0781319859 39900.91430544001
2004-12-31 3308.7609276426247 31709.80579699382 43649.82282887204
2005-12-31 3958.5005089530937 35881.15358401915 46220.00791960031
2006-12-31 4799.546579029736 38379.766904028154 47339.40891836694
2007-12-31 6097.848850073046 40729.41756576593 48690.56814902777
2008-12-31 7478.301064611335 43909.92820788725 49681.16808555389
2009-12-31 8139.116785302867 43810.411824587085 48300.71881589496
2010-12-31 9520.884317818694 44780.269029070514 49111.11332148076
2011-12-31 10698.096717138249 46409.62596787164 50350.82969561104
2012-12-31 11638.478402286351 46701.88913672164 51921.71495220139
2013-12-31 11689.673103149926 47269.584174007585 53470.78316792905
using TimeData
using WorldBankDataTd
## download data
dataRaw = WorldBankDataTd.wdi(["NY.GNP.PCAP.CD"],
["BR", "US", "DE"])
## convert to wide format
df = convert(DataFrame, dataRaw)
dfWide = unstack(df, :idx, :iso2c, symbol("NY.GNP.PCAP.CD"))
data = Timenum(dfWide[:, 2:end], dfWide[:, 1])
## randomize entries, as I am not allowed to redistribute World Bank
## data
function randomizeSorted(da::DataArray)
## preserving time rend
## get mean change
mnChg = mean(dropna(diff(da)))
## add half of mean change
nObs = size(da, 1)
return da + randn(nObs).*(sqrt(mnChg/2))
end
function randomize(da::DataArray)
## get variation
dataVar = var(dropna(diff(da)))
## add quarter of variance
nObs = size(da, 1)
return da + randn(nObs).*(sqrt(dataVar)/2)
end
## apply randomization
nObs = size(data, 1)
randomizedData = map(x -> x .+ randn(nObs), eachcol(data))
## write data to disk
writeTimedata("dummyData.csv", randomizedData)
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 16px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
<!-- display: none; -->
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.grid .tick {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
</style>
<body>
<!-- <script src="../d3/d3.min.js" charset="utf-8"> -->
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8">
</script>
<script src="assembly_code.js"></script>
<script>
var actualChart = mlineChart()
.width(900)
.y(d3.scale.linear())
.yAxisLabel("gdp in $");
d3.csv("dummyData.csv", function(inputData) {
d3.select("body")
.datum(inputData)
.call(actualChart)
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment