*! version 1.0 23may2014 Sebastian Pink & Sabrina Vogel program define d3network version 11 syntax [using], network(varlist) id(varlist) /// distinction(varlist) nodecov(varlist) /// [nodecov_newnames(string) /// arrows replace] quietly{ * -------------------------------------------------------------------------------------------------- * Preamble1: Save original dataset, generate folder, deal with errors, ... * -------------------------------------------------------------------------------------------------- * Check if d3networks already have been generated and would be overr * ---------------------------------------- loc d3cpwd `c(pwd)' loc d3path: word 2 of `using' if "`d3path'" == "" { if "`replace'" != "replace" { * Check existence of jsondata folder or index.html cap confirm file "index.html" loc indexexists = _rc cap confirm file "./jsondata/nul" if `indexexists' == 0 | _rc == 0 { n: di as err "One or multiple networks already exist. To override, specify the replace option." exit 602 } } * Start out with an empty folder and no index file cap confirm file "index.html" if _rc == 0 { erase "index.html" } cap confirm file "./jsondata/nul" if _rc != 0 { mkdir "jsondata" } else { local d3list: dir "./jsondata/" files "*" foreach d3nwfile of loc d3list { erase `"./jsondata/`d3nwfile'"' } } } else { loc d3path: subinstr loc d3path "\" "/", all cd "`d3path'" if "`replace'" != "replace" { * Check existence of jsondata folder or index.html cap confirm file "index.html" loc indexexists = _rc cap confirm file "./jsondata/nul" if `indexexists' == 0 | _rc == 0 { n: di as err "One or multiple networks already exist. To override, specify the replace option." exit 602 } } * Start out with an empty folder and no index file cap confirm file "`d3path'/index.html" if _rc == 0 { erase "`d3path'/index.html" } cap confirm file "./jsondata/nul" if _rc != 0 { mkdir "`d3path'/jsondata" } else { local d3list: dir "./jsondata/" files "*" foreach d3nwfile of loc d3list { erase `"./jsondata/`d3nwfile'"' } } } * Check for missing values on the nodal characteristics * ----------------------------------------------------- d,s loc d3nodoverall = r(N) foreach d3nodvar of loc nodecov { su `d3nodvar', meanonly if `r(N)' != `d3nodoverall' { n: di as err "Nodal covariate `d3nodvar' exhibits missings. For further information see help file under 'Remarks'." exit 416 } } * Save used dataset * ----------------- tempname d3useddata tempfile `d3useddata' save ``d3useddata'', replace * -------------------------------------------------------------------------------------------------- * -------------------------------------------------------------------------------------------------- * Preamble2: Generate index.html as well as template.html * -------------------------------------------------------------------------------------------------- * (1) index.html to browse through networks * ----------------------------------------- file open index using "index.html", write replace file write index `""' file write index `"Networks"' file write index `""' file write index `""' file write index `"<body><p><a href="Networks.html">Students networks</a>"' file write index `"<a href="Selection.html">Selection of students networks</a></p></body>"' file write index `""' file close index * (2.1) Undirected: template.html to generate the various individual network html files from * ------------------------------------------------------------------------------------------ if "`arrows'" != "arrows" { file open template using "template.html", write replace file write template `""' _n file write template `""' _n file write template `""' _n file write template `" Students networks"' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `"
"' _n file write template `"
"' _n file write template `"
Network: XY
Size of the nodes
VariableSize fromSize to
Color of the nodes
VariableColor toColor from
Label
VariableSize
Color of the links
Link not reciprocalLink reciprocal
Additional information
Nodes =Edges =
"' _n file write template `""' _n file write template `" "' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file close template } * (2.2) Directed: template.html to generate the various individual network html files from * ---------------------------------------------------------------------------------------- if "`arrows'" == "arrows" { file open template using "template.html", write replace file write template `""' _n file write template `""' _n file write template `""' _n file write template `" Students networks"' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `"
"' _n file write template `"
"' _n file write template `"
Network: XY
Size of the nodes
VariableSize fromSize to
Color of the nodes
VariableColor toColor from
Label
VariableSize
Color of the links
Link not reciprocalLink reciprocal
Additional information
Nodes =Edges =
"' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file write template `""' _n file close template } * -------------------------------------------------------------------------------------------------- * Get Stata data to json data (distinct for each network) * ------------------------------------------------------- * Keep only the pertaining network and nodecovariates and rename them keep `distinction' `id' `network' `nodecov' * Nodecov if "`nodecov_newnames'" != "" { forv i = 1/`: word count `nodecov_newnames'' { ren `: word `i' of `nodecov'' `: word `i' of `nodecov_newnames'' } } else loc nodecov_newnames "`nodecov'" loc nodecovariates_sum: word count `nodecov_newnames' * Networkvar unab nwvarlist: `network' loc i = 1 foreach nwvar of loc nwvarlist { ren `nwvar' nwvar`i' loc ++i } * Generate unique grade ids to loop over and to distinguish datasets preserve keep `distinction' duplicates drop `distinction', force sort `distinction' * Save matrix containing the distinction criteria to display them later in menu.html * for better navigatability mkmat `distinction', mat(distinction_names) gen distinction_id = _n tempfile distinction_unique save `distinction_unique', replace restore merge n:1 `distinction' using `distinction_unique', nogen keep(3) su distinction_id, meanonly loc distinction_sum = r(max) compress tempfile fulldata save `fulldata', replace n: di as txt "Processing " as res `distinction_sum' as txt " networks." forv singlenw = 1/`distinction_sum' { * Begin by selecting only the pertaining grade from the selected dataset use `fulldata', clear // select only the pertaining grade keep if distinction_id == `singlenw' * Temporary: Get information about networks qui d,s glo sum_nodes = r(N) * Generate unique ids that d3.js can work with sort `: word 1 of `nodecov_newnames'' `id' gen id_d3js = _n-1 // achtung: richtig? gen name = `id' * Save two versions of this dataset, one for nodes part and one for dyadic part preserve drop nwvar* save "jsondata/fulldata_d3jsids_wonetwork", replace restore preserve loc i = 1 foreach nodecov of loc nodecov_newnames { if `i' != 1 drop `nodecov' loc ++i } save "jsondata/fulldata_d3jsids_wocov", replace restore clear * ------------------------------------------------------------------------------------- * Start first procedure: First nodes and their covariates and then the edgelist to json * ------------------------------------------------------------------------------------- /* Steps: ----- Step 1: Generate list of nodes with characteristics as a json data document Step 2: Generate list of links with characteristics as a json data document and append it to the node list Step 2.1: Change the ids according to the ids needed by d3js Step 2.2: Change the data structure (or format) to the one needed by d3js d3js needs a list of links in long-format, not in wide-format */ * Step 1: List of nodes w/ characteristics * (Important: the d3js wants to have a * succeeding list of nodes, i.e. 0,1,2,3,...,40 not 101,102,...,220) * ----------------------------------------------------------------- + use "jsondata/fulldata_d3jsids_wonetwork", clear file open nodes using "jsondata/network`singlenw'.json", write replace * Header of nodes section file write nodes "{" _n file write nodes `" "nodes" : ["' _n * Retrieve and insert all artists' names qui d,s loc sum_elements = r(N)-1 forv x = 0/`sum_elements' { * Extract person specific characteristics in terms of the variables foreach variable in name `nodecov_newnames' { su `variable' if id_d3js == `x', meanonly loc char_`variable' = r(mean) } * Write each person and their respective characteristics in json format to the json data document (ascii text file) if `x' != `sum_elements' { file write nodes " {" loc i = 1 foreach charname in name `nodecov_newnames' { if `i' < `: word count name `nodecov_newnames'' file write nodes `""`charname'":`char_`charname'', "' if `i' == `: word count name `nodecov_newnames'' file write nodes `""`charname'":`char_`charname''"' loc ++i } file write nodes "}," _n } else { // last entry of all nodes does not end with a comma file write nodes " {" loc i = 1 foreach charname in name `nodecov_newnames' { if `i' < `: word count name `nodecov_newnames'' file write nodes `""`charname'":`char_`charname'', "' if `i' == `: word count name `nodecov_newnames'' file write nodes `""`charname'":`char_`charname''"' loc ++i } file write nodes "}" _n } } * End of nodes section file write nodes "]" _n file write nodes "," _n file close nodes // the file does not contain the ids. This is not necessary as d3js generates them automatically. // However, d3js starts counting ids at 0, not 1. So the first student (id_p = 1 & id_c =1 is the student 0 in d3js) * Step 2: Generate list of links * ------------------------------ + use "jsondata/fulldata_d3jsids_wocov.dta", clear * Step 2.1 * -------- * Generate new id for d3js order id_d3js, first sort id_d3js * Generate temporary concordance list of internal ids (id_internal) and d3js compatible ids (id_d3js) preserve // temporary change in dataset tempfile concordance_list // generate temporary dataset that exists as long as do-file is running keep id_d3js `id' save `concordance_list', replace restore ren id_d3js id_d3js_sender drop `id' * Replace the internal id numbers with d3js compatible id numbers (1,...,40) foreach x of varlist nwvar* { ren `x' `id' qui merge n:1 `id' using `concordance_list', nogen keep(1 3) drop `id' ren id_d3js `x' sort id_d3js_sender } * Step 2.2 * -------- reshape long nwvar@, i(id_d3js_sender) j(newvar) drop newvar drop if mi(nwvar) // If the connection is missing, remove it, because there has not been any nomination ren nwvar id_d3js_receiver sort id_d3js_sender id_d3js_receiver drop if id_d3js_sender == id_d3js_receiver // delete self-nominations (just to be sure) duplicates drop id_d3js_sender id_d3js_receiver, force // duplicates might be due to wrong verification * Generate a characteristic of the links: reciprocity (both people nominated each other) preserve ren id_d3js_sender id_d3js_receiver1 ren id_d3js_receiver id_d3js_sender ren id_d3js_receiver1 id_d3js_receiver sort id_d3js_sender id_d3js_receiver tempfile links_reciprocity save `links_reciprocity', replace restore merge 1:1 id_d3js_sender id_d3js_receiver using `links_reciprocity', keep(1 3) gen reciprocal = _merge == 3 drop _merge sort id_d3js_sender id_d3js_receiver * Temporary: Gen count of Edges qui d,s glo sum_edges = r(N) file open links using "jsondata/network`singlenw'.json", write append * Header of links section file write links `" "links" : ["' _n * Retrieve and insert all artists' names qui d,s loc sum_links = r(N) forv x = 1/`sum_links' { qui su id_d3js_sender if _n == `x' loc source = r(mean) qui su id_d3js_receiver if _n == `x' loc target = r(mean) qui su reciprocal if _n == `x' loc char_reciprocal = r(mean) if `x' != `sum_links' { file write links `" {"source":`source', "target":`target', "reciprocal":`char_reciprocal'},"' _n } else { file write links `" {"source":`source', "target":`target', "reciprocal":`char_reciprocal'}"' _n } } * End of links section file write links "]" _n file write links "}" _n file close links * Get rid of old tempfiles erase "jsondata/fulldata_d3jsids_wonetwork.dta" erase "jsondata/fulldata_d3jsids_wocov.dta" * ---------------------------------------------------------------------------- * Start second procedure: Generate different html files for each grade network * ---------------------------------------------------------------------------- file open template using "template.html", read // template document that is duplicated file read template line file open duplikat using "jsondata/network`singlenw'.html", write replace // duplicate in which only the dataset is changed while r(eof)==0 { if `"`line'"' == `"d3.json("data.json", function(error, json) {"' { file write duplikat `"d3.json("network`singlenw'.json", function(error, json) {"' _n // make new data assignment } else if `"`line'"' == "Nodes =Edges =" { // write some additional information file write duplikat "Nodes =${sum_nodes}Edges =${sum_edges}" } else if `"`line'"' == `"var variables = ["VARIABLES"]"' { // write selected covariates loc i = 1 file write duplikat "var variables = [" foreach newvar of loc nodecov_newnames { if `i' < `nodecovariates_sum' { file write duplikat `""`newvar'", "' } else { file write duplikat `""`newvar'""' } loc ++i } file write duplikat "]" _n } else if `"`line'"' == "Network: XY
Size of the nodes" { file write duplikat `"Network: `singlenw'
Size of the nodes"' _n } else { file write duplikat `"`line'"' _n } file read template line } file close duplikat file close template } erase "template.html" * ---------------------------------------------------------------------------------------------------------- * Start third procedure: Write menu.html containing all networks so that one can browse through them quickly * ---------------------------------------------------------------------------------------------------------- file open menu using "jsondata/menu.html", write replace file write menu `""' _n file write menu `"Selection of the networks"' _n file write menu `"Selection of the networks"' _n file write menu "

To change the current network please select:

" _n forv singlenw = 1/`distinction_sum' { loc distinction_names_loc "" forv distnames = 1/`: word count `distinction'' { if `distnames' < `: word count `distinction'' { loc distinction_names_loc "`distinction_names_loc' `=distinction_names[`singlenw',`distnames']'," } else { loc distinction_names_loc "`distinction_names_loc' `=distinction_names[`singlenw',`distnames']'" } } loc distinction_names_loc = trim("`distinction_names_loc'") file write menu `"Network`singlenw' (`distinction_names_loc')
"' _n } file write menu "" file close menu * Reload data set use ``d3useddata'', clear cd "`d3cpwd'" * Provide neat way to directly view the networks if "`d3path'" == "" { n: di as txt "(output written to {browse index.html})" } else { n: di as txt `"(output written to {browse "`d3path'/index.html"})"' } * Clean up macros and one matrix macro drop sum_nodes sum_edges matrix drop distinction_names } end * End.