Loading public/main.css +86 −14 Original line number Diff line number Diff line /* Import Google Font */ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); body{ background:#767a83; /*margin-top:50px;*/ background: #ffffff; /* Changed background to white */ font-family: 'Roboto', sans-serif; /* Updated font to Roboto */ color: #333333; /* Changed text color to dark gray for better contrast */ margin: 20px; /* Added margin for spacing */ font: 15px "Trebuchet MS"; color:#c0c0c0; } Loading Loading @@ -38,6 +42,10 @@ body{ #graph_div { text-align: center; /* padding: 20px; */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Added subtle shadow */ border-radius: 8px; /* Rounded corners */ background: #eeeeee; /* Light background for contrast */ } .headline, .subline{ Loading @@ -46,46 +54,110 @@ body{ margin-bottom: 0.67em; margin-left: 0; margin-right: 0; fill: white; font-family: 'PT Sans',sans-serif; opacity: 0.5; fill: #333333; /* Dark text */ font-family: 'Roboto', sans-serif; /* Consistent font */ opacity: 1; /* Full opacity for better visibility */ } .headline{ font-weight: bold; font-weight: 700; /* Bold font */ color: #2c3e50; /* Modern dark blue */ } .subline{ font-size: 50%; font-weight: thin; font-size: 14px; /* Increased font size for readability */ color: #7f8c8d; /* Light gray */ } .label{ font-family: 'PT Sans',sans-serif; opacity: 1; font-size: 30%; color: #34495e; /* Darker label color */ font-size: 16px; /* Increased font size */ } #side_by_side_flex { display: flex; flex-direction: row; justify-content: space-between; justify-content: space-around; /* Changed to space-around for better spacing */ align-items: center; /* Vertically center align */ padding: 20px; /* Added padding */ } #list_div { flex: 1; max-width: 300px; padding: 10px; background: #ecf0f1; /* Light gray background */ border-radius: 8px; /* Rounded corners */ box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Subtle shadow */ } #info_div { max-width: 500px; flex: 2; text-align: left; padding: 20px; color: #333333; /* Dark text color */ background: #DDDDDD; /* Light gray background */ border-radius: 8px; /* Rounded corners */ box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Subtle shadow */ margin-left: 20px; /* Added margin for spacing */ } h2 { /* color: #088266; */ color: #088266; font-size: 24px; /* Increased font size */ } #selection_div { border: 1px solid black; padding: 10px; margin: 5px; clear: both; border: none; /* Removed border */ padding: 20px; /* Increased padding */ margin: 10px; /* Adjusted margin */ background: #bdc3c7; /* Subtle background color */ border-radius: 8px; /* Rounded corners */ box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Subtle shadow */ } /* Dropdown styling */ select { padding: 8px 12px; /* Added padding */ border: 1px solid #ccc; /* Light border */ border-radius: 4px; /* Rounded corners */ font-size: 14px; /* Increased font size */ margin-right: 10px; /* Added margin */ transition: border-color 0.3s ease; /* Smooth transition */ } select:focus { border-color: #2980b9; /* Change border color on focus */ outline: none; /* Remove default outline */ } /* Hover effects for list items */ #movie_list_div ul li:hover { color: #2980b9; /* Change color on hover */ text-decoration: underline; /* Underline on hover */ cursor: pointer; /* Pointer cursor on hover */ } /* Adjust scatter and bar plot divs */ #scatter_plot_div, #bar_plot_div { margin: 20px 0; /* Added vertical margin */ } /* Additional styling for better layout */ @media (max-width: 768px) { #side_by_side_flex { flex-direction: column; /* Stack elements vertically on small screens */ } #list_div, #info_div { max-width: 100%; /* Full width on small screens */ margin-left: 0; /* Remove left margin */ } } No newline at end of file public/mcuD3.js +36 −20 Original line number Diff line number Diff line import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm"; let selection_color = "#69b3a2"; // Global variables let data; let networkDiv, infoDiv, graphConfigDiv, graphDiv, scatterPlotDiv, barPlotDiv, movieListDiv; Loading Loading @@ -54,6 +56,7 @@ function initGraphConfig() { // Add dropdowns for scatterplot variables const scatterplotVars = ["tomato_meter", "audience_score", "movie_duration", "production_budget", "opening_weekend", "domestic_box_office", "worldwide_box_office"]; const scatterplotConfigDiv = graphConfigDiv.append("div").attr("id", "scatterplotConfig").style("width", "50%").style("display", "inline-block"); scatterplotConfigDiv.append("span") Loading Loading @@ -159,11 +162,14 @@ function renderMovieList() { // Phase Header const phaseHeader = movieListDiv.append("h3") .text(`Phase ${phase}`) .style("cursor", "pointer"); .style("color", "#333333") // Select All label phaseHeader.append("span") .text(" (select all)") .style("font-size", "12px") .style("color", "#666666") .style("font-style", "italic") .style("cursor", "pointer") .style("margin-left", "10px") .on("click", () => togglePhaseSelection(phase)); Loading @@ -186,8 +192,10 @@ function renderMovieList() { hoveredMovie = null; updateHoveredMovie(); }) .style("color", movie === hoveredMovie ? "orange" : movieSelection.includes(movie) ? "green" : "blue"); // .style("color", movie === hoveredMovie ? "orange" : movieSelection.includes(movie) ? "green" : "blue"); }); updateHoveredMovie(); }); } Loading Loading @@ -239,7 +247,9 @@ function updateHoveredMovie() { node.attr("opacity", n => (n.id === hoveredMovie || neighbors.includes(n.id)) ? 1 : 0.2); // Update link opacity link.attr("opacity", l => (l.source.id === hoveredMovie || l.target.id === hoveredMovie) ? 1 : 0.2); link.attr("opacity", l => (l.source.id === hoveredMovie || l.target.id === hoveredMovie) ? 1 : 0); link.attr("stroke-width", l => (l.source.id === hoveredMovie || l.target.id === hoveredMovie) ? 6 : 2); // Update node colors Loading Loading @@ -267,11 +277,11 @@ function updateHoveredMovie() { } scatterPlotDiv.selectAll("circle") .attr("r", d => d.movie_title === hoveredMovie ? 15 : 5) .style("fill", d => d.movie_title === hoveredMovie ? "orange" : "#69b3a2"); .attr("r", d => d.movie_title === hoveredMovie ? 10 : 6) .style("fill", d => d.movie_title === hoveredMovie ? "orange" : selection_color); barPlotDiv.selectAll("rect") .style("fill", d => d.movie_title === hoveredMovie ? "orange" : "#69b3a2"); .style("fill", d => d.movie_title === hoveredMovie ? "orange" : selection_color); } else { // Reset node opacity and colors Loading @@ -291,14 +301,19 @@ function updateHoveredMovie() { link.attr("opacity", 1) .attr("stroke", "#999"); infoDiv.html(`<h2>Hover over a movie node to see details here.</h2>`); link.attr("stroke-width", 2); infoDiv.selectAll("*").remove(); infoDiv.append("h1").text("Marvel Cinematic Universe visualization:").style("color", "#222222"); infoDiv.append("h2").text("Hover over a movie node to see details here.").style("color", "#555555"); scatterPlotDiv.selectAll("circle") .attr("r", 5) .style("fill", "#69b3a2"); .attr("r", 6) .style("fill", selection_color); barPlotDiv.selectAll("rect") .style("fill", "#69b3a2"); .style("fill", selection_color); } var lis = document.getElementsByTagName("li"); Loading @@ -306,9 +321,10 @@ function updateHoveredMovie() { if (lis[i].textContent === hoveredMovie) { lis[i].style.color = "orange"; } else if (movieSelection.includes(lis[i].textContent)) { lis[i].style.color = "green"; lis[i].style.color = "#088266"; lis[i].style.fontWeight = "bold"; } else { lis[i].style.color = "blue"; lis[i].style.color = "gray"; } } } Loading Loading @@ -461,7 +477,7 @@ function renderNetworkGraph() { .attr("id", "hoveredText") .attr("x", d.x ) .attr("y", d.y - 2 * r) .attr("fill", "white") .attr("fill", "#333333") .attr("text-anchor", "middle") .attr("font-size", "16px") .attr("font-weight", "bold") Loading Loading @@ -539,7 +555,7 @@ function renderScatterPlot() { // Y Axis Label svg.append("text") .attr("transform", "rotate(-90)") // .attr("y", -margin.left + 25) // shifted further to avoid overlap .attr("y", -margin.left ) // shifted further to avoid overlap .attr("x", -plotHeight / 2) .attr("dy", "1em") .style("text-anchor", "middle") Loading @@ -554,8 +570,8 @@ function renderScatterPlot() { .append("circle") .attr("cx", d => x(+d[scatterplotXVar])) .attr("cy", d => y(+d[scatterplotYVar])) .attr("r", 5) .style("fill", "#69b3a2") .attr("r", 6) .style("fill", selection_color) .on("mouseover", function(event, d) { hoveredMovie = d.movie_title; updateHoveredMovie(); Loading Loading @@ -621,7 +637,7 @@ function renderBarPlot() { .style("text-anchor", "end") .attr("dx", "-0.8em") .attr("dy", "-0.15em") .attr("transform", "rotate(-65)"); .attr("transform", "rotate(-15)"); // Y Scale const y = d3.scaleLinear() Loading Loading @@ -659,7 +675,7 @@ function renderBarPlot() { .attr("y", d => y(+d[barplotVar])) .attr("width", x.bandwidth()) .attr("height", d => plotHeight - y(+d[barplotVar])) .attr("fill", "#69b3a2") .attr("fill", selection_color) .on("mouseover", function(event, d) { hoveredMovie = d.movie_title; updateHoveredMovie(); Loading Loading @@ -721,9 +737,9 @@ function getMoviesByPhase(phase) { function getNodeColor(d) { if (d.group === "movie") { return movieSelection.includes(d.id) ? "green" : "blue"; return selection_color } return "red"; return "#333333"; } function getFriendlyVarName(varName, inMillions = false) { Loading Loading
public/main.css +86 −14 Original line number Diff line number Diff line /* Import Google Font */ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); body{ background:#767a83; /*margin-top:50px;*/ background: #ffffff; /* Changed background to white */ font-family: 'Roboto', sans-serif; /* Updated font to Roboto */ color: #333333; /* Changed text color to dark gray for better contrast */ margin: 20px; /* Added margin for spacing */ font: 15px "Trebuchet MS"; color:#c0c0c0; } Loading Loading @@ -38,6 +42,10 @@ body{ #graph_div { text-align: center; /* padding: 20px; */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Added subtle shadow */ border-radius: 8px; /* Rounded corners */ background: #eeeeee; /* Light background for contrast */ } .headline, .subline{ Loading @@ -46,46 +54,110 @@ body{ margin-bottom: 0.67em; margin-left: 0; margin-right: 0; fill: white; font-family: 'PT Sans',sans-serif; opacity: 0.5; fill: #333333; /* Dark text */ font-family: 'Roboto', sans-serif; /* Consistent font */ opacity: 1; /* Full opacity for better visibility */ } .headline{ font-weight: bold; font-weight: 700; /* Bold font */ color: #2c3e50; /* Modern dark blue */ } .subline{ font-size: 50%; font-weight: thin; font-size: 14px; /* Increased font size for readability */ color: #7f8c8d; /* Light gray */ } .label{ font-family: 'PT Sans',sans-serif; opacity: 1; font-size: 30%; color: #34495e; /* Darker label color */ font-size: 16px; /* Increased font size */ } #side_by_side_flex { display: flex; flex-direction: row; justify-content: space-between; justify-content: space-around; /* Changed to space-around for better spacing */ align-items: center; /* Vertically center align */ padding: 20px; /* Added padding */ } #list_div { flex: 1; max-width: 300px; padding: 10px; background: #ecf0f1; /* Light gray background */ border-radius: 8px; /* Rounded corners */ box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Subtle shadow */ } #info_div { max-width: 500px; flex: 2; text-align: left; padding: 20px; color: #333333; /* Dark text color */ background: #DDDDDD; /* Light gray background */ border-radius: 8px; /* Rounded corners */ box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Subtle shadow */ margin-left: 20px; /* Added margin for spacing */ } h2 { /* color: #088266; */ color: #088266; font-size: 24px; /* Increased font size */ } #selection_div { border: 1px solid black; padding: 10px; margin: 5px; clear: both; border: none; /* Removed border */ padding: 20px; /* Increased padding */ margin: 10px; /* Adjusted margin */ background: #bdc3c7; /* Subtle background color */ border-radius: 8px; /* Rounded corners */ box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Subtle shadow */ } /* Dropdown styling */ select { padding: 8px 12px; /* Added padding */ border: 1px solid #ccc; /* Light border */ border-radius: 4px; /* Rounded corners */ font-size: 14px; /* Increased font size */ margin-right: 10px; /* Added margin */ transition: border-color 0.3s ease; /* Smooth transition */ } select:focus { border-color: #2980b9; /* Change border color on focus */ outline: none; /* Remove default outline */ } /* Hover effects for list items */ #movie_list_div ul li:hover { color: #2980b9; /* Change color on hover */ text-decoration: underline; /* Underline on hover */ cursor: pointer; /* Pointer cursor on hover */ } /* Adjust scatter and bar plot divs */ #scatter_plot_div, #bar_plot_div { margin: 20px 0; /* Added vertical margin */ } /* Additional styling for better layout */ @media (max-width: 768px) { #side_by_side_flex { flex-direction: column; /* Stack elements vertically on small screens */ } #list_div, #info_div { max-width: 100%; /* Full width on small screens */ margin-left: 0; /* Remove left margin */ } } No newline at end of file
public/mcuD3.js +36 −20 Original line number Diff line number Diff line import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm"; let selection_color = "#69b3a2"; // Global variables let data; let networkDiv, infoDiv, graphConfigDiv, graphDiv, scatterPlotDiv, barPlotDiv, movieListDiv; Loading Loading @@ -54,6 +56,7 @@ function initGraphConfig() { // Add dropdowns for scatterplot variables const scatterplotVars = ["tomato_meter", "audience_score", "movie_duration", "production_budget", "opening_weekend", "domestic_box_office", "worldwide_box_office"]; const scatterplotConfigDiv = graphConfigDiv.append("div").attr("id", "scatterplotConfig").style("width", "50%").style("display", "inline-block"); scatterplotConfigDiv.append("span") Loading Loading @@ -159,11 +162,14 @@ function renderMovieList() { // Phase Header const phaseHeader = movieListDiv.append("h3") .text(`Phase ${phase}`) .style("cursor", "pointer"); .style("color", "#333333") // Select All label phaseHeader.append("span") .text(" (select all)") .style("font-size", "12px") .style("color", "#666666") .style("font-style", "italic") .style("cursor", "pointer") .style("margin-left", "10px") .on("click", () => togglePhaseSelection(phase)); Loading @@ -186,8 +192,10 @@ function renderMovieList() { hoveredMovie = null; updateHoveredMovie(); }) .style("color", movie === hoveredMovie ? "orange" : movieSelection.includes(movie) ? "green" : "blue"); // .style("color", movie === hoveredMovie ? "orange" : movieSelection.includes(movie) ? "green" : "blue"); }); updateHoveredMovie(); }); } Loading Loading @@ -239,7 +247,9 @@ function updateHoveredMovie() { node.attr("opacity", n => (n.id === hoveredMovie || neighbors.includes(n.id)) ? 1 : 0.2); // Update link opacity link.attr("opacity", l => (l.source.id === hoveredMovie || l.target.id === hoveredMovie) ? 1 : 0.2); link.attr("opacity", l => (l.source.id === hoveredMovie || l.target.id === hoveredMovie) ? 1 : 0); link.attr("stroke-width", l => (l.source.id === hoveredMovie || l.target.id === hoveredMovie) ? 6 : 2); // Update node colors Loading Loading @@ -267,11 +277,11 @@ function updateHoveredMovie() { } scatterPlotDiv.selectAll("circle") .attr("r", d => d.movie_title === hoveredMovie ? 15 : 5) .style("fill", d => d.movie_title === hoveredMovie ? "orange" : "#69b3a2"); .attr("r", d => d.movie_title === hoveredMovie ? 10 : 6) .style("fill", d => d.movie_title === hoveredMovie ? "orange" : selection_color); barPlotDiv.selectAll("rect") .style("fill", d => d.movie_title === hoveredMovie ? "orange" : "#69b3a2"); .style("fill", d => d.movie_title === hoveredMovie ? "orange" : selection_color); } else { // Reset node opacity and colors Loading @@ -291,14 +301,19 @@ function updateHoveredMovie() { link.attr("opacity", 1) .attr("stroke", "#999"); infoDiv.html(`<h2>Hover over a movie node to see details here.</h2>`); link.attr("stroke-width", 2); infoDiv.selectAll("*").remove(); infoDiv.append("h1").text("Marvel Cinematic Universe visualization:").style("color", "#222222"); infoDiv.append("h2").text("Hover over a movie node to see details here.").style("color", "#555555"); scatterPlotDiv.selectAll("circle") .attr("r", 5) .style("fill", "#69b3a2"); .attr("r", 6) .style("fill", selection_color); barPlotDiv.selectAll("rect") .style("fill", "#69b3a2"); .style("fill", selection_color); } var lis = document.getElementsByTagName("li"); Loading @@ -306,9 +321,10 @@ function updateHoveredMovie() { if (lis[i].textContent === hoveredMovie) { lis[i].style.color = "orange"; } else if (movieSelection.includes(lis[i].textContent)) { lis[i].style.color = "green"; lis[i].style.color = "#088266"; lis[i].style.fontWeight = "bold"; } else { lis[i].style.color = "blue"; lis[i].style.color = "gray"; } } } Loading Loading @@ -461,7 +477,7 @@ function renderNetworkGraph() { .attr("id", "hoveredText") .attr("x", d.x ) .attr("y", d.y - 2 * r) .attr("fill", "white") .attr("fill", "#333333") .attr("text-anchor", "middle") .attr("font-size", "16px") .attr("font-weight", "bold") Loading Loading @@ -539,7 +555,7 @@ function renderScatterPlot() { // Y Axis Label svg.append("text") .attr("transform", "rotate(-90)") // .attr("y", -margin.left + 25) // shifted further to avoid overlap .attr("y", -margin.left ) // shifted further to avoid overlap .attr("x", -plotHeight / 2) .attr("dy", "1em") .style("text-anchor", "middle") Loading @@ -554,8 +570,8 @@ function renderScatterPlot() { .append("circle") .attr("cx", d => x(+d[scatterplotXVar])) .attr("cy", d => y(+d[scatterplotYVar])) .attr("r", 5) .style("fill", "#69b3a2") .attr("r", 6) .style("fill", selection_color) .on("mouseover", function(event, d) { hoveredMovie = d.movie_title; updateHoveredMovie(); Loading Loading @@ -621,7 +637,7 @@ function renderBarPlot() { .style("text-anchor", "end") .attr("dx", "-0.8em") .attr("dy", "-0.15em") .attr("transform", "rotate(-65)"); .attr("transform", "rotate(-15)"); // Y Scale const y = d3.scaleLinear() Loading Loading @@ -659,7 +675,7 @@ function renderBarPlot() { .attr("y", d => y(+d[barplotVar])) .attr("width", x.bandwidth()) .attr("height", d => plotHeight - y(+d[barplotVar])) .attr("fill", "#69b3a2") .attr("fill", selection_color) .on("mouseover", function(event, d) { hoveredMovie = d.movie_title; updateHoveredMovie(); Loading Loading @@ -721,9 +737,9 @@ function getMoviesByPhase(phase) { function getNodeColor(d) { if (d.group === "movie") { return movieSelection.includes(d.id) ? "green" : "blue"; return selection_color } return "red"; return "#333333"; } function getFriendlyVarName(varName, inMillions = false) { Loading