Skip to content

Instantly share code, notes, and snippets.

@cieloazul310 cieloazul310/.block
Last active Aug 29, 2017

Embed
What would you like to do?
Ibaraki Election 2017
license: gpl-3.0
height: 500

Ibaraki Election 2017

TopoJSONと茨城県知事選2017の投票得票のデータを利用して、自治体ごとの県知事選の動向を可視化。 国土数値情報の行政区域データ(平成28年茨城県)を加工したものを利用しています。

使用したデータ

市町村名 行政コード 区分 市郡 市町村区分 橋本まさる 大井川かずひこ 鶴田まこみ 得票率橋本 得票率大井川 得票率鶴田 得票総数 いずれにも属さない票数 有効投票数 無効投票数 投票総数 不受理 持帰り その他 開票率 有権者数_男 有権者数_女 有権者数 投票者数_男 投票者数_女 投票者数 棄権者数_男 棄権者数_女 棄権者数 投票率_男 投票率_女 投票率 普通投票_男 普通投票_女 普通投票 期日前投票_男 期日前投票_女 期日前投票 不在者投票_男 不在者投票_女 不在者投票 投票者数計_男 投票者数計_女 投票者数計 仮投票 不在者投票_不受理 不在者投票_拒否
茨城県 08 茨城県 427743 497361 122013 0.40849590 0.47498131 0.11652280 1047117 0 1047117 9157 1056280 2 5 -1 100 1208568 1220758 2429326 525091 531189 1056280 683477 689569 1373046 0.43447369 0.43513047 0.43480373 357905 342200 700105 164514 185291 349805 2672 3698 6370 525091 531189 1056280 0 2 0
水戸市 08201 市部 水戸市 37357 54792 11896 0.35904657 0.52661829 0.11433514 104045 0 104045 931 104976 0 0 0 100 109015 115775 224790 50945 54031 104976 58070 61744 119814 0.46732101 0.46668970 0.46699586 35822 37102 72924 14866 16582 31448 257 347 604 50945 54031 104976 0 0 0
日立市 08202 市部 日立市 25579 36821 5904 0.37448758 0.53907531 0.08643710 68304 0 68304 466 68771 0 1 0 100 77289 77363 154652 34041 34730 68771 43248 42633 85881 0.44043784 0.44892261 0.44468225 22177 20884 43061 11645 13620 25265 219 226 445 34041 34730 68771 0 0 0
土浦市 08203 市部 土浦市 17906 21519 6417 0.39060250 0.46941669 0.13998080 45842 0 45842 465 46307 0 0 0 100 58317 59181 117498 22846 23461 46307 35471 35720 71191 0.39175541 0.39642791 0.39410884 15251 14564 29815 7479 8704 16183 116 193 309 22846 23461 46307 0 0 0
古河市 08204 市部 古河市 15104 19085 5008 0.38533561 0.48689951 0.12776488 39197 0 39197 383 39580 0 0 0 100 59445 59265 118710 19712 19868 39580 39733 39397 79130 0.33160064 0.33524002 0.33341757 14352 13542 27894 5266 6208 11474 94 118 212 19712 19868 39580 0 0 0
石岡市 08205 市部 石岡市 13366 12377 3068 0.46392003 0.42959286 0.10648711 28811 0 28811 216 29027 0 0 0 100 31780 32524 64304 14375 14652 29027 17405 17872 35277 0.45232851 0.45049809 0.45140271 9302 8840 18142 4949 5611 10560 124 201 325 14375 14652 29027 0 0 0
結城市 08207 市部 結城市 8376 5942 1833 0.51860566 0.36790292 0.11349142 16151 0 16151 147 16298 0 0 0 100 21013 21259 42272 8148 8150 16298 12865 13109 25974 0.38775996 0.38336704 0.38555072 5936 5563 11499 2141 2452 4593 71 135 206 8148 8150 16298 0 0 0
龍ケ崎市 08208 市部 龍ケ崎市 9796 10859 4226 0.39371408 0.43643744 0.16984848 24881 0 24881 289 25169 0 0 -1 100 31907 32396 64303 12545 12624 25169 19362 19772 39134 0.39317391 0.38967774 0.39141253 8971 8682 17653 3539 3895 7434 35 47 82 12545 12624 25169 0 0 0
下妻市 08210 市部 下妻市 5815 8182 1350 0.37890141 0.53313351 0.08796507 15347 0 15347 118 15465 0 0 0 100 17727 17703 35430 7763 7702 15465 9964 10001 19965 0.43791956 0.43506750 0.43649450 4504 4005 8509 3245 3685 6930 14 12 26 7763 7702 15465 0 0 0
常総市 08211 市部 常総市 11048 8989 2591 0.48824465 0.39725119 0.11450415 22628 0 22628 230 22858 0 0 0 100 25039 25293 50332 11279 11579 22858 13760 13714 27474 0.45045729 0.45779465 0.45414448 7490 7157 14647 3752 4367 8119 37 55 92 11279 11579 22858 0 0 0
常陸太田市 08212 市部 常陸太田市 9321 13136 1671 0.38631466 0.54442971 0.06925564 24128 0 24128 134 24262 0 0 0 100 22819 23898 46717 12093 12169 24262 10726 11729 22455 0.52995311 0.50920579 0.51933985 6796 6258 13054 5259 5881 11140 38 30 68 12093 12169 24262 0 0 0
高萩市 08214 市部 高萩市 4483 5900 953 0.39546577 0.52046577 0.08406845 11336 0 11336 105 11441 0 0 0 100 12339 12719 25058 5628 5813 11441 6711 6906 13617 0.45611476 0.45703279 0.45658073 3953 3819 7772 1615 1922 3537 60 72 132 5628 5813 11441 0 0 0
北茨城市 08215 市部 北茨城市 9691 6613 1334 0.54943871 0.37492913 0.07563216 17638 0 17638 125 17763 0 0 0 100 18848 19140 37988 8747 9016 17763 10101 10124 20225 0.46408107 0.47105538 0.46759503 5435 5104 10539 3226 3842 7068 86 70 156 8747 9016 17763 0 0 0
笠間市 08216 市部 笠間市 11629 17182 3215 0.36311122 0.53650159 0.10038719 32026 0 32026 224 32250 0 0 0 100 31697 33232 64929 15769 16481 32250 15928 16751 32679 0.49749188 0.49593765 0.49669639 10138 9868 20006 5556 6458 12014 75 155 230 15769 16481 32250 0 0 0
取手市 08217 市部 取手市 12599 14478 7715 0.36212348 0.41613014 0.22174638 34792 0 34792 379 35171 0 0 0 100 45008 46637 91645 17449 17722 35171 27559 28915 56474 0.38768663 0.37999871 0.38377435 12801 12284 25085 4576 5306 9882 72 132 204 17449 17722 35171 0 0 0
牛久市 08219 市部 牛久市 10512 12846 5489 0.36440531 0.44531494 0.19027975 28847 0 28847 286 29133 0 0 0 100 34328 35219 69547 14512 14621 29133 19816 20598 40414 0.42274528 0.41514523 0.41889657 9639 9339 18978 4822 5224 10046 51 58 109 14512 14621 29133 0 0 0
つくば市 08220 市部 つくば市 28208 28680 12529 0.40635579 0.41315528 0.18048893 69417 0 69417 764 70182 0 1 0 100 89039 87137 176176 35245 34937 70182 53794 52200 105994 0.39583778 0.40094334 0.39836300 24777 23585 48362 10343 11165 21508 125 187 312 35245 34937 70182 0 0 0
ひたちなか市 08221 市部 ひたちなか市 21201 32346 6261 0.35448435 0.54083066 0.10468499 59808 0 59808 448 60256 0 0 0 100 65365 64861 130226 30140 30116 60256 35225 34745 69970 0.46110304 0.46431600 0.46270330 21860 21344 43204 8149 8617 16766 131 155 286 30140 30116 60256 0 0 0
鹿嶋市 08222 市部 鹿嶋市 11315 10785 2740 0.45551530 0.43417874 0.11030596 24840 0 24840 248 25091 0 3 0 100 28919 27210 56129 12707 12384 25091 16212 14826 31038 0.43939970 0.45512679 0.44702382 8050 7291 15341 4572 5002 9574 85 91 176 12707 12384 25091 0 0 0
潮来市 08223 市部 潮来市 5633 4491 825 0.51447621 0.41017445 0.07534935 10949 0 10949 73 11022 0 0 0 100 12024 12207 24231 5470 5552 11022 6554 6655 13209 0.45492349 0.45482100 0.45487186 3413 3163 6576 2024 2356 4380 33 33 66 5470 5552 11022 0 0 0
守谷市 08224 市部 守谷市 8189 8823 3411 0.40096950 0.43201293 0.16701758 20423 0 20423 257 20680 0 0 0 100 26364 26383 52747 10423 10257 20680 15941 16126 32067 0.39534972 0.38877307 0.39206021 8183 7900 16083 2227 2323 4550 13 34 47 10423 10257 20680 0 0 0
常陸大宮市 08225 市部 常陸大宮市 7818 11009 1556 0.38355492 0.54010695 0.07633812 20383 0 20383 94 20477 0 0 0 100 18326 18749 37075 10212 10265 20477 8114 8484 16598 0.55724108 0.54749587 0.55231288 6203 5822 12025 3953 4365 8318 56 78 134 10212 10265 20477 0 0 0
那珂市 08226 市部 那珂市 9309 12573 2287 0.38516281 0.52021184 0.09462535 24169 0 24169 182 24351 0 0 0 100 22623 23765 46388 11897 12454 24351 10726 11311 22037 0.52588074 0.52404797 0.52494180 7562 7487 15049 4260 4849 9109 75 118 193 11897 12454 24351 0 0 0
筑西市 08227 市部 筑西市 16643 16243 3969 0.45158052 0.44072717 0.10769231 36855 0 36855 279 37135 1 0 0 100 43684 44437 88121 18621 18514 37135 25063 25923 50986 0.42626591 0.41663479 0.42140920 13065 12202 25267 5486 6231 11717 70 81 151 18621 18514 37135 0 1 0
坂東市 08228 市部 坂東市 6828 9479 1835 0.37636424 0.52248925 0.10114651 18142 0 18142 174 18316 0 0 0 100 22599 22107 44706 9299 9017 18316 13300 13090 26390 0.41147838 0.40787986 0.40969892 6411 5738 12149 2833 3222 6055 55 57 112 9299 9017 18316 0 0 0
稲敷市 08229 市部 稲敷市 5861 7077 1291 0.41190526 0.49736454 0.09073020 14229 0 14229 143 14372 0 0 0 100 17944 18123 36067 7191 7181 14372 10753 10942 21695 0.40074677 0.39623683 0.39848061 4958 4593 9551 2177 2502 4679 56 86 142 7191 7181 14372 0 0 0
かすみがうら市 08230 市部 かすみがうら市 7640 6316 1905 0.48168464 0.39820944 0.12010592 15861 0 15861 159 16020 0 0 0 100 17585 17375 34960 8054 7966 16020 9531 9409 18940 0.45800398 0.45847482 0.45823799 5803 5422 11225 2182 2447 4629 69 97 166 8054 7966 16020 0 0 0
桜川市 08231 市部 桜川市 9062 7650 1490 0.49785738 0.42028349 0.08185914 18202 0 18202 152 18355 1 0 0 100 17992 18718 36710 9025 9330 18355 8967 9388 18355 0.50161183 0.49845069 0.50000000 5515 5233 10748 3469 4030 7499 41 67 108 9025 9330 18355 0 1 0
神栖市 08232 市部 神栖市 12411 12282 2545 0.45565019 0.45091416 0.09343564 27238 0 27238 253 27491 0 0 0 100 39094 36893 75987 13863 13628 27491 25231 23265 48496 0.35460685 0.36939257 0.36178557 10338 9648 19986 3446 3840 7286 79 140 219 13863 13628 27491 0 0 0
行方市 08233 市部 行方市 6855 6516 988 0.47740093 0.45379205 0.06880702 14359 0 14359 110 14469 0 0 0 100 15005 15165 30170 7314 7155 14469 7691 8010 15701 0.48743752 0.47181009 0.47958237 4716 4284 9000 2559 2783 5342 39 88 127 7314 7155 14469 0 0 0
鉾田市 08234 市部 鉾田市 7972 8813 1529 0.43529540 0.48121656 0.08348804 18314 0 18314 164 18478 0 0 0 100 20481 20246 40727 9326 9152 18478 11155 11094 22249 0.45534886 0.45203991 0.45370393 5345 4822 10167 3913 4217 8130 68 113 181 9326 9152 18478 0 0 0
つくばみらい市 08235 市部 つくばみらい市 6273 7498 2562 0.38406906 0.45907059 0.15686034 16333 0 16333 158 16491 0 0 0 100 20776 20763 41539 8285 8206 16491 12491 12557 25048 0.39877744 0.39522227 0.39700041 6231 5816 12047 2038 2369 4407 16 21 37 8285 8206 16491 0 0 0
小美玉市 08236 市部 小美玉市 9060 8490 1651 0.47185042 0.44216447 0.08598510 19201 0 19201 164 19365 0 0 0 100 21252 21065 42317 9819 9546 19365 11433 11519 22952 0.46202710 0.45316876 0.45761751 6716 6292 13008 3024 3148 6172 79 106 185 9819 9546 19365 0 0 0
茨城町 08302 郡部 東茨城郡 5024 7443 1080 0.37085702 0.54942054 0.07972245 13547 0 13547 101 13648 0 0 0 100 13850 14096 27946 6771 6877 13648 7079 7219 14298 0.48888087 0.48786890 0.48837043 4153 3843 7996 2585 2991 5576 33 43 76 6771 6877 13648 0 0 0
大洗町 08309 郡部 東茨城郡 3212 3703 489 0.43381956 0.50013506 0.06604538 7404 0 7404 52 7456 0 0 0 100 6971 7228 14199 3577 3879 7456 3394 3349 6743 0.51312581 0.53666298 0.52510740 2069 2146 4215 1488 1703 3191 20 30 50 3577 3879 7456 0 0 0
城里町 08310 郡部 東茨城郡 3335 4312 792 0.39518900 0.51096101 0.09384998 8439 0 8439 48 8487 0 0 0 100 8633 8906 17539 4175 4312 8487 4458 4594 9052 0.48360941 0.48416798 0.48389304 2744 2666 5410 1422 1635 3057 9 11 20 4175 4312 8487 0 0 0
東海村 08341 郡部 那珂郡 7107 6957 1393 0.45979168 0.45008734 0.09012098 15457 0 15457 116 15573 0 0 0 100 15384 15307 30691 7853 7720 15573 7531 7587 15118 0.51046542 0.50434442 0.50741260 5574 5259 10833 2257 2422 4679 22 39 61 7853 7720 15573 0 0 0
大子町 08364 郡部 久慈郡 4847 4681 433 0.48659773 0.46993274 0.04346953 9961 0 9961 50 10011 0 0 0 100 7776 8162 15938 4969 5042 10011 2807 3120 5927 0.63901749 0.61774075 0.62812147 3342 3217 6559 1555 1722 3277 72 103 175 4969 5042 10011 0 0 0
美浦村 08442 郡部 稲敷郡 1987 2871 539 0.36816750 0.53196220 0.09987030 5397 0 5397 41 5438 0 0 0 100 6825 6429 13254 2654 2784 5438 4171 3645 7816 0.38886447 0.43303780 0.41029123 1664 1616 3280 971 1158 2129 19 10 29 2654 2784 5438 0 0 0
阿見町 08443 郡部 稲敷郡 6601 7294 2109 0.41245939 0.45576106 0.13177956 16004 0 16004 157 16161 0 0 0 100 19265 19523 38788 8032 8129 16161 11233 11394 22627 0.41692188 0.41638068 0.41664948 6167 6091 12258 1839 2014 3853 26 24 50 8032 8129 16161 0 0 0
河内町 08447 郡部 稲敷郡 1280 2064 223 0.35884497 0.57863751 0.06251752 3567 0 3567 35 3602 0 0 0 100 3981 4072 8053 1756 1846 3602 2225 2226 4451 0.44109520 0.45333988 0.44728673 1370 1390 2760 386 450 836 0 6 6 1756 1846 3602 0 0 0
八千代町 08521 郡部 結城郡 4256 3005 751 0.53120320 0.37506241 0.09373440 8012 0 8012 75 8087 0 0 0 100 9086 9006 18092 4096 3991 8087 4990 5015 10005 0.45080343 0.44314901 0.44699315 2890 2614 5504 1197 1369 2566 9 8 17 4096 3991 8087 0 0 0
五霞町 08542 郡部 猿島郡 1341 1250 355 0.45519348 0.42430414 0.12050238 2946 0 2946 21 2967 0 0 0 100 3773 3728 7501 1505 1462 2967 2268 2266 4534 0.39888683 0.39216738 0.39554726 1156 1058 2214 348 404 752 1 0 1 1505 1462 2967 0 0 0
境町 08546 郡部 猿島郡 3678 3297 715 0.47828349 0.42873862 0.09297789 7690 0 7690 88 7778 0 0 0 100 10319 10153 20472 3908 3870 7778 6411 6283 12694 0.37871887 0.38116813 0.37993357 2822 2587 5409 1081 1276 2357 5 7 12 3908 3870 7778 0 0 0
利根町 08564 郡部 北相馬郡 2215 2692 1090 0.36935134 0.44889111 0.18175755 5997 0 5997 53 6050 0 0 0 100 7062 7340 14402 3052 2998 6050 4010 4342 8352 0.43217219 0.40844687 0.42008054 2241 2060 4301 794 924 1718 17 14 31 3052 2998 6050 0 0 0
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@font-face{
font-family: "Original Yu Gothic";
src: local("Yu Gothic");
font-weight: 300;
}
@font-face{
font-family: "Original Yu Gothic";
src: local("Yu Gothic");
font-weight: 500;
}
@font-face{
font-family: "Original Yu Gothic";
src: local("Yu Gothic");
font-weight: bold;
}
@font-face {
font-family: "Helvetica Neue";
src: local("Helvetica Neue Regular");
font-weight: 100;
}
@font-face {
font-family: "Helvetica Neue";
src: local("Helvetica Neue Regular");
font-weight: 200;
}
/* IE10以上 */
@media all and (-ms-high-contrast: none) {
html {
font-family: Verdana, Meiryo, sans-serif;
}
}
@media all and (-ms-high-contrast: active) {
html {
font-family: Verdana, Meiryo, sans-serif;
}
}
html {
font-size: 62.5%;
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Original Yu Gothic", "Yu Gothic", YuGothic, Verdana, Meiryo, "M+ 1p", sans-serif;
}
body {
margin: 0;
padding: 0;
}
h1 {
text-align: center;
}
.chart-container {
margin: 0 auto;
padding: 0;
width: 100%;/*
height: 500px;*/
max-width: 600px;
}
.chart-container-inner {
position: relative;
}
svg#chart {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
path.selected {
fill: none;/*
stroke: #fff500;*/
stroke-width: 2.5;
stroke-linecap: round;
stroke-linejoin: round;
}
path {
cursor: pointer;
}
#info {
width: 200px;
max-width: 35%;
position: absolute;
top: .5em;
left: .5em;
background: rgba(255, 255, 255, 0.8);
font-size: 1.4rem;
padding: .5em;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
}
#info h4 {
text-align: center;
margin: auto;
}
#info p {
margin: auto;
text-align: center;
}
#info small {
color: gray;
cursor: pointer;
}
#info small.active {
color: #007cd6;
font-weight: bold;
}
div#info table {
width: 100%;
font-size: 1.2rem;
margin-bottom: 0.5em;
}
div#info tr {
height: 100%;
}
div#info td {
height: 100%;
}
.td-name {
width: 3.4em;
text-align: right;
}
div.outer {
width: 100%;
height: 1em;
min-width: 5em;
}
div.inner {
width: 0%;
height: 100%;
}
div.inner span {
position: absolute;
right: 0.4em;
font-size: 1rem;
text-shadow: 0 0 4px rgba(255,255,255,1);
}
.subinfo ul {
margin: auto;
padding: inherit;
font-size: 1.1rem;
}
.subinfo li {
display: inline-block;
}
/*
.button-group {
border: 1px solid black;
border-radius: 2px;
}
.button-group div.button {
font-size: 1.2rem;
display: inline;
width: 50%;
text-align: center;
padding: .4em;
}
*/
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/topojson@3"></script>
<div class="chart-container">
<h1>茨城県知事選 2017</h1>
<div class="chart-container-inner">
<svg id="chart"></svg>
<div id="info">
<h4>茨城県</h4>
<p><small class="active" data-guide="得票率">得票率</small> &#124; <small data-guide="得票数">得票数</small></p>
<div id="subchart">
</div>
<div class="subinfo">
<ul>
<li>有権者: <span id="voter">214,231人</span></li>
<li>投票率: <span id="voterate">42.5%</span></li>
<li>大井川-橋本: <span id="difference">+12.2</span></li>
</ul>
</div>
</div>
</div>
</div>
<script>
const q = d3.queue()
.defer(d3.json, "./ibaraki_h28_merge.topojson")
.defer(d3.csv, "./data.csv");
q.await((err, json, csv) => {
if (err) throw err;
// merge csv to topojson
// and create new object for candidates
const candidates = {
"大井川": {
name: "大井川かずひこ",
firstname: "大井川",
color: "#50bcff",
values: {}
},
"橋本": {
name: "橋本まさる",
firstname: "橋本",
color: "#ff6a85",
values: {}
},
"鶴田": {
name: "鶴田まこみ",
firstname: "鶴田",
color: "#d0d73d",
values: {}
}
};
const cities = topojson.feature(json, json.objects.cities).features;
for (const feature of cities) {
const idx = csv.map(d => d["行政コード"]).indexOf(feature.properties.N03_007);
feature.properties = Object.assign(feature.properties, csv[idx]);
candidates["大井川"].values[feature.properties["市町村名"]] = {"得票数": +feature.properties["大井川かずひこ"], "得票率": +feature.properties["得票率大井川"]};
candidates["橋本"].values[feature.properties["市町村名"]] = {"得票数": +feature.properties["橋本まさる"], "得票率": +feature.properties["得票率橋本"]};
candidates["鶴田"].values[feature.properties["市町村名"]] = {"得票数": +feature.properties["鶴田まこみ"], "得票率": +feature.properties["得票率鶴田"]};
}
for (const person in candidates) {
candidates[person].sum = {
"得票数": +csv[0][candidates[person].name],
"得票率": +csv[0]["得票率" + person]
};
candidates[person].values["茨城県"] = candidates[person].sum;
}
// visualization types
const types = {
difference: {
title: "大井川氏と橋本氏のポイント差",
description: "市町村における大井川氏の得票率から橋本氏の得票率を引いたもの",
unit: "%",
cast: function(d) {
return +d["得票率大井川"] - +d["得票率橋本"];
}
},
attendance: {
title: "投票率",
description: "市町村における投票率(投票者数/有権者数)",
unit: "%",
cast: function(d) {
return d["投票率"];
}
}
};
const config = {
current: "difference",
currentInfo: "得票率",
selectedCity: "茨城県",
selected: false
};
const format = d3.format("+.2%");
const rateDiff = csv.map(d => Math.abs(types[config.current].cast(d)));
const rateColor = d3.scaleLinear()
.domain([-d3.max(rateDiff), 0, d3.max(rateDiff)])
.range(["#b9384f", "white", "#3d97d0"]).nice();
const rateForWidth = d3.scaleLinear()
.domain([0, 0.6])
.range([0, 100]);
const svg = d3.select("#chart");
const h1margin = parseFloat(d3.select("h1").style("margin").split(" ")[0].slice(0, -2));
const size = {
width: parseInt(svg.style("width")),
height: /*parseInt(d3.select(".chart-container").style("height").slice(0, -2))*/window.innerHeight - parseInt(d3.select("h1").style("height").slice(0,-2)) - (h1margin * 2)
};
const padding = {
top: 4,
right: 4,
bottom: 40,
left: 4
};
const info = d3.select("#info");
svg.attr("width", size.width)
.attr("height", size.height);
const merged = topojson.merge(json, json.objects.cities.geometries);
const projection = d3.geoMercator()
.fitExtent([[padding.left, padding.top],[size.width - padding.right, size.height - padding.bottom]], merged);
const path = d3.geoPath()
.projection(projection);
// render maps
svg.append("g")
.append("rect")
.datum(csv[0])
.attr("width", size.width)
.attr("height", size.height - padding.bottom)
.attr("x", 0)
.attr("y", 0)
.attr("fill", "white")
.on("mouseover", (d) => {
if (config.selected) return;
config.selectedCity = "茨城県";
if (config.currentInfo === "得票数") rateForWidth.domain([0, 500000]);
updateInfo();
info.select("#difference")
.text(d3.format("+.1f")(types.difference.cast(d)*100));
info.select("#voter")
.text(d3.format(",")(d["有権者数"]) + "");
info.select("#voterate")
.text(d3.format(".1%")(d["投票率"]));
})
.on("click", (d) => {
config.selected = false;
overlay1.selectAll(".selected")
.remove();
config.selectedCity = "茨城県";
if (config.currentInfo === "得票数") rateForWidth.domain([0, 500000]);
updateInfo();
info.select("#difference")
.text(d3.format("+.1f")(types.difference.cast(d)*100));
info.select("#voter")
.text(d3.format(",")(d["有権者数"]) + "");
info.select("#voterate")
.text(d3.format(".1%")(d["投票率"]));
});
const baselayer = svg.append("g");
const overlay1 = svg.append("g");
baselayer.selectAll(".cities")
.data(cities.sort((a, b) => types[config.current].cast(b.properties) - types[config.current].cast(a.properties)))
.enter()
.append("path")
.attr("class", (d) => {
const cla = ["cities"];
const rate = types[config.current].cast(d.properties);
if (rate < -0.2) cla.push("rate-20");
else if (rate < -0.1) cla.push("rate-10");
else if (rate < -0.05) cla.push("rate-5");
else if (rate <= 0.05) cla.push("rate0");
else if (rate <= 0.1) cla.push("rate5");
else if (rate <= 0.2) cla.push("rate10");
else if (rate > 0.2) cla.push("rate20");
return cla.join(" ");
})
.attr("d", path)
.attr("fill", "white")
.on("mouseover", (d, i, nodes) => {
if (config.selected) return;
config.selectedCity = d.properties["市町村名"];
if (config.currentInfo === "得票数") rateForWidth.domain([0, 60000]);
updateInfo();
info.select("#difference")
.text(d3.format("+.1f")(types.difference.cast(d.properties)*100));
info.select("#voter")
.text(d3.format(",")(d.properties["有権者数"]) + "");
info.select("#voterate")
.text(d3.format(".1%")(d.properties["投票率"]));
overlay1.append("path")
.datum(d)
.attr("class", "selected")
.attr("d", path)
.style("stroke", types[config.current].cast(d.properties) >= 0 ? d3.rgb(rateColor.range()[2]).darker() : d3.rgb(rateColor.range()[0]).darker());
})
.on("mouseout", (d, i, nodes) => {
if (config.selected) return;
overlay1.selectAll(".selected")
.remove();
})
.on("click", (d, i, nodes) => {
if (!config.selected) {
config.selected = true;
return;
} else if (config.selectedCity === d.properties["市町村名"]){
config.selected = false;
return;
} else {
overlay1.selectAll(".selected")
.remove();
config.selectedCity = d.properties["市町村名"];
if (config.currentInfo === "得票数") rateForWidth.domain([0, 60000]);
updateInfo();
info.select("#difference")
.text(d3.format("+.1f")(types.difference.cast(d.properties)*100));
info.select("#voter")
.text(d3.format(",")(d.properties["有権者数"]) + "");
info.select("#voterate")
.text(d3.format(".1%")(d.properties["投票率"]));
overlay1.append("path")
.datum(d)
.attr("class", "selected")
.attr("d", path)
.style("stroke", types[config.current].cast(d.properties) >= 0 ? d3.rgb(rateColor.range()[2]).darker() : d3.rgb(rateColor.range()[0]).darker());
}
})
.transition()
.delay((d, i) => i * 50 + 500)
.duration(1000)
.attr("fill", (d) => rateColor(types[config.current].cast(d.properties)));
baselayer.append("path")
.datum(topojson.mesh(json, json.objects.cities, (a, b) => a !== b))
.attr("class", "mesh")
.attr("d", path)
.attr("fill", "none")
.attr("stroke", "#777")
.attr("stroke-width", .5);
baselayer.append("path")
.datum(topojson.mesh(json, json.objects.cities, (a, b) => a === b))
.attr("d", path)
.attr("fill", "none")
.attr("stroke", "black");
// about info
const table = d3.select("#subchart").append("table");
const rows = table.selectAll("tr")
.data(d3.values(candidates))
.enter()
.append("tr");
rows.append("td")
.attr("class", "td-name")
.text(d => d.firstname);
rows.append("td")
.append("div")
.attr("class", "outer")
.append("div")
.attr("class", "inner")
.style("width", 0)
.style("background-color", d => d.color);
rows.selectAll("div.inner")
.transition()
.delay(500).duration(250)
.style("width", d => rateForWidth(d.sum[config.currentInfo]) + "%");
rows.selectAll("div.inner")
.append("span")
.text(d => d3.format(".1f")(d.sum[config.currentInfo] * 100));
d3.selectAll("#info small")
.on("click", (d, i, nodes) => {
if (d3.select(nodes[i]).classed("active")) return;
d3.selectAll(nodes).classed("active", false);
d3.select(nodes[i]).classed("active", true);
config.currentInfo = nodes[i].dataset.guide;
if (config.currentInfo === "得票率") {
rateForWidth.domain([0, 0.6]);
} else if (config.currentInfo === "得票数") {
if (config.selectedCity === "茨城県") {
rateForWidth.domain([0, 500000]);
} else {
rateForWidth.domain([0, 60000]);
}
}
updateInfo();
});
function updateInfo() {
info.select("h4").text(config.selectedCity);
rows.selectAll("div.inner")
.transition().duration(250)
.style("width", v => rateForWidth(v.values[config.selectedCity][config.currentInfo]) + "%");
rows.selectAll("div.inner")
.selectAll("span")
.text(v => config.currentInfo === "得票率" ? d3.format(".1f")(v.values[config.selectedCity][config.currentInfo] * 100) : d3.format(",")(v.values[config.selectedCity][config.currentInfo]));
}
// create legend
size.legend = {
width: Math.max(300, (size.width - padding.left - padding.right) / 2),
padding: {
top: 2
},
bar: {
height: 12
}
};
const legend = svg.append("g")
.attr("transform", "translate(" + ((size.width - size.legend.width) / 2) + "," + (size.height - padding.bottom) + ")");
legend.selectAll(".blocks")
.data([-0.2, -0.1, -0.05, 0, 0.05, 0.1, 0.2])
.enter()
.append("g")
.attr("class", "blocks")
.append("rect")
.attr("width", (d, i, nodes) => size.legend.width / nodes.length - 1)
.attr("height", size.legend.bar.height)
.attr("x", (d, i, nodes) => i * size.legend.width / nodes.length)
.attr("y", size.legend.padding.top)
.attr("fill", d => rateColor(d))
.style("cursor", "pointer")
.on("click", function(d) {
const geojson = {type: "FeatureCollection", features: baselayer.selectAll(".rate" + parseInt(d * 100, 10)).data()};
const topology = topojson.topology({selected: geojson}, 1e6);
const merg = topojson.mesh(topology, topology.objects.selected, (a, b) => a === b);
overlay1.selectAll(".selected")
.remove();
overlay1.append("path")
.datum(merg)
.attr("class", "selected")
.attr("d", path)
.style("stroke", d === 0 ? "#6900ab" : d > 0 ? d3.rgb(rateColor.range()[2]).darker() : d3.rgb(rateColor.range()[0]).darker());
});
legend.selectAll(".blocks")
.append("text")
.attr("x", (d, i, nodes) => d < 0 ? (i + 1) * size.legend.width / nodes.length : i * size.legend.width / nodes.length)
.attr("y", 0)
.attr("dx", d => d < 0 ? ".5em" : "-.5em")
.attr("dy", "-.2em")
.attr("text-anchor", d => d > 0 ? "start" : "end")
.text(d => d !==0 ? (d * 100) : "");
legend.append("text")
.attr("x", 0)
.attr("y", size.legend.padding.top + size.legend.bar.height)
.attr("dy", ".5em")
.attr("text-anchor", "start")
.attr("dominant-baseline", "text-before-edge")
.text("橋本氏優勢");
legend.append("text")
.attr("x", size.legend.width)
.attr("y", size.legend.padding.top + size.legend.bar.height)
.attr("dy", ".5em")
.attr("text-anchor", "end")
.attr("dominant-baseline", "text-before-edge")
.text("大井川氏優勢");
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.