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
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> |