46121575bd78653f4443e6a4cbde0af6bb3f674c ceisenhart Wed Jan 13 13:26:30 2016 -0800 Heavy refactoring to the .html output, now all javascript is in the file d3.dendrograms.js, refs# 16216 diff --git src/hg/expMatrixToJson/expMatrixToJson.c src/hg/expMatrixToJson/expMatrixToJson.c index 0bed5b1..742feff 100644 --- src/hg/expMatrixToJson/expMatrixToJson.c +++ src/hg/expMatrixToJson/expMatrixToJson.c @@ -7,31 +7,31 @@ #include "memalloc.h" #include "jksql.h" #include "expData.h" #include "sqlList.h" #include "hacTree.h" #include "rainbow.h" boolean clCSV = FALSE; // Converts the comma separated matrix into a tab based file. boolean clMultiThreads = FALSE; // Allows the user to run the program with multiple threads, default is off. int clThreads = 10; // The number of threads to run with the multiThreads option int clMemLim = 4; // The amount of memeory the program can use, read in Gigabytes. float clLongest = 0; // Used to normalize link distances in rlinkJson. char* clDescFile = NULL; // The user can provide a description file char* clAttributeTable = NULL; // The user can provide an attributes table... this may get removed soon. int nodeCount; //The number of nodes. - +int internalNodes = 0; void usage() /* Explain usage and exit. */ { errAbort( "expMatrixToJson - Takes in an expression matrix and outputs a binary tree clustering the data.\n" " The tree is output as a .json file, a .html file is generated to view the \n" " tree. The files are named using the output argument (ex output.json, output.html).\n" "usage:\n" " expMatrixToJson [options] matrix output\n" "options:\n" " -multiThreads The program will run on multiple threads. \n" " -CSV The input matrix is in .csv format. \n" " -threads=int Sets the thread count for the multiThreads option, default is 10 \n" " -memLim=int Sets the amount of memeory the program can use before aborting. The default is 4G. \n" " -verbose=2 Show basic run stats. \n" @@ -168,70 +168,71 @@ } static void rPrintHierarchicalJson(FILE *f, struct hacTree *tree, int level, double distance) /* Recursively prints out the elements of the hierarchical .json file. */ { struct bioExpVector *bio = (struct bioExpVector *)tree->itemOrCluster; char *tissue = bio->name; struct rgbColor colors = bio->color; if (tree->childDistance > clLongest) /* In practice the first distance will be the longest, and is used for normalization. */ clLongest = tree->childDistance; int i; for (i = 0; i < level; i++) fputc(' ', f); // correct spacing for .json format + // *****LEAVES***** if (tree->left == NULL && tree->right == NULL) // Print the leaf nodes { - if (bio->desc) - fprintf(f, "{\"name\":\"%s\",\"length\":%f,\"distance\":\"%s\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", tissue, (tree->parent->childDistance*tree->parent->childDistance) /1000, bio->desc, colors.r, colors.g, colors.b); - else - fprintf(f, "{\"name\":\"%s\",\"length\":%f,\"distance\":\"%s\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", tissue, tree->parent->childDistance, " ", colors.r, colors.g, colors.b); + fprintf(f, "{\"name\":\"%s\",\"kids\":\"0\",\"length\":\"%f\",\"colorGroup\":\"rgb(%i,%i,%i)\"}", + tissue, tree->parent->childDistance, colors.r, colors.g, colors.b); return; } else if (tree->left == NULL || tree->right == NULL) errAbort("\nHow did we get a node with one NULL kid??"); -// Prints out the node object and opens a new children block. for (i = 0; i < level + 1; i++) fputc(' ', f); distance = tree->childDistance/clLongest; -double temp = 0; + double length = 0; if (tree->parent != NULL) { - temp = tree->parent->childDistance; + length = tree->parent->childDistance; } -fprintf(f, "{\"name\": \" \", \"longestDistance\":\"%f\", \"tpmDistance\": \"%f\", \"length\": %f, \"colorGroup\": \"rgb(%i," - "%i,%i)\",",clLongest,tree->childDistance, temp*temp/1000, colors.r,colors.g,colors.b); + // *****NODES***** + ++internalNodes; + fprintf(f, "{\"name\":\" \", \"number\":\"%i\", \"kids\":\"%i\", \"tpmDistance\": \"%f\", \"length\": \"%f\", \"colorGroup\": \"rgb(%i," + "%i,%i)\",",internalNodes, bio->children , tree->childDistance, length, colors.r,colors.g,colors.b); if (distance != distance) distance = 0; -//fprintf(f, "\"%s\"%s \"%f\"%s\n", "distance", ":", 100*distance, ","); struct rgbColor wTB; struct rgbColor wTBsqrt; struct rgbColor wTBquad; if (distance == 0) { wTB = whiteToBlackRainbowAtPos(0); wTBsqrt = whiteToBlackRainbowAtPos(0); wTBquad = whiteToBlackRainbowAtPos(0); } else { wTB = whiteToBlackRainbowAtPos(distance*.95); wTBsqrt = whiteToBlackRainbowAtPos(sqrt(distance*.95)); wTBquad = whiteToBlackRainbowAtPos(sqrt(sqrt(distance*.95))); } -fprintf(f, "\"distance\": \"%f\", \"whiteToBlack\":\"rgb(%i,%i,%i)\", \"whiteTo", distance, wTB.r, wTB.g, wTB.b); -fprintf(f, "BlackSqrt\":\"rgb(%i,%i,%i)\", \"whiteToBlackQuad\":\"rgb(%i,%i,%i)\",\n", wTBsqrt.r, wTBsqrt.g, wTBsqrt.b, wTBquad.r, wTBquad.g, wTBquad.b); + fprintf(f, "\"normalizedDistance\": \"%f\", \"whiteToBlack\":\"rgb(%i,%i,%i)\", \"whiteTo", + distance, wTB.r, wTB.g, wTB.b); + fprintf(f, "BlackSqrt\":\"rgb(%i,%i,%i)\", \"whiteToBlackQuad\":\"rgb(%i,%i,%i)\",\n", + wTBsqrt.r, wTBsqrt.g, wTBsqrt.b, wTBquad.r, wTBquad.g, wTBquad.b); for (i = 0; i < level + 1; i++) fputc(' ', f); fprintf(f, "\"children\":[\n"); rPrintHierarchicalJson(f, tree->left, level+1, distance); fputs(",\n", f); rPrintHierarchicalJson(f, tree->right, level+1, distance); fputc('\n', f); // Closes the children block for node objects for (i=0; i < level + 1; i++) fputc(' ', f); fputs("]\n", f); for (i = 0; i < level; i++) fputc(' ', f); fputs("}", f); } @@ -331,33 +332,33 @@ { double normalized = distance/total; bio1->color = whiteToBlackRainbowAtPos(normalized); firstLine = FALSE; } //if (distance != distance ) distance = 0 ; //soFar += distance; //double normalized = soFar/total; double normalized = distance/total; if (normalized * 100 >= .95) bio2->color = whiteToBlackRainbowAtPos(.95); else bio2->color = whiteToBlackRainbowAtPos(normalized*100); //bio2->color = saturatedRainbowAtPos(distance); soFar += normalized; } /* Set first color to correspond to 0, since not set in above loop */ -//struct bioExpVector *bio = leafList->val; + struct bioExpVector *bio = leafList->val; //bio->color = saturatedRainbowAtPos(0); -//bio->color = whiteToBlackRainbowAtPos(0.0); + bio->color = whiteToBlackRainbowAtPos(.95); } void convertInput(char *expMatrix, char *descFile, bool csv) /* Takes in a expression matrix and makes the inputs that this program will use. * Namely a transposed table with the first column removed. Makes use of system calls * to use cut, sed, kent utility rowsToCols, and paste (for descFile option). */ { char cmd1[1024], cmd2[1024]; if (csv) /* A sed one liner will convert comma separated values into a tab separated values*/ { char cmd3[1024]; safef(cmd3, 1024, "sed -i 's/,/\\t/g' %s ",expMatrix); verbose(2,"%s\n", cmd3); mustSystem(cmd3); @@ -384,242 +385,82 @@ else { safef(cmd2, 1024, "rowsToCols %s stdout | cut -f1 | sed \'1d\' > %s.cellNames", expMatrix, expMatrix); verbose(2,"%s\n", cmd2); mustSystem(cmd2); } } void generateHtml(FILE *outputFile, int nameSize, char* jsonFile) // Generates a new .html file for the dendrogram. Will do some size calculations as well. { char *pageName = cloneString(jsonFile); chopSuffix(pageName); int textSize = 12 - log(nodeCount); int radius = 540 + 270*log10(nodeCount); + int width = 10 * nodeCount; + int height = 10 * nodeCount; int labelLength = 10+nameSize*(15-textSize); if (labelLength > 100) labelLength = 100; - fprintf(outputFile,"<!DOCTYPE html>\n"); -fprintf(outputFile,"<meta charset=\"utf-8\">\n"); -fprintf(outputFile,"<title>%s</title>\n", pageName); -// CSS styles -fprintf(outputFile,"<style>\n"); -fprintf(outputFile,"\t.node circle{fill: #ff f; stroke: steelblue; stroke-width: .25px;}\n"); -fprintf(outputFile,"\t.node{font: %ipx sans-serif;}\n", textSize); -fprintf(outputFile,"\t.link{fill: none; stroke: #ccc; st roke-width: 1.5px;}\n"); -fprintf(outputFile,"\t.selectedLink{fill: none; stroke: #ccc; stroke-width: 3.0px;}\n"); -fprintf(outputFile,"\t.selected{fill: red;}\n"); -fprintf(outputFile,"\t.legend{font-size: 12px;}\n"); -fprintf(outputFile,"\trect{stroke-width: 2;}\n"); -fprintf(outputFile,"</style>\n"); -// Start body -fprintf(outputFile,"<body>\n"); -// Scripts + fprintf(outputFile,"<head>\n"); + fprintf(outputFile,"<title>New dendrogram tests</title>\n"); fprintf(outputFile,"<link rel=\"stylesheet\" href=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css\">\n"); fprintf(outputFile,"<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n"); fprintf(outputFile,"<script src=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js\"></script>\n"); -fprintf(outputFile,"<script src=\"http://d3js.org/d3.v3.min.js\"></script>\n"); -// Adding dropdowns... -fprintf(outputFile,"<div class = \"dropdown\">\n\t<ul style=\"list-style-type:none;display:inline-flex\">\n"); -// Inner nodes -fprintf(outputFile,"\t\t<li class=\"dropdown\">\n"); -fprintf(outputFile,"\t\t\t<button class=\"btn btn-default dropdown-toggle\" type=\"button\" data-toggle=\"dropdown\"> Inner nodes\n"); -fprintf(outputFile,"\t\t\t<span class=\"caret\"</span></button>\n"); -fprintf(outputFile,"\t\t\t<ul class=\"dropdown-menu\">\n"); -fprintf(outputFile,"\t\t\t\t<li><button onclick=\"nodeColors(0)\">tpm distance</button></li>\n"); -fprintf(outputFile,"\t\t\t\t<li><button onclick=\"nodeColors(1)\">sqrt tpm distance</button></li>\n"); -fprintf(outputFile,"\t\t\t\t<li><button onclick=\"nodeColors(2)\">quad rt tpm distance</button></li>\n"); -fprintf(outputFile,"\t\t\t</ul>\n\t\t</li>\n"); -// Inner leaves -fprintf(outputFile,"\t\t<li class=\"dropdown\">\n"); -fprintf(outputFile,"\t\t\t<button class=\"btn btn-default dropdown-toggle\" type=\"button\" data-toggle=\"dropdown\"> Inner leaves\n"); -fprintf(outputFile,"\t\t\t<span class=\"caret\"</span></button>\n"); -fprintf(outputFile,"\t\t\t<ul class=\"dropdown-menu\">\n"); -fprintf(outputFile,"<! Identifier >\n"); -fprintf(outputFile,"\t\t\t</ul>\n\t\t</li>\n"); -// Middle leaves -fprintf(outputFile,"\t\t<li class=\"dropdown\">\n"); -fprintf(outputFile,"\t\t\t<button class=\"btn btn-default dropdown-toggle\" type=\"button\" data-toggle=\"dropdown\"> Middle leaves\n"); -fprintf(outputFile,"\t\t\t<span class=\"caret\"</span></button>\n"); -fprintf(outputFile,"\t\t\t<ul class=\"dropdown-menu\">\n"); -fprintf(outputFile,"<! Identifier >\n"); -fprintf(outputFile,"\t\t\t</ul>\n\t\t</li>\n"); -// Outer leaves -fprintf(outputFile,"\t\t<li class=\"dropdown\">\n"); -fprintf(outputFile,"\t\t\t<button class=\"btn btn-default dropdown-toggle\" type=\"button\" data-toggle=\"dropdown\"> Outer leaves\n"); -fprintf(outputFile,"\t\t\t<span class=\"caret\"</span></button>\n"); -fprintf(outputFile,"\t\t\t<ul class=\"dropdown-menu\">\n"); -fprintf(outputFile,"<! Identifier >\n"); -fprintf(outputFile,"\t\t\t</ul>\n\t\t</li>\n"); - - -fprintf(outputFile,"\t</ul>\n</div>\n"); -fprintf(outputFile,"<div id=\"graph\"></div>\n"); -// Div the graph + fprintf(outputFile,"<script src=\"http://d3js.org/d3.v3.min.js\" type=\"text/javascript\"></script>\n"); + fprintf(outputFile,"<script src=\"d3.dendrograms1.js\" type=\"text/javascript\"></script>\n"); + fprintf(outputFile,"<div class = \"dropdown\">\n"); + fprintf(outputFile," <div id = dropdown>\n"); + fprintf(outputFile,"</div>\n"); fprintf(outputFile,"<script>\n"); -// Global variables and stuffs -fprintf(outputFile,"\tvar radius= %i / 2;\n", radius); -fprintf(outputFile,"\tvar cluster=d3.layout.cluster().size([360, radius - %i]);\n", labelLength); -fprintf(outputFile,"\tvar colors=d3.scale.category20();\n"); -fprintf(outputFile,"\tvar diagonal=d3.svg.diagonal.radial().projection(function(d){return [d.y, d.x / 180 * Math.PI];});\n"); -fprintf(outputFile,"\tvar svg=d3.select(\"#graph\") .append(\"svg\") .attr(\"width\", 150 + (radius * 2) )\n"); -fprintf(outputFile,"\t\t.attr(\"height\", radius * 2) .append(\"g\") .attr(\"transform\",\n"); -fprintf(outputFile,"\t\t\"translate(\" + (radius + 150) + \",\" + radius + \")\");\n"); -fprintf(outputFile,"\tvar legendRectSize=20;\n"); -fprintf(outputFile,"\tvar legendSpacing=4;\n"); -fprintf(outputFile,"\tvar currentLegend=-1;\n"); -// Start D3 processing -fprintf(outputFile,"\td3.json(\"%s\", function(error, root){\n", jsonFile); -// Variable nodes -fprintf(outputFile,"\t\tvar nodes=cluster.nodes(root);\n\n"); -// Variable link -fprintf(outputFile,"\t\tvar link=svg.selectAll(\"path.link\")\n"); -fprintf(outputFile,"\t\t\t.data(cluster.links(nodes)).enter().append(\"path\")\n"); -fprintf(outputFile,"\t\t\t.attr(\"class\", \"link\").on(\"click\", function(){\n"); -fprintf(outputFile,"\t\t\td3.select(\".selectedLink\").classed(\"selectedLink\", false);\n"); -fprintf(outputFile,"\t\t\td3.select(this).classed(\"selectedLink\", true);}).attr(\"d\", diagonal);\n\n"); -// Graph variables!!! These are parsed by D3 and used to generate the actual dendrogram -// Variable internalNodes -fprintf(outputFile,"\t\tvar internalNodes = svg.selectAll(\"g.internalNode\")\n"); -fprintf(outputFile,"\t\t\t.data(nodes).enter().append(\"g\")\n"); -fprintf(outputFile,"\t\t\t.attr(\"class\", \"internalNode\").attr(\"transform\",\n"); -fprintf(outputFile,"\t\t\tfunction(d){\n"); -fprintf(outputFile,"\t\t\t\treturn \"rotate(\" + (d.x - 90) + \")translate(\" + d.y + \")\";});\n"); -fprintf(outputFile,"\t\t\t\tinternalNodes.append(\"circle\").attr(\"r\", function(d){\n"); -fprintf(outputFile,"\t\t\t\tif (d.name==\" \")\n"); -fprintf(outputFile,"\t\t\t\t{return 5;}\n"); //d.kids;}\n"); -fprintf(outputFile,"\t\t\t\telse{return 0;}})\n"); -fprintf(outputFile,"\t\t\t\t.style(\"fill\", function(d){\n"); -fprintf(outputFile,"\t\t\t\tif (d.name==\" \")\n"); -fprintf(outputFile,"\t\t\t\t{return d.whiteToBlack;}\n"); -fprintf(outputFile,"\t\t\t\telse{return \"none\";}})\n"); -fprintf(outputFile,"\t\t\t\t.style(\"stroke\", \"steelblue\")\n"); -fprintf(outputFile,"\t\t\t\t.style(\"stroke-width\", \"1.25px\");\n\n"); -// Variable innerLeaves -fprintf(outputFile,"\t\tvar innerLeaves = svg.selectAll(\"g.innerLeaf\")\n"); -fprintf(outputFile,"\t\t\t.data(nodes).enter().append(\"g\")\n"); -fprintf(outputFile,"\t\t\t.attr(\"class\", \"innerLeaf\").attr(\"transform\",\n"); -fprintf(outputFile,"\t\t\tfunction(d){\n"); -fprintf(outputFile,"\t\t\t\treturn \"rotate(\" + (d.x - 90) + \")translate(\" + d.y + \")\";});\n"); -fprintf(outputFile,"\t\t\t\tinnerLeaves.append(\"circle\").attr(\"r\", function(d){\n"); -fprintf(outputFile,"\t\t\t\tif (d.name !==\" \")\n"); -fprintf(outputFile,"\t\t\t\t{return 5;}})\n"); -fprintf(outputFile,"\t\t\t\t.style(\"fill\", function(d){\n"); -fprintf(outputFile,"\t\t\t\tif (d.name !==\" \")\n"); -fprintf(outputFile,"\t\t\t\t{return \"d.whiteToBlack\";}\n"); -fprintf(outputFile,"\t\t\t\t})\n\n"); -// Variable middleLeaves -fprintf(outputFile,"\t\tvar middleLeaves = svg.selectAll(\"g.middleLeaf\")\n"); -fprintf(outputFile,"\t\t\t.data(nodes).enter().append(\"g\")\n"); -fprintf(outputFile,"\t\t\t.attr(\"class\", \"middleLeaf\").attr(\"transform\",\n"); -fprintf(outputFile,"\t\t\tfunction(d){\n"); -fprintf(outputFile,"\t\t\t\treturn \"rotate(\" + (d.x - 90) + \")translate(\" + d.y + \")\";});\n"); -fprintf(outputFile,"\t\t\t\tmiddleLeaves.append(\"circle\").attr(\"r\", 5).style(\"fill\",\"none\");\n\n"); -// Variable outerLeaves -fprintf(outputFile,"\t\tvar outerLeaves = svg.selectAll(\"g.outerLeaf\")\n"); -fprintf(outputFile,"\t\t\t.data(nodes).enter().append(\"g\")\n"); -fprintf(outputFile,"\t\t\t.attr(\"class\", \"outerLeaf\").attr(\"transform\",\n"); -fprintf(outputFile,"\t\t\tfunction(d){\n"); -fprintf(outputFile,"\t\t\t\treturn \"rotate(\" + (d.x - 90) + \")translate(\" + d.y + \")\";});\n"); -fprintf(outputFile,"\t\t\t\touterLeaves.append(\"circle\").attr(\"r\", 5).style(\"fill\",\"none\");\n\n"); -// Legend variables!!! These are parsed by D3 and used to generate the legends -// Variable innerLegend -fprintf(outputFile,"\t\t\tvar innerLegend=svg.selectAll('.innerLegend') .data(colors.domain()) .enter()\n"); -fprintf(outputFile,"\t\t\t.append('g') .attr('class', 'innerLegend')\n"); -fprintf(outputFile,"\t\t\t.attr('transform', \n"); -fprintf(outputFile,"\t\t\tfunction (d, i){\n"); -fprintf(outputFile,"\t\t\t\tvar height=legendRectSize + legendSpacing;\n"); -fprintf(outputFile,"\t\t\t\tvar offset=height * colors.domain().length / 2;\n"); -fprintf(outputFile,"\t\t\t\tvar horz=-2 * legendRectSize;\n"); -fprintf(outputFile,"\t\t\t\tvar vert=i * height - offset;\n"); -fprintf(outputFile,"\t\t\t\treturn 'translate(' + horz + ',' + vert + ')';}\n"); -fprintf(outputFile,"\t\t\t);\n"); -fprintf(outputFile,"\t\t\tinnerLegend.append('rect') .attr('width', legendRectSize) .attr('height', legendRectSize)\n"); -fprintf(outputFile,"\t\t\t.style('fill', colors) .style('stroke', colors);\n"); -fprintf(outputFile,"\t\t\tinnerLegend.append('text') .attr('x', legendRectSize + legendSpacing)\n"); -fprintf(outputFile,"\t\t\t.attr('y', legendRectSize - legendSpacing) .text(function (d){return d;});\n\n"); -// Variable middleLegend -fprintf(outputFile,"\t\t\tvar middleLegend=svg.selectAll('.middleLegend') .data(colors.domain()) .enter()\n"); -fprintf(outputFile,"\t\t\t.append('g') .attr('class', 'middlerLegend')\n"); -fprintf(outputFile,"\t\t\t.attr('transform', \n"); -fprintf(outputFile,"\t\t\tfunction (d, i){\n"); -fprintf(outputFile,"\t\t\t\tvar height=legendRectSize + legendSpacing;\n"); -fprintf(outputFile,"\t\t\t\tvar offset=height * colors.domain().length / 2;\n"); -fprintf(outputFile,"\t\t\t\tvar horz=-2 * legendRectSize;\n"); -fprintf(outputFile,"\t\t\t\tvar vert=i * height - offset;\n"); -fprintf(outputFile,"\t\t\t\treturn 'translate(' + horz + ',' + vert + ')';}\n"); -fprintf(outputFile,"\t\t\t);\n"); -fprintf(outputFile,"\t\t\tmiddleLegend.append('rect') .attr('width', legendRectSize) .attr('height', legendRectSize)\n"); -fprintf(outputFile,"\t\t\t.style('fill', colors) .style('stroke', colors);\n"); -fprintf(outputFile,"\t\t\tmiddleLegend.append('text') .attr('x', legendRectSize + legendSpacing)\n"); -fprintf(outputFile,"\t\t\t.attr('y', legendRectSize - legendSpacing) .text(function (d){return d;});\n\n"); -// Variable outerLegend -fprintf(outputFile,"\t\t\tvar outerLegend=svg.selectAll('.outerLegend') .data(colors.domain()) .enter()\n"); -fprintf(outputFile,"\t\t\t.append('g') .attr('class', 'outerLegend')\n"); -fprintf(outputFile,"\t\t\t.attr('transform', \n"); -fprintf(outputFile,"\t\t\tfunction (d, i){\n"); -fprintf(outputFile,"\t\t\t\tvar height=legendRectSize + legendSpacing;\n"); -fprintf(outputFile,"\t\t\t\tvar offset=height * colors.domain().length / 2;\n"); -fprintf(outputFile,"\t\t\t\tvar horz=-2 * legendRectSize;\n"); -fprintf(outputFile,"\t\t\t\tvar vert=i * height - offset;\n"); -fprintf(outputFile,"\t\t\t\treturn 'translate(' + horz + ',' + vert + ')';}\n"); -fprintf(outputFile,"\t\t\t);\n"); -fprintf(outputFile,"\t\t\touterLegend.append('rect') .attr('width', legendRectSize) .attr('height', legendRectSize)\n"); -fprintf(outputFile,"\t\t\t.style('fill', colors) .style('stroke', colors);\n"); -fprintf(outputFile,"\t\t\touterLegend.append('text') .attr('x', legendRectSize + legendSpacing)\n"); -fprintf(outputFile,"\t\t\t.attr('y', legendRectSize - legendSpacing) .text(function (d){return d;});\n\n"); -fprintf(outputFile,"\t\t\t});\n"); -// Function updateLegend -fprintf(outputFile,"\tfunction updateLegend(val, layer, shift){\n"); -fprintf(outputFile,"\t\tvar legend=svg.selectAll('g.'+layer+'legend').data(val);\n"); -fprintf(outputFile,"\t\tlegend.enter() .append('g') .attr('class', 'legend') .attr('transform', function (d, i){\n"); -fprintf(outputFile,"\t\t\tvar height=legendRectSize + legendSpacing;\n"); -fprintf(outputFile,"\t\t\tvar offset=height *colors.domain().length / 2;\n"); -fprintf(outputFile,"\t\t\tvar horz=(-2 * legendRectSize) - radius - 75;\n"); -fprintf(outputFile,"\t\t\tvar vert=-(i * height - offset);\n"); -fprintf(outputFile,"\t\t\treturn 'translate(' + horz + ',' + vert + ')';});\n"); -fprintf(outputFile,"\t\tlegend.append('rect') .attr('width', legendRectSize) .attr('height', legendRectSize)\n"); -fprintf(outputFile,"\t\t.style('fill', colors) .style('stroke', colors);\n"); -fprintf(outputFile,"\t\tlegend.append('text') .attr('x', legendRectSize + legendSpacing)\n"); -fprintf(outputFile,"\t\t.attr('y', legendRectSize - legendSpacing) .text(function (d){return d;});}\n\n"); -// Function leafColors -fprintf(outputFile,"\tfunction leafColors(val, layer, shift){\n"); -fprintf(outputFile,"\t\tvar node = svg.selectAll(\"g.\" + layer + \"Leaf\")\n"); -fprintf(outputFile,"\t\t.selectAll(\"circle\").style(\"fill\", function(d){\n"); -fprintf(outputFile,"\t\t\tif (d.name !== \" \"){\n"); -fprintf(outputFile,"\t\t\t\tif (val ===0) {return d3.rgb(d.colorGroup);}\n"); -fprintf(outputFile,"\t\t /* Identifier */\n"); -fprintf(outputFile,"\t\t\t}\n"); -fprintf(outputFile,"\t\t\t\telse{return 'none'}});\n"); -fprintf(outputFile,"\t\tvar legend=svg.selectAll('g.' + layer + 'Legend').remove();\n"); -fprintf(outputFile,"\t\tif (val >= 0) updateLegend(colors.domain(), layer);\n"); -fprintf(outputFile,"\t\tcolors=d3.scale.category20();}\n\n"); -// Function nodeColors -fprintf(outputFile,"\tfunction nodeColors(val){\n"); -fprintf(outputFile,"\t\tvar node=svg.selectAll(\"g.internalNode\").selectAll(\"circle\")\n"); -fprintf(outputFile,"\t\t.style(\"fill\",function(d){\n"); -fprintf(outputFile,"\t\t\tif (d.name === \" \"){\n"); -fprintf(outputFile,"\t\t\t\tif (val==-1) return d3.rgb(d.colorGroup);\n"); -fprintf(outputFile,"\t\t\t\tif (val==0) return d3.rgb(d.whiteToBlack);\n"); -fprintf(outputFile,"\t\t\t\tif (val==1) return d3.rgb(d.whiteToBlackSqrt);\n"); -fprintf(outputFile,"\t\t\t\tif (val==2) return d3.rgb(d.whiteToBlackQuad);\n"); -fprintf(outputFile,"}});\n"); -fprintf(outputFile,"\t\t}\n"); + fprintf(outputFile," function load() {\n"); + fprintf(outputFile," var data;\n\n"); + fprintf(outputFile," d3.json(\"testClustersWMeta.json\", function(error,json){\n"); + fprintf(outputFile," if (error) return console.warn(error);\n"); + fprintf(outputFile," data = json;\n"); + fprintf(outputFile," d3.dendrogram.makeCartesianDendrogram('#phylogram', data, {\n"); + fprintf(outputFile," width: %i,\n", width); + fprintf(outputFile," height: %i,\n", height); + fprintf(outputFile," });\n\n"); + fprintf(outputFile," d3.dendrogram.makeRadialDendrogram('#dendrogram', data,{\n"); + fprintf(outputFile," radius: %i,\n", radius); + fprintf(outputFile," });\n"); + fprintf(outputFile," });\n"); + fprintf(outputFile," }\n"); fprintf(outputFile,"</script>\n"); -fprintf(outputFile,"</body>"); + fprintf(outputFile,"<style type=\"text/css\" media=\"screen\">\n"); + fprintf(outputFile," body { font-family: \"Helvetica Neue\", Helvetica, sans-serif; }\n"); + fprintf(outputFile," td { vertical-align: top; }\n"); + fprintf(outputFile,"</style>\n"); + fprintf(outputFile,"</head>\n"); + fprintf(outputFile,"<body onload=\"load()\">\n"); + fprintf(outputFile,"<table>\n"); + fprintf(outputFile," <tr>\n"); + fprintf(outputFile," <td>\n"); + fprintf(outputFile," <h1>Phylogram</h2>\n"); + fprintf(outputFile," <div id='phylogram'></div>\n"); + fprintf(outputFile," </td>\n"); + fprintf(outputFile," <td>\n"); + fprintf(outputFile," <h1>Dendrogram</h1>\n"); + fprintf(outputFile," <div id='dendrogram'></div>\n"); + fprintf(outputFile," </td>\n"); + fprintf(outputFile," </tr>\n"); + fprintf(outputFile,"</table>\n"); + fprintf(outputFile,"</body>\n"); + fprintf(outputFile,"</html>\n"); carefulClose(&outputFile); } void expData(char *matrixFile, char *outDir, char *descFile) /* Read matrix and names into a list of bioExpVectors, run hacTree to * associate them, and write output. */ { verbose(2,"Start binary clustering of the expression matrix by euclidean distance (expMatrixToJson).\n"); clock_t begin, end; begin = clock(); convertInput(matrixFile, descFile, clCSV); @@ -646,31 +487,30 @@ struct slRef *orderedList = getOrderedLeafList(clusters); colorLeaves(orderedList); printHierarchicalJson(f, clusters); FILE *htmlF = mustOpen(catTwoStrings(outDir,".html"),"w"); generateHtml(htmlF,size,catTwoStrings(outDir,".json")); // Remove temporary files char cleanup[1024], cleanup2[1024]; safef(cleanup, 1024, "rm %s.cellNames", matrixFile); safef(cleanup2, 1024, "rm %s.transposedMatrix", matrixFile); mustSystem(cleanup); mustSystem(cleanup2); end = clock(); verbose(2,"%lld allocated at end. The program took %f seconds to complete.\n", (long long)carefulTotalAllocated(), (double)(end-begin)/CLOCKS_PER_SEC); - verbose(2,"Completed binary clustering of the expression matrix by euclidean distance (expMatrixToJson).\n"); } int main(int argc, char *argv[]) /* Process command line. */ { optionInit(&argc, argv, options); clCSV = optionExists("CSV"); clMultiThreads = optionExists("multiThreads"); clThreads = optionInt("threads", clThreads); clMemLim = optionInt("memLim", clMemLim); clDescFile = optionVal("descFile", clDescFile); if (argc != 3) usage(); pushCarefulMemHandler(1L*1024*1024*1024*clMemLim);