Built with blockbuilder.org
xxxxxxxxxx
<html>
<head>
<script src="https://d3js.org/d3.v3.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<style>
body {
padding-top: 60px;
text-align: center;
}
@media (max-width: 979px) {
body {
padding-top: 0px;
}
}
.label {
font-family: sans-serif;
font-size: 13px;
}
.buttonText {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none; /* non-prefixed version, currently
not supported by any browser */
}
<!-- .dotPlot {
display: block;
margin-left: auto;
margin-right: auto;
} -->
.selButtons {
display: inline-block;
}
h2 { text-align: center; }
.cancerButton {
cursor: pointer; cursor: hand;
fill-opacity: 0.3;
}
.treatmentButton {
cursor: pointer; cursor: hand;
fill-opacity: 0.3;
}
.recolorButton {
cursor: pointer; cursor: hand;
fill-opacity: 0.3;
}
.resetButton{
color: #0000EE;
display: inline;
float: right;
margin-left: 10px;
font-size: 14px;
}
.clearButton{
color: #0000EE;
display: inline;
float: right;
font-size: 14px;
}
.buttonText {
alignment-baseline: middle;
text-anchor: middle;
}
.recolorButtonText {
alignment-baseline: middle;
text-anchor: middle;
font-size: 11px;
}
.recolorButton.selected{
fill: #eeeeee;
}
.hover {
//fill-opacity: 0.7 !important;
}
.selected {
fill-opacity: 1;
}
</style>
<body>
<div class="container-fluid">
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<span class="navbar-brand">Patient Viewer</span>
</div>
<div id="navbar" class="collapse navbar-collapse">
</div><!--/.nav-collapse -->
</div>
</nav>
</div>
<div class="container-fluid">
<div class="tab-content">
<div class="tab-pane active" id="tab_newGraphic">
<h2 style="align: center">Weekly Patient Volume</h2>
<div class="row">
<div class="dotPlot"></div>
</div>
<div class="row">
<div class="selButtons selCancer well">
<h4>Cancer Type</h4>
</div>
<div class="selButtons selTreatment well">
<h4>Treatment Modality</h4>
</div>
</div>
</div>
<div class="tab-pane" id="tab_oldGraphic">
<h2>The Original Data Viz</h2>
<img src="https://oncoramedical.com/assets/images/screenshots/donut_hist.gif" alt="Original Viz">
</div>
<div class="tab-pane" id="tab_whatChanged">
Nothing Here Either
</div>
</div>
</div>
<script>
// --- Define Functions ----------------------------------------------
// Data Filtering -- filters for button click
function filterOnClick(data, passThis){
//Helper function for getting data from D3 selection
function getSelDataFromObj(selClass){
var selDataObj = d3.selectAll(".selected").filter(selClass)["0"];
var selDataArray = [];
for(var property in selDataObj){
if (selDataObj.hasOwnProperty(property) && property !== "parentNode") {
selDataArray.push(selDataObj[property].__data__);
}
}
return selDataArray;
};
var pressedResetButton = d3.select(passThis).classed("resetButton");
var pressedClearButton = d3.select(passThis).classed("clearButton");
var pressedCancerButton = d3.select(passThis).classed("cancerButton");
var pressedTreatButton = d3.select(passThis).classed("treatmentButton");
// If reset button is pressed, turn all selections on
if( pressedResetButton && pressedCancerButton ){
d3.selectAll(".cancerButton").classed("selected", true);
d3.select(passThis).classed("selected", false);
}else if( pressedResetButton && pressedTreatButton ) {
d3.selectAll(".treatmentButton").classed("selected", true);
d3.select(passThis).classed("selected", false);
}else
// If clear button is pressed, turn all selections off
if( pressedClearButton && pressedCancerButton ){
d3.selectAll(".cancerButton").classed("selected", false);
d3.select(passThis).classed("selected", false);
}else if( pressedClearButton && pressedTreatButton ) {
d3.selectAll(".treatmentButton").classed("selected", false);
d3.select(passThis).classed("selected", false);
}else{
// If not reset button...
var allCancersSelected = d3.selectAll(".cancerButton").filter(".selected").size() === cancerTypes.length
var allTreatsSelected = d3.selectAll(".treatmentButton").filter(".selected").size() === treatmentTypes.length
// If it's the first button selected in a group, leave it on and turn everything else off; otherwise, toggle the button
if( allCancersSelected && pressedCancerButton ){
d3.selectAll(".cancerButton").classed("selected", false);
d3.select(passThis).classed("selected", true);
}else if( allTreatsSelected && pressedTreatButton ){
d3.selectAll(".treatmentButton").classed("selected", false);
d3.select(passThis).classed("selected", true);
}else if( d3.select(passThis).classed("selected") ){
d3.select(passThis).classed("selected", false);
}else{
d3.select(passThis).classed("selected", true);
}}
// Main Function
var selCancerArray = getSelDataFromObj(".cancerButton");
var selTreatArray = getSelDataFromObj(".treatmentButton");
data = data.filter(
function(obj){
return ($.inArray(obj.cancerType, selCancerArray) > -1) &&
($.inArray(obj.treatmentModality, selTreatArray) > -1);
}
);
return data;
};
// Drawer function
function redraw(data){
var colorBy = d3.selectAll(".recolorButton").filter(".selected").data();
if(colorBy[0] === "Cancer Type"){
sortBy = "cancerType";
data = data.sort(sortByCancerFreqThenWeek);
}else if(colorBy[0] === "Treatment Modality"){
sortBy = "treatmentModality";
data = data.sort(sortByTreatmentFreqThenWeek);
}
data = accumWeeks(data);
// Join Data
var dots = dotGraphic.selectAll("circle")
.data(data, function(d) {return d.visitId})
console.log(dots)
// UPDATE
dots
.transition()
//.delay(function(d,i){ return Math.random()*8*dots.enter().size();})
.attr("cy", function(d){ return yScale_dot(d.accWeek);})
.attr("fill", function(d){ return colorScale_active(d[sortBy])});
// ENTER
dots.enter()
.append("circle")
.attr("cx", function(d) { return xScale_dot(d.week)})
.attr("cy", -100)
.attr("fill", function(d) {return colorScale_active(d[sortBy])})
.attr("r",5)
.transition()
.delay(function(d,i){
return Math.random()*8*dots.enter().size();})
.attr("cy", function(d){ return yScale_dot(d.accWeek);});
// EXIT
dots.exit()
.transition(1250)
.attr("fill-opacity", 1e-6)
.remove()
}
// Recolor function
function recolor(data){
var iColor = $.inArray(data, colorOptions);
// Update selection
d3.selectAll(".recolorButton").classed("selected", false);
d3.selectAll(".recolorButton")
.filter(function(d,i){return i===iColor;}).classed("selected", true);
if(iColor===0){
colorScale_active = colorScale_cancer;
cancerButtons.attr("fill", "#000000");
cancerButton_shapes
.attr("fill", function(d,i){return colorScale_active(d);});
treatmentButtons.attr("fill", "#000000");
treatmentButton_shapes
.attr("fill", function(d,i){return colorScale_inactive(d);});
}else if(iColor===1){
colorScale_active = colorScale_treatment;
cancerButtons.attr("fill", "#000000");
cancerButton_shapes
.attr("fill", function(d,i){return colorScale_inactive(d);});
treatmentButtons.attr("fill", "#000000");
treatmentButton_shapes
.attr("fill", function(d,i){return colorScale_active(d);})
}else if(iColor===2){
colorScale_active = colorScale_oneColor
cancerButtons.attr("fill", "#eeeeee");
cancerButton_shapes
.attr("fill", function(d,i){return colorScale_active(d);});
treatmentButtons.attr("fill", "#eeeeee");
treatmentButton_shapes
.attr("fill", function(d,i){return colorScale_active(d);});
}
redraw(visitData)
}
// Sorting Functions
function sortByCancerFreqThenWeek(a,b){
var typeLen_a = visitsByCancer[a.cancerType].length;
var typeLen_b = visitsByCancer[b.cancerType].length;
if(a.week === b.week){
if(typeLen_b === typeLen_a){
return a.visitId - b.visitId;
}
return typeLen_b - typeLen_a;
}
return a.week - b.week;
};
function sortByTreatmentFreqThenWeek(a,b){
var treatLen_a = visitsByTreatment[a.treatmentModality].length;
var treatLen_b = visitsByTreatment[b.treatmentModality].length;
if(a.week === b.week){
if(treatLen_b === treatLen_a){
return a.visitId - b.visitId;
}
return treatLen_b - treatLen_a;
}
return a.week - b.week;
};
function sortByLength(anObject) {
return function(a,b) {
return anObject[b].length - anObject[a].length;
};
};
// Ennumerate visit count per week (after sorting) -- used as y pos value
function accumWeeks(sortedVisitData){
if(sortedVisitData.length === 0){return sortedVisitData};
sortedVisitData[0].accWeek = 1;
for(i = 1; i < sortedVisitData.length; i++){
if(sortedVisitData[i].week === sortedVisitData[i-1].week){
sortedVisitData[i].accWeek = sortedVisitData[i-1].accWeek + 1;
}else{
sortedVisitData[i].accWeek = 1;
}
}
return sortedVisitData
};
// Path creator to make rounded rectangle
function createPillButton(x, y, width, height, radius) {
var x = typeof x !== 'undefined' ? x : 0;
var y = typeof y !== 'undefined' ? y : 0;
var width = typeof width !== 'undefined' ? width : 120;
var height = typeof height !== 'undefined' ? height : 40;
var radius = typeof radius !== 'undefined' ? radius : 10;
return "M" + x + "," + y
+ "h" + (width - radius)
+ "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius
+ "v" + (height - 2 * radius)
+ "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius
+ "h" + (radius - width)
+ "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + -radius
+ "v" + (2 * radius - height)
+ "a" + radius + "," + radius + " 0 0 1 " + radius + "," + -radius
+ "z";
}
//---------------------------------------------------------------------
//--- Data & Data Manipulation ----------------------------------------
// Hardcode data (for convenience) generated by separate R script
var visitData_full = [{"visitId":1,"week":9,"cancerType":"Leukaemia","treatmentModality":"Proton"},{"visitId":2,"week":46,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":3,"week":23,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":4,"week":46,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"Proton"},{"visitId":5,"week":13,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":6,"week":12,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":7,"week":5,"cancerType":"Lung","treatmentModality":"3D CRT"},{"visitId":8,"week":9,"cancerType":"Lung","treatmentModality":"3D CRT"},{"visitId":9,"week":16,"cancerType":"Lung","treatmentModality":"3D CRT"},{"visitId":10,"week":33,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":11,"week":2,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":12,"week":6,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":13,"week":13,"cancerType":"Bladder","treatmentModality":"IMRT"},{"visitId":14,"week":16,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":15,"week":31,"cancerType":"Malignant Melanoma","treatmentModality":"IMRT"},{"visitId":16,"week":20,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":17,"week":26,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"3D CRT"},{"visitId":18,"week":15,"cancerType":"Malignant Melanoma","treatmentModality":"3D CRT"},{"visitId":19,"week":13,"cancerType":"Bladder","treatmentModality":"IMRT"},{"visitId":20,"week":33,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":21,"week":3,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":22,"week":2,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":23,"week":2,"cancerType":"Lung","treatmentModality":"IMRT"},{"visitId":24,"week":19,"cancerType":"Bladder","treatmentModality":"IMRT"},{"visitId":25,"week":40,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":26,"week":38,"cancerType":"Malignant Melanoma","treatmentModality":"Proton"},{"visitId":27,"week":3,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":28,"week":13,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"3D CRT"},{"visitId":29,"week":50,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":30,"week":15,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":31,"week":14,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":32,"week":31,"cancerType":"Brain","treatmentModality":"IMRT"},{"visitId":33,"week":2,"cancerType":"Uterus","treatmentModality":"IMRT"},{"visitId":34,"week":31,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"Proton"},{"visitId":35,"week":26,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":36,"week":21,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":37,"week":8,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":38,"week":35,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":39,"week":46,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":40,"week":1,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":41,"week":42,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":42,"week":24,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":43,"week":17,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":44,"week":33,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":45,"week":4,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":46,"week":21,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":47,"week":48,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"IMRT"},{"visitId":48,"week":5,"cancerType":"Malignant Melanoma","treatmentModality":"Proton"},{"visitId":49,"week":14,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":50,"week":50,"cancerType":"Malignant Melanoma","treatmentModality":"3D CRT"},{"visitId":51,"week":18,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"3D CRT"},{"visitId":52,"week":17,"cancerType":"Malignant Melanoma","treatmentModality":"Proton"},{"visitId":53,"week":4,"cancerType":"Bladder","treatmentModality":"Proton"},{"visitId":54,"week":47,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":55,"week":52,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":56,"week":20,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":57,"week":35,"cancerType":"Malignant Melanoma","treatmentModality":"Proton"},{"visitId":58,"week":39,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":59,"week":7,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":60,"week":25,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"Proton"},{"visitId":61,"week":34,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":62,"week":1,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":63,"week":35,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":64,"week":9,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":65,"week":10,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":66,"week":6,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":67,"week":47,"cancerType":"Malignant Melanoma","treatmentModality":"Proton"},{"visitId":68,"week":8,"cancerType":"Malignant Melanoma","treatmentModality":"SBRT"},{"visitId":69,"week":18,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":70,"week":50,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":71,"week":19,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":72,"week":14,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":73,"week":22,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"IMRT"},{"visitId":74,"week":16,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":75,"week":5,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":76,"week":23,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":77,"week":48,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":78,"week":36,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":79,"week":10,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":80,"week":9,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":81,"week":40,"cancerType":"Lung","treatmentModality":"3D CRT"},{"visitId":82,"week":47,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":83,"week":12,"cancerType":"Malignant Melanoma","treatmentModality":"SBRT"},{"visitId":84,"week":22,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":85,"week":40,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":86,"week":5,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"SBRT"},{"visitId":87,"week":18,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":88,"week":17,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":89,"week":35,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"IMRT"},{"visitId":90,"week":29,"cancerType":"Lung","treatmentModality":"3D CRT"},{"visitId":91,"week":16,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":92,"week":47,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":93,"week":19,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":94,"week":36,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":95,"week":20,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":96,"week":19,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":97,"week":4,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":98,"week":19,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":99,"week":45,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":100,"week":51,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":101,"week":19,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":102,"week":19,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":103,"week":40,"cancerType":"Malignant Melanoma","treatmentModality":"Proton"},{"visitId":104,"week":40,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":105,"week":24,"cancerType":"Malignant Melanoma","treatmentModality":"IMRT"},{"visitId":106,"week":11,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":107,"week":23,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":108,"week":24,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":109,"week":21,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":110,"week":8,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":111,"week":29,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":112,"week":51,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":113,"week":47,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":114,"week":31,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":115,"week":25,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":116,"week":21,"cancerType":"Lung","treatmentModality":"IMRT"},{"visitId":117,"week":46,"cancerType":"Malignant Melanoma","treatmentModality":"3D CRT"},{"visitId":118,"week":42,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":119,"week":38,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":120,"week":39,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":121,"week":1,"cancerType":"Lung","treatmentModality":"IMRT"},{"visitId":122,"week":38,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":123,"week":26,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":124,"week":49,"cancerType":"Lung","treatmentModality":"SBRT"},{"visitId":125,"week":40,"cancerType":"Lung","treatmentModality":"IMRT"},{"visitId":126,"week":24,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":127,"week":36,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":128,"week":37,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":129,"week":11,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":130,"week":29,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":131,"week":33,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":132,"week":15,"cancerType":"Malignant Melanoma","treatmentModality":"3D CRT"},{"visitId":133,"week":7,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":134,"week":30,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":135,"week":6,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":136,"week":32,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":137,"week":45,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":138,"week":36,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":139,"week":26,"cancerType":"Malignant Melanoma","treatmentModality":"SBRT"},{"visitId":140,"week":8,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":141,"week":40,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":142,"week":27,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":143,"week":44,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":144,"week":25,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":145,"week":48,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":146,"week":28,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":147,"week":21,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":148,"week":25,"cancerType":"Lung","treatmentModality":"3D CRT"},{"visitId":149,"week":23,"cancerType":"Malignant Melanoma","treatmentModality":"IMRT"},{"visitId":150,"week":33,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":151,"week":7,"cancerType":"Bladder","treatmentModality":"Proton"},{"visitId":152,"week":49,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":153,"week":16,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":154,"week":37,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":155,"week":40,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":156,"week":34,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":157,"week":39,"cancerType":"Malignant Melanoma","treatmentModality":"IMRT"},{"visitId":158,"week":45,"cancerType":"Malignant Melanoma","treatmentModality":"IMRT"},{"visitId":159,"week":23,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":160,"week":32,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"IMRT"},{"visitId":161,"week":39,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":162,"week":17,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":163,"week":31,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":164,"week":44,"cancerType":"Breast","treatmentModality":"Proton"},{"visitId":165,"week":21,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":166,"week":47,"cancerType":"Kidney","treatmentModality":"3D CRT"},{"visitId":167,"week":5,"cancerType":"Lung","treatmentModality":"SBRT"},{"visitId":168,"week":14,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":169,"week":46,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":170,"week":36,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":171,"week":14,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":172,"week":1,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":173,"week":15,"cancerType":"Malignant Melanoma","treatmentModality":"SBRT"},{"visitId":174,"week":51,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":175,"week":16,"cancerType":"Lung","treatmentModality":"SBRT"},{"visitId":176,"week":20,"cancerType":"Prostate","treatmentModality":"SBRT"},{"visitId":177,"week":22,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":178,"week":29,"cancerType":"Non-Hodgkin Lympoma","treatmentModality":"IMRT"},{"visitId":179,"week":5,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":180,"week":17,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":181,"week":44,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":182,"week":13,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":183,"week":48,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":184,"week":38,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":185,"week":11,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":186,"week":3,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":187,"week":15,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":188,"week":26,"cancerType":"Breast","treatmentModality":"SBRT"},{"visitId":189,"week":50,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":190,"week":9,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":191,"week":19,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":192,"week":23,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":193,"week":15,"cancerType":"Prostate","treatmentModality":"IMRT"},{"visitId":194,"week":10,"cancerType":"Lung","treatmentModality":"Proton"},{"visitId":195,"week":42,"cancerType":"Pancreas","treatmentModality":"IMRT"},{"visitId":196,"week":13,"cancerType":"Prostate","treatmentModality":"Proton"},{"visitId":197,"week":46,"cancerType":"Prostate","treatmentModality":"3D CRT"},{"visitId":198,"week":3,"cancerType":"Breast","treatmentModality":"IMRT"},{"visitId":199,"week":9,"cancerType":"Breast","treatmentModality":"3D CRT"},{"visitId":200,"week":16,"cancerType":"Brain","treatmentModality":"IMRT"}];
// Visit data chunked by cancer types
var visitsByCancer = d3.nest()
.key(function(d) {return d.cancerType;})
.map(visitData_full);
// Visit data chunked by treament types
var visitsByTreatment = d3.nest()
.key(function(d) {return d.treatmentModality;})
.map(visitData_full);
// Sort data before setting color scale to map the scale correctly
visitData = visitData_full
.sort(sortByCancerFreqThenWeek);
visitData = accumWeeks(visitData);
// Create list of cancer types sorted by most common
var cancerTypes = Object.keys(visitsByCancer).sort(sortByLength(visitsByCancer));
// Create list of treatment modalities sorted by most common
var treatmentTypes = Object.keys(visitsByTreatment).sort(sortByLength(visitsByTreatment));
//---------------------------------------------------------------------
// --- Set height, width, margins -------------------------------------
var margin = {top: 50, right: 200, bottom: 75, left: 50},
outerWidth = 1100,
outerHeight = 325,
width = outerWidth - margin.left - margin.right,
height = outerHeight - margin.top - margin.bottom;
var height_dotGraphic = height,
width_dotGraphic = width;
var horizSplitPadding = 50,
vertSplitPadding = 50;
var height_selCancer = 300,
width_selCancer = 11*width/12;
var height_selTreatment = 300,
width_selTreatment = 5*width/12;
//----------------------------------------------------------------------
// --- Create SVG and main groups --------------------------------------
var dotGraphic_svg = d3.select(".dotPlot").append("svg")
.attr("class", "dotPlot")
.attr("width", outerWidth)
.attr("height", outerHeight);
var selCancerGraphic_svg = d3.select(".selCancer").append("svg")
.attr("class", "selCancer")
.attr("width", width_selCancer)
.attr("height", height_selCancer);
var selTreatGraphic_svg = d3.select(".selTreatment").append("svg")
.attr("class", "selTreatment")
.attr("width", width_selTreatment)
.attr("height", height_selTreatment);
// Group for the dotplot graphic
var dotGraphic = dotGraphic_svg.append("g")
.attr("transform", "translate(" + [margin.left, margin.top] + ")");
// Group for cancer buttons
var selCancerGraphic = selCancerGraphic_svg.append("g")
.attr("transform",
"translate(" + [
margin.left/2,
margin.top/3
] + ")"
);
// Group for treatment buttons
var selTreatGraphic = selTreatGraphic_svg.append("g")
.attr("transform",
"translate(" + [
margin.left/2,
margin.top/3
] + ")"
);
//----------------------------------------------------------------------
// --- Define Scales ---------------------------------------------------
var xScale_dot = d3.scale.linear()
.domain([0,53])
.range([0, width_dotGraphic]);
var yScale_dot = d3.scale.linear()
.domain([0.5, d3.max(visitData.map(function(a) {return a.accWeek;}))/.8 ])
.range([height_dotGraphic, 0]);
// From https://colorbrewer2.org/ : 12-class qualitative
var colorList = [
"#1f78b4", "#33a02c",
"#e31a1c", "#ff7f00",
"#6a3d9a", "#b15928",
"#a6cee3", "#b2df8a",
"#fb9a99", "#fdbf6f",
"#cab2d6", "#eeee88"
]
var colorScale_cancer = d3.scale.ordinal()
.domain(cancerTypes)
.range(colorList)
var colorScale_treatment = d3.scale.ordinal()
.domain(treatmentTypes)
.range(colorList)
var colorScale_active = colorScale_cancer;
var colorScale_inactive = function(ignore){return "#bbbbbb";}
var colorScale_oneColor = function(ignore){return "#515151";}
//----------------------------------------------------------------------
// --- Define & draw axes ----------------------------------------------
var xAxisFn = d3.svg.axis()
.scale(xScale_dot)
.orient("bottom");
var yAxisFn = d3.svg.axis()
.scale(yScale_dot)
.orient("left");
var xAxis = dotGraphic_svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + [margin.left, height_dotGraphic + margin.top] + ")")
.call(xAxisFn);
xAxis.append("text")
.text("Weeks")
.attr("class", "label")
.attr("text-anchor", "middle")
.attr("alignment-baseline", "middle")
.attr("transform", "translate(" + [width_dotGraphic/2, 40 ] + ")")
var yAxis = dotGraphic_svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + [margin.left, margin.top] + ")")
.call(yAxisFn);
yAxis.append("text")
.text("Number of Patients")
.attr("class", "label")
.attr("text-anchor", "middle")
.attr("alignment-baseline", "middle")
.attr("transform", "translate(" + [-35, height_dotGraphic/2] + ")rotate(-90)")
//----------------------------------------------------------------------
// --- Draw Buttons ----------------------------------------------------
var roundedRect_w = 160,
roundedRect_h = 40,
roundedRect_r = 10;
// Cancer select buttons
var cancerButtons = selCancerGraphic.selectAll("g")
.data(cancerTypes)
.enter()
.append("g")
.attr("class", "cancerButton selected")
.attr("transform", function(d,i) {
// Make 2 columns of buttons
var nRows = Math.ceil(cancerTypes.length/2)-1;
if( i <= nRows ){
return "translate(" + [0, i*(roundedRect_h+5)] + ")";
}else{
return "translate(" + [width_selCancer/2, (i-1-nRows)*(roundedRect_h+5)] + ")";
}
});
var cancerButton_shapes = cancerButtons
.append("path")
.attr("d", createPillButton(0,0, roundedRect_w, roundedRect_h, roundedRect_r))
.attr("stroke", "#777777");
var cancerButton_text = cancerButtons
.append("text")
.text(function(d) {return d;})
.attr("class", "buttonText")
.attr("transform", "translate(" +
[(roundedRect_w - roundedRect_r)/2, roundedRect_h/2] +
")");
// Treatment select buttons
var treatmentButtons = selTreatGraphic.selectAll("g")
.data(treatmentTypes)
.enter()
.append("g")
.attr("class", "treatmentButton selected")
.attr("transform", function(d,i) {
return "translate(" + [0, i*(roundedRect_h+5)] + ")";
});
var treatmentButton_shapes = treatmentButtons
.append("path")
.attr("d", createPillButton(0,0, roundedRect_w, roundedRect_h, roundedRect_r))
.attr("stroke", "#777777");
var treatmentButton_text = treatmentButtons
.append("text")
.text(function(d) {return d;})
.attr("class", "buttonText")
.attr("transform", "translate(" +
[(roundedRect_w - roundedRect_r)/2, roundedRect_h/2] +
")");
// Reset Buttons
var resetCancerButton = d3.select(".selCancer.well>h4")
.append("p")
.attr("class", "resetButton cancerButton")
.text(" reset")
.on("click", function(){
visitData = filterOnClick(visitData_full, this);
redraw(visitData);
})
var resetTreatButton = d3.select(".selTreatment.well>h4")
.append("p")
.attr("class", "resetButton treatmentButton")
.text(" reset")
.on("click", function(){
visitData = filterOnClick(visitData_full, this);
visitData = visitData
.sort(sortByCancerFreqThenWeek);
visitData = accumWeeks(visitData);
redraw(visitData);
})
// Clear Buttons
var clearCancerButton = d3.select(".selCancer.well>h4")
.append("p")
.attr("class", "clearButton cancerButton")
.text(" clear")
.on("click", function(){
visitData = filterOnClick(visitData_full, this);
visitData = visitData
.sort(sortByCancerFreqThenWeek);
visitData = accumWeeks(visitData);
redraw(visitData);
})
var clearTreatButton = d3.select(".selTreatment.well>h4")
.append("p")
.attr("class", "clearButton treatmentButton")
.text(" clear")
.on("click", function(){
visitData = filterOnClick(visitData_full, this);
visitData = visitData
.sort(sortByCancerFreqThenWeek);
visitData = accumWeeks(visitData);
redraw(visitData);
})
// Recolor Buttons
var recolorButton_w = 100
var recolorButton_h = 35
var recolorButton_r = 8
var recolorButtonGraphic = dotGraphic_svg.append("g")
.attr("transform", "translate(" + [
margin.left + width_dotGraphic + 40,
margin.top + height_dotGraphic/2 - 2*recolorButton_h
] + ")");
recolorButtonGraphic.append("text")
.text("Colorize by:")
var colorOptions = ["Cancer Type", "Treatment Modality", "Single Color"];
var recolorButtons = recolorButtonGraphic.selectAll("g")
.data(colorOptions)
.enter()
.append("g")
.attr("class", function(d,i) {
if(i === 0){return "recolorButton selected"};
return "recolorButton";
})
.attr("transform", function(d,i) {
return "translate(" + [recolorButton_r, i*(recolorButton_h+5)+8] + ")";
});
var recolorButton_shapes = recolorButtons
.append("path")
.attr("d", createPillButton(0,0, recolorButton_w, recolorButton_h, recolorButton_r))
.attr("fill", "#515151")
.attr("stroke", "#777777");
var recolorButton_text = recolorButtons
.append("text")
.text(function(d) {return d;})
.attr("class", "recolorButtonText buttonText")
.attr("transform", "translate(" +
[(recolorButton_w - recolorButton_r)/2, recolorButton_h/2] +
")");
//----------------------------------------------------------------------
// --- Add button functionality ----------------------------------------
cancerButtons
.on("mouseover", function(){
d3.select(this).classed("hover", true);
})
.on("mouseout", function(){
d3.select(this).classed("hover", false);
});
treatmentButtons
.on("mouseover", function(){
d3.select(this).classed("hover", true);
})
.on("mouseout", function(){
d3.select(this).classed("hover", false);
});
recolorButtons
.on("mouseover", function(){
d3.select(this).classed("hover", true);
})
.on("mouseout", function(){
d3.select(this).classed("hover", false);
});
cancerButtons
.on("click", function(){
visitData = filterOnClick(visitData_full, this);
visitData = visitData
.sort(sortByCancerFreqThenWeek);
visitData = accumWeeks(visitData);
redraw(visitData);
});
treatmentButtons
.on("click", function(){
visitData = filterOnClick(visitData_full, this);
visitData = visitData
.sort(sortByCancerFreqThenWeek);
visitData = accumWeeks(visitData);
redraw(visitData);
});
recolorButtons
.on("click", function(d){
recolor(d);
});
//----------------------------------------------------------------------
// --- Plot points -----------------------------------------------------
recolor("Cancer Type") //*NOTE* recolor calls redraw!
//----------------------------------------------------------------------
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.js to a secure url
Modified http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js to a secure url
https://d3js.org/d3.v3.js
https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js