Skip to content

Instantly share code, notes, and snippets.

@RicCheng
Last active September 23, 2016 21:30
Show Gist options
  • Save RicCheng/73aa51d457d0125e314260cbd6842153 to your computer and use it in GitHub Desktop.
Save RicCheng/73aa51d457d0125e314260cbd6842153 to your computer and use it in GitHub Desktop.
Focus+Context+Scanning
license: mit

This examples demonstrates how to use D3's brush component to implement focus + context zooming. Click and drag in the small chart below to pan or zoom.

forked from vlandham's block: Focus+Context via Brushing

date price
20140102 4143.07
20140103 4131.91
20140106 4113.68
20140107 4153.18
20140108 4165.61
20140109 4156.19
20140110 4174.66
20140113 4113.3
20140114 4183.02
20140115 4214.88
20140116 4218.69
20140117 4197.58
20140121 4225.76
20140122 4243.0
20140123 4218.87
20140124 4128.17
20140127 4083.61
20140128 4097.96
20140129 4051.43
20140130 4123.13
20140131 4103.88
20140203 3996.96
20140204 4031.52
20140205 4011.55
20140206 4057.12
20140207 4125.86
20140210 4148.17
20140211 4191.04
20140212 4201.29
20140213 4240.67
20140214 4244.03
20140218 4272.78
20140219 4237.95
20140220 4267.55
20140221 4263.41
20140224 4292.97
20140225 4287.59
20140226 4292.06
20140227 4318.93
20140228 4308.12
20140303 4277.3
20140304 4351.97
20140305 4357.97
20140306 4352.13
20140307 4336.22
20140310 4334.45
20140311 4307.19
20140312 4323.33
20140313 4260.42
20140314 4245.4
20140317 4279.95
20140318 4333.31
20140319 4307.6
20140320 4319.29
20140321 4276.79
20140324 4226.39
20140325 4234.27
20140326 4173.58
20140327 4151.23
20140328 4155.76
20140331 4198.99
20140401 4268.04
20140402 4276.46
20140403 4237.74
20140404 4127.73
20140407 4079.75
20140408 4112.99
20140409 4183.9
20140410 4054.11
20140411 3999.73
20140414 4022.69
20140415 4034.16
20140416 4086.23
20140417 4095.52
20140421 4121.55
20140422 4161.46
20140423 4126.97
20140424 4148.34
20140425 4075.56
20140428 4074.4
20140429 4103.54
20140430 4114.56
20140501 4127.45
20140502 4123.9
20140505 4138.06
20140506 4080.76
20140507 4067.67
20140508 4051.5
20140509 4071.87
20140512 4143.86
20140513 4130.17
20140514 4100.63
20140515 4069.29
20140516 4090.59
20140519 4125.82
20140520 4096.89
20140521 4131.54
20140522 4154.34
20140523 4185.81
20140527 4237.07
20140528 4225.07
20140529 4247.95
20140530 4242.62
20140602 4237.2
20140603 4234.08
20140604 4251.64
20140605 4296.23
20140606 4321.4
20140609 4336.24
20140610 4338.0
20140611 4331.93
20140612 4297.63
20140613 4310.65
20140616 4321.11
20140617 4337.23
20140618 4362.84
20140619 4359.33
20140620 4368.04
20140623 4368.68
20140624 4350.36
20140625 4379.76
20140626 4379.05
20140627 4397.93
20140630 4408.18
20140701 4458.65
20140702 4457.73
20140703 4485.93
20140707 4451.53
20140708 4391.46
20140709 4419.03
20140710 4396.2
20140711 4415.49
20140714 4440.42
20140715 4416.39
20140716 4425.97
20140717 4363.45
20140718 4432.15
20140721 4424.7
20140722 4456.02
20140723 4473.7
20140724 4472.11
20140725 4449.56
20140728 4444.91
20140729 4442.7
20140730 4462.9
20140731 4369.77
20140801 4352.64
20140804 4383.89
20140805 4352.84
20140806 4355.05
20140807 4334.97
20140808 4370.9
20140811 4401.33
20140812 4389.25
20140813 4434.13
20140814 4453.0
20140815 4464.93
20140818 4508.31
20140819 4527.51
20140820 4526.48
20140821 4532.1
20140822 4538.55
20140825 4557.35
20140826 4570.64
20140827 4569.62
20140828 4557.69
20140829 4580.27
20140902 4598.19
20140903 4572.57
20140904 4562.29
20140905 4582.9
20140908 4592.29
20140909 4552.29
20140910 4586.52
20140911 4591.81
20140912 4567.6
20140915 4518.9
20140916 4552.76
20140917 4562.19
20140918 4593.43
20140919 4579.79
20140922 4527.69
20140923 4508.69
20140924 4555.22
20140925 4466.75
20140926 4512.19
20140929 4505.85
20140930 4493.39
20141001 4422.09
20141002 4430.19
20141003 4475.62
20141006 4454.8
20141007 4385.2
20141008 4468.59
20141009 4378.34
20141010 4276.24
20141013 4213.66
20141014 4227.17
20141015 4215.32
20141016 4217.39
20141017 4258.44
20141020 4316.07
20141021 4419.48
20141022 4382.85
20141023 4452.79
20141024 4483.72
20141027 4485.93
20141028 4564.29
20141029 4549.23
20141030 4566.14
20141031 4630.74
20141103 4638.91
20141104 4623.64
20141105 4620.72
20141106 4638.47
20141107 4632.53
20141110 4651.62
20141111 4660.56
20141112 4675.13
20141113 4680.14
20141114 4688.54
20141117 4671.0
20141118 4702.44
20141119 4675.71
20141120 4701.87
20141121 4712.97
20141124 4754.89
20141125 4758.25
20141126 4787.32
20141128 4791.63
20141201 4727.35
20141202 4755.81
20141203 4774.47
20141204 4769.44
20141205 4780.76
20141208 4740.69
20141209 4766.47
20141210 4684.03
20141211 4708.16
20141212 4653.6
20141215 4605.16
20141216 4547.83
20141217 4644.31
20141218 4748.4
20141219 4765.38
20141222 4781.42
20141223 4765.42
20141224 4773.47
20141226 4806.86
20141229 4806.91
20141230 4777.44
20141231 4736.05
20150102 4726.81
20150105 4652.57
20150106 4592.74
20150107 4650.47
20150108 4736.19
20150109 4704.07
20150112 4664.71
20150113 4661.5
20150114 4639.32
20150115 4570.82
20150116 4634.38
20150120 4654.85
20150121 4667.42
20150122 4750.4
20150123 4757.88
20150126 4771.76
20150127 4681.5
20150128 4637.99
20150129 4683.41
20150130 4635.24
20150202 4676.69
20150203 4727.74
20150204 4716.7
20150205 4765.1
20150206 4744.4
20150209 4726.01
20150210 4787.64
20150211 4801.18
20150212 4857.61
20150213 4893.84
20150217 4899.27
20150218 4906.36
20150219 4924.7
20150220 4955.97
20150223 4960.97
20150224 4968.12
20150225 4967.14
20150226 4987.89
20150227 4963.53
20150302 5008.1
20150303 4979.9
20150304 4967.14
20150305 4982.81
20150306 4927.37
20150309 4942.44
20150310 4859.79
20150311 4849.94
20150312 4893.29
20150313 4871.76
20150316 4929.51
20150317 4937.43
20150318 4982.83
20150319 4992.38
20150320 5026.42
20150323 5010.97
20150324 4994.73
20150325 4876.52
20150326 4863.36
20150327 4891.22
20150330 4947.44
20150331 4900.88
20150401 4880.23
20150402 4886.94
20150406 4917.32
20150407 4910.23
20150408 4950.82
20150409 4974.56
20150410 4995.98
20150413 4988.25
20150414 4977.29
20150415 5011.02
20150416 5007.79
20150417 4931.81
20150420 4994.6
20150421 5014.1
20150422 5035.17
20150423 5056.06
20150424 5092.08
20150427 5060.25
20150428 5055.42
20150429 5023.64
20150430 4941.42
20150501 5005.39
20150504 5016.93
20150505 4939.33
20150506 4919.64
20150507 4945.54
20150508 5003.55
20150511 4993.57
20150512 4976.19
20150513 4981.69
20150514 5050.8
20150515 5048.29
20150518 5078.44
20150519 5070.03
20150520 5071.74
20150521 5090.79
20150522 5089.36
20150526 5032.75
20150527 5106.59
20150528 5097.98
20150529 5070.03
20150601 5082.93
20150602 5076.52
20150603 5099.23
20150604 5059.12
20150605 5068.46
20150608 5021.63
20150609 5013.87
20150610 5076.69
20150611 5082.51
20150612 5051.1
20150615 5029.97
20150616 5055.55
20150617 5064.88
20150618 5132.95
20150619 5117.0
20150622 5153.97
20150623 5160.09
20150624 5122.41
20150625 5112.19
20150626 5080.51
20150629 4958.47
20150630 4986.87
20150701 5013.12
20150702 5009.21
20150706 4991.94
20150707 4997.46
20150708 4909.76
20150709 4922.4
20150710 4997.7
20150713 5071.51
20150714 5104.89
20150715 5098.94
20150716 5163.18
20150717 5210.14
20150720 5218.86
20150721 5208.12
20150722 5171.77
20150723 5146.41
20150724 5088.63
20150727 5039.78
20150728 5089.21
20150729 5111.73
20150730 5128.78
20150731 5128.28
20150803 5115.38
20150804 5105.55
20150805 5139.94
20150806 5056.44
20150807 5043.54
20150810 5101.8
20150811 5036.79
20150812 5044.39
20150813 5033.56
20150814 5048.24
20150817 5091.7
20150818 5059.35
20150819 5019.05
20150820 4877.49
20150821 4706.04
20150824 4526.25
20150825 4506.49
20150826 4697.54
20150827 4812.71
20150828 4828.32
20150831 4776.51
20150901 4636.1
20150902 4749.98
20150903 4733.5
20150904 4683.92
20150908 4811.93
20150909 4756.53
20150910 4796.25
20150911 4822.34
20150914 4805.76
20150915 4860.52
20150916 4889.24
20150917 4893.95
20150918 4827.23
20150921 4828.95
20150922 4756.72
20150923 4752.74
20150924 4734.48
20150925 4686.5
20150928 4543.97
20150929 4517.32
20150930 4620.16
20151001 4627.08
20151002 4707.78
20151005 4781.26
20151006 4748.36
20151007 4791.15
20151008 4810.79
20151009 4830.47
20151012 4838.64
20151013 4796.61
20151014 4782.85
20151015 4870.1
20151016 4886.69
20151019 4905.47
20151020 4880.97
20151021 4840.12
20151022 4920.05
20151023 5031.86
20151026 5034.7
20151027 5030.15
20151028 5095.69
20151029 5074.27
20151030 5053.75
20151102 5127.15
20151103 5145.13
20151104 5142.48
20151105 5127.74
20151106 5147.12
20151109 5095.3
20151110 5083.24
20151111 5067.02
20151112 5005.08
20151113 4927.88
20151116 4984.62
20151117 4986.01
20151118 5075.2
20151119 5073.64
20151120 5104.92
20151123 5102.48
20151124 5102.81
20151125 5116.14
20151127 5127.52
20151130 5108.67
20151201 5156.31
20151202 5123.22
20151203 5037.53
20151204 5142.27
20151207 5101.81
20151208 5098.24
20151209 5022.87
20151210 5045.17
20151211 4933.47
20151214 4952.23
20151215 4995.36
20151216 5071.13
20151217 5002.55
20151218 4923.08
20151221 4968.92
20151222 5001.11
20151223 5045.93
20151224 5048.49
20151228 5040.99
20151229 5107.94
20151230 5065.85
20151231 5007.41
20160104 4903.09
20160105 4891.43
20160106 4835.76
20160107 4689.43
20160108 4643.63
20160111 4637.99
20160112 4685.92
20160113 4526.06
20160114 4615.0
20160115 4488.42
20160119 4476.95
20160120 4471.69
20160121 4472.06
20160122 4591.18
20160125 4518.49
20160126 4567.67
20160127 4468.17
20160128 4506.68
20160129 4613.95
20160201 4620.37
20160202 4516.95
20160203 4504.24
20160204 4509.56
20160205 4363.14
20160208 4283.75
20160209 4268.76
20160210 4283.59
20160211 4266.84
20160212 4337.51
20160216 4435.96
20160217 4534.06
20160218 4487.54
20160219 4504.43
20160222 4570.61
20160223 4503.58
20160224 4542.61
20160225 4582.2
20160226 4590.47
20160229 4557.95
20160301 4689.6
20160302 4703.42
20160303 4707.42
20160304 4717.02
20160307 4708.25
20160308 4648.82
20160309 4674.38
20160310 4662.16
20160311 4748.47
20160314 4750.28
20160315 4728.67
20160316 4763.97
20160317 4774.99
20160318 4795.65
20160321 4808.87
20160322 4821.66
20160323 4768.86
20160324 4773.5
20160328 4766.79
20160329 4846.62
20160330 4869.29
20160331 4869.85
20160401 4914.54
20160404 4891.8
20160405 4843.93
20160406 4920.72
20160407 4848.37
20160408 4850.69
20160411 4833.4
20160412 4872.09
20160413 4947.42
20160414 4945.89
20160415 4938.22
20160418 4960.02
20160419 4940.33
20160420 4948.15
20160421 4945.93
20160422 4906.2
20160425 4895.79
20160426 4888.28
20160427 4863.14
20160428 4805.29
20160429 4775.36
20160502 4817.59
20160503 4763.22
20160504 4725.64
20160505 4717.09
20160506 4736.16
20160509 4750.21
20160510 4809.88
20160511 4760.69
20160512 4737.33
20160513 4717.68
20160516 4775.46
20160517 4715.73
20160518 4739.12
20160519 4712.53
20160520 4769.56
20160523 4765.78
20160524 4861.06
20160525 4894.89
20160526 4901.77
20160527 4933.5
20160531 4948.05
20160601 4952.25
20160602 4971.36
20160603 4942.52
20160606 4968.71
20160607 4961.75
20160608 4974.64
20160609 4958.62
20160610 4894.55
20160613 4848.44
20160614 4843.55
20160615 4834.93
20160616 4844.91
20160617 4800.34
20160620 4837.21
20160621 4843.76
20160622 4833.32
20160623 4910.04
20160624 4707.98
20160627 4594.44
20160628 4691.87
20160629 4779.25
20160630 4842.67
20160701 4862.57
20160705 4822.9
20160706 4859.16
20160707 4876.81
20160708 4956.76
20160711 4988.64
20160712 5022.82
20160713 5005.73
20160714 5034.06
20160715 5029.59
20160718 5055.78
20160719 5036.37
20160720 5089.93
20160721 5073.9
20160722 5100.16
20160725 5097.63
20160726 5110.05
20160727 5139.81
20160728 5154.98
20160729 5162.13
20160801 5184.2
20160802 5137.73
20160803 5159.74
20160804 5166.25
20160805 5221.12
20160808 5213.14
20160809 5225.48
20160810 5204.58
20160811 5228.4
20160812 5232.89
20160815 5262.02
20160816 5227.11
20160817 5228.66
20160818 5240.15
20160819 5238.38
20160822 5244.6
20160823 5260.08
20160824 5217.69
20160825 5212.2
20160826 5218.92
20160829 5232.33
20160830 5222.99
20160831 5213.22
20160901 5227.21
20160902 5249.9
20160906 5275.91
20160907 5283.93
20160908 5259.48
20160909 5125.91
20160912 5211.89
20160913 5155.25
20160914 5173.77
20160915 5249.69
20160916 5244.57
20160919 5235.03
20160920 5241.35
20160921 5295.18
20160922 5339.52
<!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 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("%Y%m%d").parse
bisectDate = d3.bisector(function(d) { return d.date; }).left;
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 area = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
// to remove
var area2 = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x2(d.date); })
.y0(height2)
.y1(function(d) { return y2(d.price); });
var area = d3.svg.area()
.interpolate("step-after")
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
var line = d3.svg.line()
.interpolate("step-after")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.price); })
.defined(function(d) { return d.price; }); // Hiding line value defaults of 0 for missing data
var area_brush = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x2(d.date); })
.y0(height2)
.y1(function(d) { return y2(d.price); })
var data;
var brush = d3.svg.brush()
.x(x2)
.extent([0.9, 1])
.on("brush", brushed);
var scan = d3.svg.brush()
.x(x)
.on("brush", scanned)
.on("brushstart", function () {d3.select("g.focus_box").remove();});
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("datapoints.csv", function(error, csv_data) {
data = csv_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());
// gradient color for the area for decoration
focus.append("linearGradient")
.attr("id", "temperature-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", "0%")
.attr("x2", 0).attr("y2", "100%")
.selectAll("stop")
.data([
{offset: "0%", color: "#ADD8E6"},
{offset: "70%", color: "lightgrey"},
{offset: "100%", color: "white"}
])
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; });
focus.append("path")
.datum(data)
//.attr("clip-path", "url(#clip)")
.attr("d", area);
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("class", "x scan")
.call(scan)
.selectAll("rect")
.attr("height", height )
.on("mouseover", function() { focus_dropline.style("display", null); })
.on("mouseout", function() { focus_dropline.style("display", "none"); })
.on("mousemove", mousemove);
// prettify: to block the stroke of the scanner
focus.append("line")
.style("stroke", "white")
.style("stroke-width", "2px")
.attr("x1",2)
.attr("x2",width)
// prettify: to block the stroke of the scanner at bottom
focus.append("line")
.style("stroke", "black")
.style("stroke-width", "2px")
.attr("x1",0)
.attr("x2",width)
.attr("y1",height)
.attr("y2",height);
// for the drop line
var focus_dropline = focus.append("g")
.attr("class", "focus_dropline")
.style("display", "none");
focus_dropline.append("circle")
.attr("r", 4.5);
focus_dropline.append("line")
.classed("x", true)
focus_dropline.append("line")
.classed("y", true)
focus_dropline.append("text")
.attr("x", 20)
.attr("y", 20)
.attr("dy", ".35em");
function mousemove() {
var x0 = x.invert(d3.mouse(this)[0]),
i = bisectDate(data, x0, 1),
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus_dropline.attr("transform", "translate(" + x(d.date) + "," + y(d.price) + ")");
focus_dropline.select("line.x")
.attr("x1", 0)
.attr("x2", -x(d.date))
.attr("y1", 0)
.attr("y2", 0)
focus_dropline.select("line.y")
.attr("x1", 0)
.attr("x2", 0)
.attr("y1", 0)
.attr("y2", height - y(d.price))
focus_dropline.select("text").text(d.price.toFixed(2));
}
context.append("path")
.datum(data)
.attr("class", "brush-area")
.attr("d", area_brush);
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() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
var dataFiltered = data.filter(function(d, i) {
if ( (d.date >= x.domain()[0]) && (d.date <= x.domain()[1]) ) {
return d.price;
}
});
// to re-scale y-axis
y.domain([0.9*d3.min(dataFiltered.map(function(d) { return d.price; })),
1.1*d3.max(dataFiltered.map(function(d) { return d.price; }))]);
focus.select(".line").attr("d", line);
focus.select(".area").attr("d", area);
focus.select(".x.axis").transition().call(xAxis);
focus.select(".y.axis").call(yAxis);
// focus.select(".dot").attr("d", circles);
d3.selectAll('circle.dot')
.attr("cx",function(d) { return x( d.FileDate ); })
.attr("cy", function(d) {
var i_price = bisectDate(data, d.FileDate, 1),
d0_price = data[i_price - 1],
d1_price = data[i_price],
d_price = d.FileDate - d0_price.date > d1_price.date - d.FileDate ? d1_price.price : d0_price.price;
return y( d_price); });
};
// here's the function that is called upon brushing the main chart
function scanned() {
// get the brush that is being manipulated
var brush_event = d3.event.target;
// check if it is empty - if not, then do the analytics box
if(!brush_event.empty()) {
// get the extent of the brush as a two-element array [min, max]
var extent = brush_event.extent();
minDate = extent[0];
maxDate = extent[1];
console.log("minDate",minDate)
console.log("maxDate",maxDate)
// day difference
var timeDiff = Math.abs(maxDate-minDate);
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
console.log("TimeDiff", Date(timeDiff))
var i_min = bisectDate(data, minDate, 1),
d0_min = data[i_min - 1],
d1_min = data[i_min],
d_min = minDate - d0_min.date > d1_min.date - minDate ? d1_min : d0_min;
var i_max = bisectDate(data, maxDate, 1),
d0_max = data[i_max - 1],
d1_max = data[i_max],
d_max = maxDate - d0_max.date > d1_max.date - maxDate ? d1_max : d0_max;
period_return = (d_max.price - d_min.price) / d_min.price
annualized_return = (d_max.price - d_min.price) / d_min.price / (diffDays/365)
// get line data dynamically
var lineData = [{"x": x(minDate), "y":y(d_min.price) }, {"x": x(maxDate), "y": y(d_max.price)}];
console.log(lineData);
console.log(lineFunction(lineData));
//focus_box
var focus_box = focus.selectAll("g.focus_box")
.data([maxDate]);
focus_box
.enter()
.append("g")
.attr("class", "focus_box")
focus_box.selectAll("*").remove();
focus_box
.append("g")
.attr("class", "indicator")
.append("path")
.attr("class", "line")
.attr("d", lineFunction(lineData))
focus_box
.append("circle")
.attr("cx", x(maxDate))
.attr("cy", y(d_max.price))
.attr("r", 8)
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", 2);
focus_box
.append("circle")
.attr("cx", x(maxDate))
.attr("cy", y(d_max.price))
.attr("r", 2)
.attr("fill", "black");
focus_box
.append("circle")
.attr("cx", x(minDate))
.attr("cy", y(d_min.price))
.attr("r", 3)
.attr("fill", "black")
.attr("stroke", "black")
.attr("stroke-width", 1);
focus_box
.append("rect")
.attr("width", 120)
.attr("height", 65)
.attr('x', Math.min(width - 125, x(maxDate)+14))
.attr('y', height - 80)
.attr("fill", "black")
.attr("stroke", "steelblue")
.attr("stroke-width", "1px")
.attr("opacity", 0.2);
focus_box.append("text")
.attr('x', Math.min(width - 125, x(maxDate)+20))
.attr('y', height - 70)
.attr("dy", ".3em")
.text("Return (period)");
focus_box.append("text")
.attr('x', Math.min(width - 125, x(maxDate)+20))
.attr('y', height - 55)
.attr("dy", ".35em")
.text(((period_return*100).toFixed(1)).toString().concat("%"));
focus_box.append("text")
.attr('x', Math.min(width - 125, x(maxDate)+20))
.attr('y', height - 40)
.attr("dy", ".3em")
.text("Return (annualized)");
focus_box.append("text")
.attr('x', Math.min(width - 125, x(maxDate)+20))
.attr('y', height - 25)
.attr("dy", ".35em")
.text(((annualized_return*100).toFixed(1)).toString().concat("%"));
}
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment