Skip to content

Instantly share code, notes, and snippets.

@paulgarias
Last active March 19, 2017 23:40
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 paulgarias/7b1f6be1cc403d4e04f01e6a4adac323 to your computer and use it in GitHub Desktop.
Save paulgarias/7b1f6be1cc403d4e04f01e6a4adac323 to your computer and use it in GitHub Desktop.
Stacked bars with divergent layout
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300|Source+Sans+Pro:300,400');
/* Eric Meyer's Reset CSS v2.0 - http://cssreset.com */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
/* Solarized Palette - http://ethanschoonover.com/solarized ---------
lightgray : #819090;
gray : #708284;
mediumgray : #536870;
darkgray : #475B62;
darkblue : #0A2933;
darkerblue : #042029;
paleryellow : #FCF4DC;
paleyellow : #EAE3CB;
yellow : #A57706;
orange : #BD3613;
red : #D11C24;
pink : #C61C6F;
purple : #595AB7;
blue : #2176C7;
cyan : #259286;
green : #738A05; */
body {
font-family: "Source Sans Pro", sans-serif;
font-weight: 300;
font-size: 1.2em;
line-height: 1.2em;
background: #FFFFFF;
color: #000000;
}
strong {
font-weight: 400;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Open Sans', sans-serif;
font-weight: 300;
color: #000000;
font-size: 1.75em;
margin-bottom: .4em;
}
p {
margin-bottom: .5em;
}
.container {
width: 80%;
max-width: 1200px;
margin: 0 auto;
margin-top:10px;
}
@media all and (max-width: 500px) {
h2 {
padding-left: 10px;
text-align: center;
}
.container {
width: 100%;
}
}
#graphic {
margin: 0 auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3 Graphic</title>
<link rel="stylesheet" href ="base.css">
<link rel="stylesheet" href ="style.css">
<head>
<body>
<div class="container">
<h2 style="text-align:left"> Stock portfolio unrealized gains/losses </h2>
<div id="chart"></div>
</div>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="script.js"></script>
</body>
</html>
var margin = { top : 40, right:40, bottom:80, left:80 }
var height = 400 -margin.top - margin.bottom,
width = 800 -margin.left -margin.right,
barWidth = 50,
barOffset = 5;
//var parseDate = d3.time.format("%Y-%m-%d").parse
//var parseDate = d3.time.format("%m-%d").parse
var parseDate = d3.timeFormat("%m-%d")
var myChart = d3.select('#chart').append('svg')
.style('background','#FFF')
// To provide the right dimensions of the svg element, recall that we have to add back the
// top, left, bottom and right margins to the svg. These style attributes are then grouped
// together (append('g') command) and translated the left (x) and top (y) margins.
.attr('width',width+margin.left+margin.right)
.attr('height',height+margin.top+margin.bottom)
prev=900
prevl = 900
var colors = d3.scaleLinear()
.domain([-prev/4,-1, 0, 1,prev/2])
.range(['#EBBAB9','#CC2936','#000000','#b5ffe1','#002b58'])
var tooltip = d3.select('body').append('div')
.style('position','absolute')
.style('padding','0 5px')
.style('background','grey')
.style('color','white')
d3.json("stocks.json", function(data) {
// We need to extract the dates in order to build the xAxis
datelist = []
for (key in data) {
datelist.push(new Date(data[key][key][0].date+"T12:00:00-05:00"))
}
var yScale = d3.scaleLinear()
.domain([0,prev])
.range([0,height/2]);
var vGuideScale = d3.scaleLinear()
.domain([-prevl, prev])
.range([height,0])
var vAxis = d3.axisLeft()
.scale(vGuideScale)
.ticks(10)
var vGuide = d3.select('svg').append('g')
vAxis(vGuide)
vGuide.attr('transform','translate('+(margin.left-5)+','+margin.top+')')
vGuide.attr("font-size","15")
vGuide.selectAll('path')
.style( {fill : 'none', stroke:'#000'})
vGuide.selectAll('line')
.style( {fill : 'none', stroke:'#000'})
var xS = d3.scaleBand().range([0,width])
.domain(datelist.map(function (d) {return parseDate(d)}))
.padding([0.05]);
var xScale = d3.scaleBand()
.domain(d3.range(0,datelist.length))
.range([0,width])
.padding([0.05]);
var xAxis = d3.axisBottom()
.scale(xS)
myChart.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+(margin.left)+"," + (height+margin.top+5) + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-0.6em")
.attr("dy", "0.20em")
.attr("transform", "rotate(-70)" )
.attr("font-size","15")
console.log(data)
function getData(dat) {
listing = []
for (kk in dat) {
console.log(kk)
for (key in dat[kk][kk]){
if(key!=0){
listing.push({day: kk, offset: dat[kk][kk][key].offset, name: dat[kk][kk][key].name, value: dat[kk][kk][key].value})
}
}
}
return listing;
}
console.log(getData(data))
var rects = d3.select('svg').append('g').selectAll('rect')
.data(getData(data)).enter()
.append('rect')
.attr("width",xScale.bandwidth)
.attr("height", function(d) {
return Math.abs(yScale(d.value));
})
.attr("x", function(d,i) {
return xScale(d.day);
})
.attr('y', function(d,i) {
if (d.value >= 0){
return height/2.0-Math.abs(yScale(d.value))-yScale(d.offset) ;
} else {
return height/2.0+yScale(d.offset);
}
})
.style("opacity",0.0)
.style('fill',function(d,i) {
return colors(d.value);
})
.attr('transform','translate('+margin.left+','+(margin.top)+')')
.on('mouseover',function(d){
tempColor = this.style.fill;
d3.select(this)
.style('opacity',0.5)
.style('fill','yellow')
tooltip.transition()
.style('opacity',0.8)
.duration(10)
tooltip.html(Math.round(1000*d.value)/1000+" <br> "+d.name)
.style('left',(d3.event.pageX + 15) + 'px')
.style('top',(d3.event.pageY- 30) + 'px')
})
.on('mouseout', function(d) {
tooltip.transition()
.style('opacity',0.0)
.style('pointer-events','none')
d3.select(this)
.style("opacity",1.0)
.style("fill", tempColor)
})
rects.transition()
.style("opacity",1.0)
.duration(1000)
.delay(function (d,i) {
return d.day*400;
})
})
[
{"0":
[
{"date":"2017-03-03"},
{"name":"AAPL", "value":220.89999, "offset":0.0},
{"name":"FB", "value":169.619978, "offset":220.89999},
{"name":"BAC", "value":129.500025, "offset":390.519968},
{"name":"MMM", "value":129.09998, "offset":520.019993},
{"name":"GM", "value":117.18, "offset":649.119973},
{"name":"PG", "value":40.05, "offset":766.299973},
{"name":"LUV", "value":33.120016, "offset":806.349973},
{"name":"SAN", "value":7.8, "offset":839.469989},
{"name":"AAL", "value":-7.6, "offset":0.0},
{"name":"DPZ", "value":-9.360084, "offset":7.6},
{"name":"DAL", "value":-23.759982, "offset":16.960084},
{"name":"NVDA", "value":-32.7, "offset":40.720066},
{"name":"F", "value":-65.78, "offset":73.420066},
{"name":"M", "value":-228.8745, "offset":139.200066}
]
},
{"1":
[
{"date":"2017-03-06"},
{"name":"AAPL", "value":216.49996, "offset":0.0},
{"name":"FB", "value":172.369978, "offset":216.49996},
{"name":"MMM", "value":124.99994, "offset":388.869938},
{"name":"BAC", "value":124.75, "offset":513.869878},
{"name":"GM", "value":103.74, "offset":638.619878},
{"name":"PG", "value":39.400015, "offset":742.359878},
{"name":"LUV", "value":12.320016, "offset":781.759893},
{"name":"SAN", "value":3.0, "offset":794.079909},
{"name":"DPZ", "value":-11.160012, "offset":0.0},
{"name":"AAL", "value":-37.79998, "offset":11.160012},
{"name":"NVDA", "value":-44.10003, "offset":48.959992},
{"name":"DAL", "value":-46.800036, "offset":93.060022},
{"name":"F", "value":-84.37, "offset":139.860058},
{"name":"M", "value":-256.18767471, "offset":224.230058}
]
},
{"2":
[
{"date":"2017-03-07"},
{"name":"AAPL", "value":218.30004, "offset":0.0},
{"name":"FB", "value":171.050033, "offset":218.30004},
{"name":"MMM", "value":126.89996, "offset":389.350073},
{"name":"BAC", "value":123.749975, "offset":516.250033},
{"name":"GM", "value":87.36, "offset":640.000008},
{"name":"PG", "value":39.000005, "offset":727.360008},
{"name":"SAN", "value":3.0, "offset":766.360013},
{"name":"LUV", "value":0.640032, "offset":769.360013},
{"name":"DPZ", "value":-6.239964, "offset":0.0},
{"name":"NVDA", "value":-28.05003, "offset":6.239964},
{"name":"AAL", "value":-47.2, "offset":34.289994},
{"name":"DAL", "value":-68.580018, "offset":81.489994},
{"name":"F", "value":-92.95, "offset":150.070012},
{"name":"M", "value":-253.15292529, "offset":243.020012}
]
},
{"3":
[
{"date":"2017-03-08"},
{"name":"AAPL", "value":213.1, "offset":0.0},
{"name":"FB", "value":175.670011, "offset":213.1},
{"name":"MMM", "value":131.09995, "offset":388.770011},
{"name":"BAC", "value":125.0, "offset":519.869961},
{"name":"GM", "value":76.86, "offset":644.869961},
{"name":"PG", "value":38.249995, "offset":721.729961},
{"name":"SAN", "value":5.4, "offset":759.979956},
{"name":"LUV", "value":-1.76, "offset":0.0},
{"name":"DPZ", "value":-17.519988, "offset":1.76},
{"name":"NVDA", "value":-30.75003, "offset":19.279988},
{"name":"AAL", "value":-46.20002, "offset":50.030018},
{"name":"DAL", "value":-68.040036, "offset":96.230038},
{"name":"F", "value":-82.94, "offset":164.270074},
{"name":"M", "value":-228.8745, "offset":247.210074}
]
},
{"4":
[
{"date":"2017-03-09"},
{"name":"AAPL", "value":209.89993, "offset":0.0},
{"name":"FB", "value":181.390055, "offset":209.89993},
{"name":"MMM", "value":134.99994, "offset":391.289985},
{"name":"BAC", "value":127.25, "offset":526.289925},
{"name":"GM", "value":58.380084, "offset":653.539925},
{"name":"PG", "value":39.24998, "offset":711.920009},
{"name":"SAN", "value":22.2, "offset":751.169989},
{"name":"LUV", "value":-6.879984, "offset":0.0},
{"name":"NVDA", "value":-31.049985, "offset":6.879984},
{"name":"DPZ", "value":-61.559976, "offset":37.929969},
{"name":"DAL", "value":-75.6, "offset":99.489945},
{"name":"AAL", "value":-77.39996, "offset":175.089945},
{"name":"F", "value":-87.23, "offset":252.489905},
{"name":"M", "value":-234.94407471, "offset":339.719905}
]
},
{"5":
[
{"date":"2017-03-10"},
{"name":"AAPL", "value":214.49999, "offset":0.0},
{"name":"FB", "value":187.439923, "offset":214.49999},
{"name":"MMM", "value":148.10007, "offset":401.939913},
{"name":"BAC", "value":126.249975, "offset":550.039983},
{"name":"GM", "value":58.380084, "offset":676.289958},
{"name":"PG", "value":42.9, "offset":734.670042},
{"name":"SAN", "value":33.0, "offset":777.570042},
{"name":"LUV", "value":-14.559984, "offset":0.0},
{"name":"NVDA", "value":-22.349955, "offset":14.559984},
{"name":"DPZ", "value":-37.080048, "offset":36.909939},
{"name":"DAL", "value":-63.72, "offset":73.989987},
{"name":"AAL", "value":-65.99996, "offset":137.709987},
{"name":"F", "value":-82.94, "offset":203.709947},
{"name":"M", "value":-229.8861, "offset":286.649947}
]
},
{"6":
[
{"date":"2017-03-13"},
{"name":"AAPL", "value":215.09997, "offset":0.0},
{"name":"FB", "value":196.350066, "offset":215.09997},
{"name":"MMM", "value":151.20004, "offset":411.450036},
{"name":"BAC", "value":125.999975, "offset":562.650076},
{"name":"GM", "value":60.059958, "offset":688.650051},
{"name":"PG", "value":44.09999, "offset":748.710009},
{"name":"SAN", "value":25.8, "offset":792.809999},
{"name":"NVDA", "value":18.59997, "offset":818.609999},
{"name":"DPZ", "value":-36.360084, "offset":0.0},
{"name":"LUV", "value":-36.799968, "offset":36.360084},
{"name":"DAL", "value":-73.800036, "offset":73.160052},
{"name":"F", "value":-81.51, "offset":146.960088},
{"name":"AAL", "value":-96.60002, "offset":228.470088},
{"name":"M", "value":-250.8768, "offset":325.070108}
]
},
{"7":
[
{"date":"2017-03-14"},
{"name":"AAPL", "value":213.00005, "offset":0.0},
{"name":"FB", "value":193.270077, "offset":213.00005},
{"name":"MMM", "value":139.30002, "offset":406.270127},
{"name":"BAC", "value":126.5, "offset":545.570147},
{"name":"GM", "value":63.839958, "offset":672.070147},
{"name":"PG", "value":42.55, "offset":735.910105},
{"name":"NVDA", "value":17.549985, "offset":778.460105},
{"name":"SAN", "value":12.6, "offset":796.01009},
{"name":"LUV", "value":-62.559984, "offset":0.0},
{"name":"DPZ", "value":-73.800024, "offset":62.559984},
{"name":"F", "value":-80.08, "offset":136.360008},
{"name":"DAL", "value":-93.060018, "offset":216.440008},
{"name":"AAL", "value":-119.80002, "offset":309.500026},
{"name":"M", "value":-249.61227471, "offset":429.300046}
]
},
{"8":
[
{"date":"2017-03-15"},
{"name":"AAPL", "value":227.70007, "offset":0.0},
{"name":"FB", "value":197.670011, "offset":227.70007},
{"name":"MMM", "value":147.99997, "offset":425.370081},
{"name":"BAC", "value":123.0, "offset":573.370051},
{"name":"GM", "value":69.3, "offset":696.370051},
{"name":"PG", "value":44.55001, "offset":765.670051},
{"name":"NVDA", "value":29.100045, "offset":810.220061},
{"name":"SAN", "value":22.2, "offset":839.320106},
{"name":"LUV", "value":-39.999984, "offset":0.0},
{"name":"DPZ", "value":-42.599952, "offset":39.999984},
{"name":"F", "value":-65.78, "offset":82.599936},
{"name":"DAL", "value":-76.680018, "offset":148.379936},
{"name":"AAL", "value":-102.2, "offset":225.059954},
{"name":"M", "value":-265.545, "offset":327.259954}
]
},
{"9":
[
{"date":"2017-03-16"},
{"name":"AAPL", "value":230.00002, "offset":0.0},
{"name":"FB", "value":200.640055, "offset":230.00002},
{"name":"MMM", "value":139.09998, "offset":430.640075},
{"name":"BAC", "value":123.999975, "offset":569.740055},
{"name":"GM", "value":68.880084, "offset":693.74003},
{"name":"SAN", "value":63.0, "offset":762.620114},
{"name":"NVDA", "value":47.99997, "offset":825.620114},
{"name":"PG", "value":44.75001, "offset":873.620084},
{"name":"LUV", "value":-42.239968, "offset":0.0},
{"name":"DPZ", "value":-50.40006, "offset":42.239968},
{"name":"F", "value":-58.63, "offset":92.640028},
{"name":"DAL", "value":-72.72, "offset":151.270028},
{"name":"AAL", "value":-101.39998, "offset":223.990028},
{"name":"M", "value":-263.2689, "offset":325.390008}
]
},
{"10":
[
{"date":"2017-03-17"},
{"name":"AAPL", "value":223.00005, "offset":0.0},
{"name":"FB", "value":198.989956, "offset":223.00005},
{"name":"MMM", "value":159.60001, "offset":421.990006},
{"name":"BAC", "value":115.000025, "offset":581.590016},
{"name":"NVDA", "value":81.9, "offset":696.590041},
{"name":"SAN", "value":55.8, "offset":778.490041},
{"name":"PG", "value":42.55, "offset":834.290041},
{"name":"GM", "value":37.380084, "offset":876.840041},
{"name":"LUV", "value":-57.76, "offset":0.0},
{"name":"DPZ", "value":-59.879976, "offset":57.76},
{"name":"DAL", "value":-88.920036, "offset":117.639976},
{"name":"F", "value":-90.09, "offset":206.560012},
{"name":"AAL", "value":-109.59998, "offset":296.650012},
{"name":"M", "value":-259.98117471, "offset":406.249992}
]
}
]
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment