mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-18 21:49:37 -04:00
Responsive updates
This commit is contained in:
@@ -14,10 +14,6 @@
|
|||||||
const container = d3.select(containerId);
|
const container = d3.select(containerId);
|
||||||
container.selectAll('*').remove(); // Clear any existing content
|
container.selectAll('*').remove(); // Clear any existing content
|
||||||
|
|
||||||
// Dynamically create tooltip element
|
|
||||||
const tooltip = container.append('div')
|
|
||||||
.attr('id', 'tooltip');
|
|
||||||
|
|
||||||
const margin = { top: 60, right: 20, bottom: 40, left: 20 }; // Adjusted top margin for legend
|
const margin = { top: 60, right: 20, bottom: 40, left: 20 }; // Adjusted top margin for legend
|
||||||
const width = container.node().getBoundingClientRect().width - margin.left - margin.right;
|
const width = container.node().getBoundingClientRect().width - margin.left - margin.right;
|
||||||
const height = 400 - margin.top - margin.bottom;
|
const height = 400 - margin.top - margin.bottom;
|
||||||
@@ -29,32 +25,28 @@
|
|||||||
.attr('transform', `translate(${margin.left},${margin.top})`);
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
||||||
|
|
||||||
// Create legend
|
// Create legend
|
||||||
const legend = svg.append('g')
|
const legendContainer = d3.select('.chart-legend');
|
||||||
.attr('class', 'legend')
|
legendContainer.selectAll('*').remove(); // Clear any existing legend
|
||||||
.attr('transform', `translate(${width - 200},-40)`); // Adjust the position of the legend
|
|
||||||
|
|
||||||
const legendData = [
|
const legendData = [
|
||||||
{ label: 'Delivered', color: COLORS.delivered },
|
{ label: 'Delivered', color: COLORS.delivered },
|
||||||
{ label: 'Failed', color: COLORS.failed }
|
{ label: 'Failed', color: COLORS.failed }
|
||||||
];
|
];
|
||||||
|
|
||||||
const legendItem = legend.selectAll('.legend-item')
|
const legendItem = legendContainer.selectAll('.legend-item')
|
||||||
.data(legendData)
|
.data(legendData)
|
||||||
.enter()
|
.enter()
|
||||||
.append('g')
|
.append('div')
|
||||||
.attr('class', 'legend-item')
|
.attr('class', 'legend-item')
|
||||||
.attr('transform', (d, i) => `translate(${i * 100},0)`); // Adjust the spacing between legend items
|
|
||||||
|
|
||||||
legendItem.append('rect')
|
legendItem.append('div')
|
||||||
.attr('width', 18)
|
.attr('class', 'legend-rect')
|
||||||
.attr('height', 18)
|
.style('background-color', d => d.color)
|
||||||
.attr('fill', d => d.color);
|
.style('display', 'inline-block')
|
||||||
|
.style('margin-right', '5px');
|
||||||
|
|
||||||
legendItem.append('text')
|
legendItem.append('span')
|
||||||
.attr('x', 24)
|
.attr('class', 'legend-label')
|
||||||
.attr('y', 9)
|
|
||||||
.attr('dy', '0.35em')
|
|
||||||
.style('text-anchor', 'start')
|
|
||||||
.text(d => d.label);
|
.text(d => d.label);
|
||||||
|
|
||||||
const x = d3.scaleBand()
|
const x = d3.scaleBand()
|
||||||
@@ -103,6 +95,11 @@
|
|||||||
.domain(['delivered', 'failed'])
|
.domain(['delivered', 'failed'])
|
||||||
.range([COLORS.delivered, COLORS.failed]);
|
.range([COLORS.delivered, COLORS.failed]);
|
||||||
|
|
||||||
|
// Create tooltip
|
||||||
|
const tooltip = d3.select('body').append('div')
|
||||||
|
.attr('id', 'tooltip')
|
||||||
|
.style('display', 'none');
|
||||||
|
|
||||||
// Create bars with animation
|
// Create bars with animation
|
||||||
const barGroups = svg.selectAll('.bar-group')
|
const barGroups = svg.selectAll('.bar-group')
|
||||||
.data(series)
|
.data(series)
|
||||||
@@ -126,9 +123,8 @@
|
|||||||
.html(`${d.data.label}<br>${capitalizedKey}: ${d.data[key]}`);
|
.html(`${d.data.label}<br>${capitalizedKey}: ${d.data[key]}`);
|
||||||
})
|
})
|
||||||
.on('mousemove', function(event) {
|
.on('mousemove', function(event) {
|
||||||
const containerPosition = container.node().getBoundingClientRect();
|
tooltip.style('left', `${event.pageX + 10}px`)
|
||||||
tooltip.style('left', `${event.clientX - containerPosition.left + 10}px`)
|
.style('top', `${event.pageY - 20}px`);
|
||||||
.style('top', `${event.clientY - containerPosition.top + 10}px`);
|
|
||||||
})
|
})
|
||||||
.on('mouseout', function() {
|
.on('mouseout', function() {
|
||||||
tooltip.style('display', 'none');
|
tooltip.style('display', 'none');
|
||||||
@@ -201,10 +197,14 @@
|
|||||||
var deliveredData = [];
|
var deliveredData = [];
|
||||||
var failedData = [];
|
var failedData = [];
|
||||||
|
|
||||||
for (var date in data) {
|
for (var dateString in data) {
|
||||||
labels.push(date);
|
// Parse the date string (assuming format YYYY-MM-DD)
|
||||||
deliveredData.push(data[date].sms.delivered);
|
const dateParts = dateString.split('-');
|
||||||
failedData.push(data[date].sms.failed !== undefined ? data[date].sms.failed : 0);
|
const formattedDate = `${dateParts[1]}/${dateParts[2]}/${dateParts[0]}`; // Format to MM/DD/YYYY
|
||||||
|
|
||||||
|
labels.push(formattedDate);
|
||||||
|
deliveredData.push(data[dateString].sms.delivered);
|
||||||
|
failedData.push(data[dateString].sms.failed !== undefined ? data[dateString].sms.failed : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
createChart('#weeklyChart', labels, deliveredData, failedData);
|
createChart('#weeklyChart', labels, deliveredData, failedData);
|
||||||
@@ -218,19 +218,34 @@
|
|||||||
|
|
||||||
// Function to handle dropdown change
|
// Function to handle dropdown change
|
||||||
function handleDropdownChange(event) {
|
function handleDropdownChange(event) {
|
||||||
const selectedValue = event.target.value;
|
const selectedValue = event.target.value;
|
||||||
const subTitle = document.querySelector(`#chartsArea .chart-subtitle`);
|
const subTitle = document.querySelector(`#chartsArea .chart-subtitle`);
|
||||||
const selectElement = document.getElementById('options');
|
const selectElement = document.getElementById('options');
|
||||||
const selectedText = selectElement.options[selectElement.selectedIndex].text;
|
const selectedText = selectElement.options[selectElement.selectedIndex].text;
|
||||||
|
|
||||||
if (selectedValue === "individual") {
|
if (selectedValue === "individual") {
|
||||||
// Mock individual data
|
// Get today's date
|
||||||
const labels = ["2024-06-06", "2024-06-07", "2024-06-08", "2024-06-09", "2024-06-10", "2024-06-11", "2024-06-12"];
|
const today = new Date();
|
||||||
const deliveredData = labels.map(() => Math.floor(Math.random() * 5) + 1); // Random between 1 and 5
|
|
||||||
const failedData = [0, 1, 0, 0, 1, 2, 1];
|
// Function to generate labels for the last 7 days (including today)
|
||||||
subTitle.textContent = selectedText + " - Last 7 Days";
|
function getLabelsForLast7Days() {
|
||||||
createChart('#weeklyChart', labels, deliveredData, failedData);
|
const labels = [];
|
||||||
createTable('weeklyTable', 'Weekly', labels, deliveredData, failedData);
|
for (let i = 6; i >= 0; i--) {
|
||||||
|
const pastDate = new Date(today.getTime() - (i * 24 * 60 * 60 * 1000)); // Subtract i days from today
|
||||||
|
const day = pastDate.getDate();
|
||||||
|
const month = pastDate.getMonth() + 1; // Months are 0-indexed
|
||||||
|
labels.push(`${month}/${day}/${pastDate.getFullYear()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = getLabelsForLast7Days();
|
||||||
|
const deliveredData = labels.map(() => Math.floor(Math.random() * 5) + 1); // Random between 1 and 5
|
||||||
|
const failedData = [0, 1, 0, 0, 1, 2, 1];
|
||||||
|
subTitle.textContent = selectedText + " - Last 7 Days";
|
||||||
|
createChart('#weeklyChart', labels, deliveredData, failedData);
|
||||||
|
createTable('weeklyTable', 'Weekly', labels, deliveredData, failedData);
|
||||||
} else if (selectedValue === "service") {
|
} else if (selectedValue === "service") {
|
||||||
subTitle.textContent = selectedText + " - Last 7 Days";
|
subTitle.textContent = selectedText + " - Last 7 Days";
|
||||||
// Fetch and use real service data
|
// Fetch and use real service data
|
||||||
@@ -238,6 +253,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resize chart on window resize
|
||||||
|
window.addEventListener('resize', function() {
|
||||||
|
const selectedValue = document.getElementById('options').value;
|
||||||
|
handleDropdownChange({ target: { value: selectedValue } });
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Initialize weekly chart and table with service data by default
|
// Initialize weekly chart and table with service data by default
|
||||||
fetchServiceData();
|
fetchServiceData();
|
||||||
|
|||||||
@@ -78,35 +78,6 @@ $failed: color('orange-30v');
|
|||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// tabs
|
|
||||||
|
|
||||||
// .tab {
|
|
||||||
// display: flex;
|
|
||||||
// margin-bottom: 10px; /* Replace units(2) with 10px */
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .tab button {
|
|
||||||
// cursor: pointer;
|
|
||||||
// border-radius: 0;
|
|
||||||
// margin-right: -1px; /* Replace units(-1px) with -1px */
|
|
||||||
// &:focus {
|
|
||||||
// outline-width: 2px;
|
|
||||||
// }
|
|
||||||
// &.active, &:hover {
|
|
||||||
// background-color: #0076d6; /* Assuming color("blue-60v") is #0076d6 */
|
|
||||||
// color: #FFF;
|
|
||||||
// box-shadow: none;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .tabcontent {
|
|
||||||
// display: none;
|
|
||||||
// height: 400px;
|
|
||||||
// width: 100%;h
|
|
||||||
// padding: 10px; /* Replace units(1) with 10px */
|
|
||||||
// }
|
|
||||||
|
|
||||||
.chart {
|
.chart {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -118,7 +89,7 @@ $failed: color('orange-30v');
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px 20px;
|
padding: units(1) units(1) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-subtitle {
|
.chart-subtitle {
|
||||||
@@ -159,12 +130,11 @@ $failed: color('orange-30v');
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-right: units(2);
|
margin-right: units(2);
|
||||||
}
|
.legend-rect {
|
||||||
|
width: units(2);
|
||||||
.legend-item rect {
|
height: units(2);
|
||||||
width: units(2);
|
margin-right: units(1);
|
||||||
height: units(2);
|
}
|
||||||
margin-right: units(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#tooltip {
|
#tooltip {
|
||||||
|
|||||||
@@ -57,36 +57,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="message"></div>
|
<div id="message"></div>
|
||||||
|
|
||||||
<!-- <h3 id="total-value" class="margin-y-1"></h3>
|
|
||||||
<div class="chart-container">
|
|
||||||
<div class="bar delivered" id="delivered-bar"></div>
|
|
||||||
<div class="bar pending" id="pending-bar"></div>
|
|
||||||
<div class="bar failed" id="failed-bar"></div>
|
|
||||||
</div>
|
|
||||||
<div class="legend">
|
|
||||||
<div class="legend-item">
|
|
||||||
<button type="button" class="usa-button usa-tooltip legend-color delivered" data-position="bottom"
|
|
||||||
data-classes="width-full tablet:width-auto"
|
|
||||||
title="Delivered means that the message was successfully delivered to the mobile device.">
|
|
||||||
</button>
|
|
||||||
<div class="legend-value" id="delivered-value"></div>
|
|
||||||
</div>
|
|
||||||
<div class="legend-item">
|
|
||||||
<button type="button" class="usa-button usa-tooltip legend-color pending" data-position="bottom"
|
|
||||||
data-classes="width-full tablet:width-auto"
|
|
||||||
title="Pending means that Notify has sent the message, but has not received the delivery status from the carrier. Messages remain in the Pending state until Notify has received the status, typically about five minutes.">
|
|
||||||
</button>
|
|
||||||
<div class="legend-value" id="pending-value"></div>
|
|
||||||
</div>
|
|
||||||
<div class="legend-item">
|
|
||||||
<button type="button" class="usa-button usa-tooltip legend-color failed" data-position="bottom"
|
|
||||||
data-classes="width-full tablet:width-auto"
|
|
||||||
title="Failed means that the carrier could not deliver the message, generally because the phone is unavailable or the number is no longer active.">
|
|
||||||
</button>
|
|
||||||
<div class="legend-value" id="failed-value"></div>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<h2 class="margin-top-4 margin-bottom-1">Recent Batches</h2>
|
<h2 class="margin-top-4 margin-bottom-1">Recent Batches</h2>
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="usa-table usa-table--borderless job-table">
|
<table class="usa-table usa-table--borderless job-table">
|
||||||
|
|||||||
Reference in New Issue
Block a user