"D3.js Practice Tutorial 02" An admission rate ranking based on the Chinese map of the college entrance examination

Source: Internet
Author: User

Learning D3.js (hereinafter referred to as D3) also has a period of time, run D3 do a few projects. I found that Chinese D3 tutorials very few, foreign materials but require a certain degree of English reading ability (recommended site: Http://bl.ocks.org/mbostock), so the germination of writing a D3 practical use of the idea of a series of articles, now began to pay action. In the series, I will use D3+HTML5 canvas to achieve some practical effects (such as statistical results display, map data display, etc.), I hope we can learn to communicate with you.


Code I posted on git.cschina.com, you can clone to local run, address is: Http://git.oschina.net/0604hx/d3lesson

The runtime is Java 7+,tomcat 7.0.47+ (WebSocket is needed later, so javaee7 with Tomcat 7+), the IDE is IntelliJ idea 13, and the project view uses Freemarker.

This chapter is on the map of China to show 2013 years of the mainland provinces college entrance examination of an acceptance rate ranking.


Preparing data

First of all, we need to have the admission rate of the relevant data, I copied from the Internet a statistical data:

2013 admission rate ranked 1 Tianjin 6.3 1.5447 24.52%2 Beijing 7.27 1.7686 24.33%3 Shanghai 5.3 1.2 22.64%4 Qinghai 3.6733 0.6837 18.61%5 Shandong 50.9 9.351 18.37  %6 Ningxia 5.87 1.001 17.05%7 Jilin 15.5 2.2435 14.47%8 Fujian 25.5 3.6186 14.19%9 Guizhou 24.78 3.4369 13.87%10 Zhejiang 31.3 4.1887 13.38%11 Shaanxi 36.65 4.8422 13.21%12 Xinjiang 15.87 2.05 12.92%13 Yunnan 23.6 3.0179 12.79%14 Hainan 5.6 0.6396 11.42%15 Inner Mongolia 19.3 2.163 11.21%16 Gansu 28 .3 2.9598 10.46%17 Anhui 51.1 5.1692 10.12%18 Jiangsu 45.1 4.5085 10.00%19 Hunan  37.3 3.5789 9.59%20 Heilongjiang 20.8 1.9931 9.58%21 Chongqing 2 3.5 2.195 9.34%22 Jiangxi 27.43 2.4891 9.07%23 Hebei 44.98 4.0602 9.03%24 Hubei 43.8 3.5923 8.20%25 Guangxi 29.8 2.3 7.72%26 Henan 71.63 4.86  55 6.79%27 Guangdong 72.7 4.3092 5.93%28 Shanxi 35.8 2.1091 5.89%29 Liaoning 25.4 1.4583 5.74% 304 Sichuan  2.849   5.28%31 Tibet 1.89 0.0904 4.78%
This file can be found in D3lesson.

For a regular TXT data (such as one line of an object), I wrote a conversion tool that can be converted to JSON (JSON format is easier to use in Web pages), Specifically visible: Org.nerve.d3lesson.common.tools.impl.TxtToJSONImporter this class.


Eventually

Finally the following (when the mouse moves to the province can see the specific information)


(according to the admission rate, the higher the color depth of the representative admission rate)


(according to the number of college entrance examination, the color of the more representative of the number of students)

How to achieve? 1. Draw a map of China

The entire map is drawn with the SVG path, so you need to have the appropriate data. JSON data for Chinese maps in/web/data/china.json, we can use the JSON () method of D3 to load the JSON and then draw the map.

Loading method:

D3.json ("{JSON path}", function (data) {//Here is the callback function, if the load succeeds, data is the JSON object//Execute Drawchina method draw map});

Draw function (used here is the Mercator projection, projection adjustment I temporarily did not get thorough, anyway is to the screen to the satisfaction of the location, if there are friends know welcome answer, thank you very much! )

In the drawing process, each province corresponding to the path plus a unique ID, convenient for later calls (such as modifying the color is obtained by the ID path to complete)

Project from latlng to Pixel coords//uses the Mercator projection var projection = D3.geo.mercator ()        . Scale (WIDTH/2)                                   //Zoom to map        . Translate ([WIDTH/2, HEIGHT/2])                 //pan the map to the middle        of the screen. Rotate ([ -110, 0])        . Center ([0, 37.5])                                  //Set Central point, Adjust to the center of the screen;//Draw Geojson to SVG path using the Projectionvar path = D3.geo.path (). projection (projection);//Draw Chinese map function D Rawchina (DS) {    if (!chinag)        Chinag = Container.append ("G");    Chinag.selectall ("path").            data (ds.features).            enter ().            Insert ("path").            attr ("id", function (d ) {                return d.id;            })            . attr ("Fill", "#000000").            attr ("D", Path).            attr (' stroke ', Setting.strokecolor)            . attr (' Stroke-width ') , ' 0.7px ')    ;}

So down and get a map like this


See what's been created in the DOM?


2. Color distribution of Provinces by rank

Next, the provinces will be colored according to the sorting rules. Let's look at what the stats are (the JSON data that was converted in the first step):

{    "_title": "2013 year admission rate ranking",    "datas": [        {            "enter": 1.5447,            "id": "Tianjin",            "index": 1,            "Province": "Tianjin",            "rate": "24.52%",            "Total": 6.3        },        {            "enter": 1.7686,            "id": "Beijing",            "index": 2,            "province": "Beijing",            "rate": "24.33%",            "Total": 7.27        },        {            "enter": 1.2 ,            "id": "Shanghai",            "index": 3,            "province": "Shanghai",            "rate": "22.64%",            "Total": 5.3        },        //.....        The rest is not listed.
Similarly, we use the D3.json () method to load the data and then sort the datas array.

Here's an over-color, that's what I define:

To create an over color, note that the previous step is sorted from large to small, then the color should be from deep to shallow        var ratecolors = d3.scale.linear ()                . Domain ([1, 340])                . Range ([D3.rgb (D3.RGB, 180, 230, 255)]);
Then you can get a color value: ratecolors (index); The index should be between 1 and 340 (of course you can spread larger or smaller), then you get D3.rgb ((), D3.RGB (180, 230, 255) corresponds to a color. such as Index=1 to get D3.rgb (three, three, five), index = 340 to get D3.rgb (in a, 255), index=170 get two end color of the middle color.


The last is to sort the data and then update the color of the corresponding province:

/** * Based on acceptance rate */function Sortbyrate () {//First we need to make the acceptance rate of the data from the big to the small sort//because rates are in xx.xx% format, we need to do a parsefloat operation before comparing Var    data = GkData.datas.sort (function (D1,D2) {return parsefloat (d2.rate)-parsefloat (d1.rate);    }); To create an excessive color, note that the previous step is sorted from large to small, then the color should be from deep to shallow var ratecolors = d3.scale.linear (). Domain ([1, 340]).    Range ([D3.rgb (255, 255, 180)]);         /* Traversal the previous step to get is the array of the ForEach parameter in the D is one of the data traversed, I is the object's subscript ordinal, starting from 0 */Data.foreach (function (d,i) {d.sort = i+1;                Use D.id to get the corresponding provinces on the map of China, because the provinces in the map are named D3.select ("#" + d.id) according to the province pinyin. Transition ()    . Duration (duration). Delay (10*i). attr ("Fill", Ratecolors ((i+1) *10));    });    Buildtip (data); Showontable (data);}    /** * According to the number of people enrolled in the college Entrance Examination */function Sortbytotal () {//First we need to make the acceptance rate of the data from the big to the small sort//because rates are in xx.xx% format, we need to do parsefloat before comparing var data = GkData.datas.sort (function (D1,D2) {return D2.totAl-d1.total;    }); To create an over color, note that the previous step is sorted from large to small, then the color should be from deep to shallow var ratecolors = d3.scale.linear (). Domain ([1, 340]). Range ([D    3.rgb (+, D3.RGB, 255)]);//. Range ([D3.rgb (180, 160, 255)]), and/or.         /* Traversal the previous step to get is the array of the ForEach parameter in the D is one of the data traversed, I is the object's subscript ordinal, starting from 0 */Data.foreach (function (d,i) {d.sort = i+1;                Use D.id to get the corresponding provinces on the map of China, because the provinces in the map are named D3.select ("#" + d.id) according to the province pinyin. Transition ()    . Duration (duration). Delay (10*i). attr ("Fill", Ratecolors ((i+1) *10));    });    Buildtip (data); Showontable (data);}

3. Create a prompt mouse to move to the province, you can display specific information (this function is very useful!) Customer is absolutely needed) first, define the DIV element that works well to display hints
<!--div hint box--><div id= "tooltip" class= "hidden box" >    <p>        <strong class= "Dataholder" name = "Province" ></strong>        rank: <span class= "Dataholder" name= "sort" ></span>    </p>    <div>        entrance: <span class= "Dataholder" name= "Total" ></span>        admission Rate: <span class= " Dataholder "name=" rate ></span>    </div></div>
Then populate the data with D3

/** * Create cue bars * Hints are created in roughly 3 ways * 1: Add a TITLE element to the SVG element, * var t = d3.select (ID). Append ("title"). Text ("I am the cue bar"); * This method does not work well, and hints monotonous * 2: Add mouseover to the element that needs prompting, Mouseout event, when the mouse moves on that element, the cue bar (dynamically created SVG element) is displayed, such as: * var t = D3.selec T (ID);              * T.on (' mouseover ', function () {*//create cue Bar svg.append ("text"). attr ("id", "tooltip")              . attr ("x", D3.event.x). attr ("Y", D3.event.y). attr ("Text-anchor", "Middle")               . attr ("font-family", "Sans-serif"). attr ("Font-size", "11px"). attr ("Font-weight", "bold")            . attr ("? ll", "Black"). Text ("I am an SVG cue bar"); }) *      }); * * 3: Similar to Method 2, but the cue bar is not an SVG element, but a normal HTML element (such as a div), dynamically modify the contents of the prompt box with the x, y coordinates of the prompt box to achieve the effect of the prompt, overall this method is better, more flexible, and can use CSS3,    Also do not worry about the hint box beyond the SVG range of issues * * So, in the tutorial, all use this method */function Buildtip (data) {var t = "#tooltip";   Chinag.selectall ("path"). Data (data, function (d) {return d.id;         }). On ("MouseOver", function (d) {d3.select (T). Style ("left", d3.e                        Vent.x + "px"). Style ("Top", D3.event.y + "px"). Classed ("hidden", false)                            . SelectAll (". Dataholder") [0]. ForEach (function (h) {                            h = d3.select (h);                        H.html (d[h.attr (' name ')]);                })                ;            D3.select (This). attr ("opacity", 0.8);                }). On ("Mouseout", function () {d3.select (T). Classed ("hidden", true);            D3.select (This). attr ("opacity", 1); })    ;}

For detailed code, please go to: Http://git.oschina.net/0604hx/d3lesson


"D3.js Practice Tutorial 02" An admission rate ranking based on the Chinese map of the college entrance examination

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.