Julai mwaka jana, wakati anawaapisha Manaibu Kamishna wa Polisi (DCP) na Makamishna Wasaidizi Waandamizi (SACP) wa Jeshi hilo, Rais Magufuli alisema amepata taarifa za rushwa ndani ya Jeshi la Polisi inayokadiriwa kuwa kati ya Sh bilioni 60 ambazo zililipwa kuwanunulia nguo na vifaa vingine askari polisi tangu mwaka 2015, lakini hazijanunuliwa.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Takwimu za Ukuaji wa Mawasiliano Tanzania</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
background-color: #f0f4f8;
color: #334155;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
box-sizing: border-box;
}
.container {
background-color: #ffffff;
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
padding: 30px;
max-width: 1200px; /* Increased max-width to accommodate two charts */
width: 100%;
display: flex;
flex-direction: column;
gap: 20px;
}
.charts-wrapper {
display: flex;
flex-direction: column; /* Stack charts by default */
gap: 20px;
}
Media (min-width: 768px) { /* On medium screens and up, display side-by-side */
.charts-wrapper {
flex-direction: row;
}
.chart-canvas-container {
flex: 1; /* Each chart takes equal width */
}
}
canvas {
max-width: 100%;
height: auto;
}
.legend-item {
display: flex;
align-items: center;
cursor: pointer;
padding: 8px 12px;
border-radius: 8px;
transition: background-color 0.3s ease;
}
.legend-item:hover {
background-color: #e2e8f0;
}
.legend-color-box {
width: 20px;
height: 20px;
border-radius: 5px;
margin-right: 10px;
border: 1px solid rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="container">
<h1 class="text-3xl font-bold text-center text-gray-800 mb-6">Takwimu za Ukuaji wa Mawasiliano Tanzania (Juni 2021 – Juni 2025)</h1>
<div class="charts-wrapper">
<div class="chart-canvas-container">
<h2 class="text-xl font-semibold text-gray-700 text-center mb-4">Chati ya Mstari</h2>
<canvas id="lineGrowthChart"></canvas>
</div>
<div class="chart-canvas-container">
<h2 class="text-xl font-semibold text-gray-700 text-center mb-4">Chati ya Pau</h2>
<canvas id="barGrowthChart"></canvas>
</div>
</div>
<div id="chart-legend" class="flex flex-wrap justify-center gap-4 mt-4">
<!-- Legend items will be dynamically added here -->
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const chartData = {
labels: ['2021', '2022', '2023', '2024', '2025'],
datasets: [
{
label: 'Idadi ya laini za simu',
data: [53182651, 56224747, 64088651, 75588006, 92735798],
borderColor: '#3b82f6', // Blue-500
backgroundColor: '#3b82f6', // Blue-500 for bars
fill: false,
tension: 0.4,
hidden: false
},
{
label: 'Akaunti za Pesa Mtandao',
data: [33282544, 37407233, 47275660, 55732728, 68059290],
borderColor: '#10b981', // Emerald-500
backgroundColor: '#10b981', // Emerald-500 for bars
fill: false,
tension: 0.4,
hidden: false
},
{
label: 'Utumiaji wa Intaneti',
data: [29152713, 29169958, 34047407, 39311477, 54078530],
borderColor: '#ef4444', // Red-500
backgroundColor: '#ef4444', // Red-500 for bars
fill: false,
tension: 0.4,
hidden: false
}
]
};
// Options common to both charts
const commonOptions = {
responsive: true,
maintainAspectRatio: true,
plugins: {
title: {
display: false
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('en-US').format(context.parsed.y);
}
return label;
}
}
},
legend: {
display: false // Hide default legend to use custom one
}
},
scales: {
x: {
title: {
display: true,
text: 'Mwaka (Year)',
color: '#4b5563'
},
grid: {
display: false
}
},
y: {
beginAtZero: true,
title: {
display: true,
text: 'Idadi (Number)',
color: '#4b5563'
},
ticks: {
callback: function(value) {
if (value >= 1000000) {
return (value / 1000000).toFixed(1) + 'M';
}
return new Intl.NumberFormat('en-US').format(value);
}
}
}
}
};
// Line Chart Configuration
const lineConfig = {
type: 'line',
data: chartData,
options: {
...commonOptions,
plugins: {
...commonOptions.plugins,
tooltip: { // Adjust tooltip for line chart to show actual background color
...commonOptions.plugins.tooltip,
backgroundColor: 'rgba(0,0,0,0.7)',
borderColor: 'rgba(0,0,0,0.7)',
borderWidth: 1,
}
}
}
};
// Bar Chart Configuration
const barConfig = {
type: 'bar',
data: JSON.parse(JSON.stringify(chartData)), // Deep copy to allow independent modifications if needed
options: {
...commonOptions,
plugins: {
...commonOptions.plugins,
tooltip: { // Adjust tooltip for bar chart to show actual background color
...commonOptions.plugins.tooltip,
backgroundColor: 'rgba(0,0,0,0.7)',
borderColor: 'rgba(0,0,0,0.7)',
borderWidth: 1,
},
datalabels: { // Datalabels plugin configuration for bar chart
anchor: 'end',
align: 'start', // Align start to be inside the bar
rotation: 90, // Rotate labels by 90 degrees
color: '#ffffff', // White color for better contrast on bars
font: {
weight: 'bold',
size: 10
},
formatter: function(value) {
// Format numbers for readability, e.g., 53,182,651 becomes 53.2M
if (value >= 1000000) {
return (value / 1000000).toFixed(1) + 'M';
} else if (value >= 1000) {
return (value / 1000).toFixed(1) + 'K';
}
return value;
}
}
},
scales: {
...commonOptions.scales,
x: {
...commonOptions.scales.x,
grid: {
display: false
}
},
y: {
...commonOptions.scales.y,
// Ensure enough padding for rotated labels
grace: '5%' // Add 5% grace to the top of the Y-axis
}
}
}
};
// For bar chart, we want to use the backgroundColor property directly for bars
barConfig.data.datasets.forEach(dataset => {
// For bars, backgroundColor is the primary color, borderColor is usually the same or slightly darker
dataset.backgroundColor = dataset.borderColor;
});
const lineGrowthChart = new Chart(
document.getElementById('lineGrowthChart'),
lineConfig
);
const barGrowthChart = new Chart(
document.getElementById('barGrowthChart'),
barConfig
);
// Custom Legend Generation
const chartLegendContainer = document.getElementById('chart-legend');
chartData.datasets.forEach((dataset, index) => {
const legendItem = document.createElement('div');
legendItem.classList.add('legend-item', 'transition-colors', 'duration-200');
legendItem.innerHTML = `
<span class="legend-color-box" style="background-color: ${dataset.borderColor};"></span>
<span class="text-sm font-medium text-gray-700">${dataset.label}</span>
`;
legendItem.addEventListener('click', () => {
// Toggle visibility for both charts
const lineMeta = lineGrowthChart.getDatasetMeta(index);
const barMeta = barGrowthChart.getDatasetMeta(index);
lineMeta.hidden = !lineMeta.hidden;
barMeta.hidden = !barMeta.hidden;
lineGrowthChart.update();
barGrowthChart.update();
legendItem.style.textDecoration = lineMeta.hidden ? 'line-through' : 'none';
legendItem.style.opacity = lineMeta.hidden ? '0.6' : '1';
});
chartLegendContainer.appendChild(legendItem);
});
});
</script>
</body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Takwimu za Ukuaji wa Mawasiliano Tanzania</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
background-color: #f0f4f8;
color: #334155;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
box-sizing: border-box;
}
.container {
background-color: #ffffff;
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
padding: 30px;
max-width: 1200px; /* Increased max-width to accommodate two charts */
width: 100%;
display: flex;
flex-direction: column;
gap: 20px;
}
.charts-wrapper {
display: flex;
flex-direction: column; /* Stack charts by default */
gap: 20px;
}
Media (min-width: 768px) { /* On medium screens and up, display side-by-side */
.charts-wrapper {
flex-direction: row;
}
.chart-canvas-container {
flex: 1; /* Each chart takes equal width */
}
}
canvas {
max-width: 100%;
height: auto;
}
.legend-item {
display: flex;
align-items: center;
cursor: pointer;
padding: 8px 12px;
border-radius: 8px;
transition: background-color 0.3s ease;
}
.legend-item:hover {
background-color: #e2e8f0;
}
.legend-color-box {
width: 20px;
height: 20px;
border-radius: 5px;
margin-right: 10px;
border: 1px solid rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="container">
<h1 class="text-3xl font-bold text-center text-gray-800 mb-6">Takwimu za Ukuaji wa Mawasiliano Tanzania (Juni 2021 – Juni 2025)</h1>
<div class="charts-wrapper">
<div class="chart-canvas-container">
<h2 class="text-xl font-semibold text-gray-700 text-center mb-4">Chati ya Mstari</h2>
<canvas id="lineGrowthChart"></canvas>
</div>
<div class="chart-canvas-container">
<h2 class="text-xl font-semibold text-gray-700 text-center mb-4">Chati ya Pau</h2>
<canvas id="barGrowthChart"></canvas>
</div>
</div>
<div id="chart-legend" class="flex flex-wrap justify-center gap-4 mt-4">
<!-- Legend items will be dynamically added here -->
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const chartData = {
labels: ['2021', '2022', '2023', '2024', '2025'],
datasets: [
{
label: 'Idadi ya laini za simu',
data: [53182651, 56224747, 64088651, 75588006, 92735798],
borderColor: '#3b82f6', // Blue-500
backgroundColor: '#3b82f6', // Blue-500 for bars
fill: false,
tension: 0.4,
hidden: false
},
{
label: 'Akaunti za Pesa Mtandao',
data: [33282544, 37407233, 47275660, 55732728, 68059290],
borderColor: '#10b981', // Emerald-500
backgroundColor: '#10b981', // Emerald-500 for bars
fill: false,
tension: 0.4,
hidden: false
},
{
label: 'Utumiaji wa Intaneti',
data: [29152713, 29169958, 34047407, 39311477, 54078530],
borderColor: '#ef4444', // Red-500
backgroundColor: '#ef4444', // Red-500 for bars
fill: false,
tension: 0.4,
hidden: false
}
]
};
// Options common to both charts
const commonOptions = {
responsive: true,
maintainAspectRatio: true,
plugins: {
title: {
display: false
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('en-US').format(context.parsed.y);
}
return label;
}
}
},
legend: {
display: false // Hide default legend to use custom one
}
},
scales: {
x: {
title: {
display: true,
text: 'Mwaka (Year)',
color: '#4b5563'
},
grid: {
display: false
}
},
y: {
beginAtZero: true,
title: {
display: true,
text: 'Idadi (Number)',
color: '#4b5563'
},
ticks: {
callback: function(value) {
if (value >= 1000000) {
return (value / 1000000).toFixed(1) + 'M';
}
return new Intl.NumberFormat('en-US').format(value);
}
}
}
}
};
// Line Chart Configuration
const lineConfig = {
type: 'line',
data: chartData,
options: {
...commonOptions,
plugins: {
...commonOptions.plugins,
tooltip: { // Adjust tooltip for line chart to show actual background color
...commonOptions.plugins.tooltip,
backgroundColor: 'rgba(0,0,0,0.7)',
borderColor: 'rgba(0,0,0,0.7)',
borderWidth: 1,
}
}
}
};
// Bar Chart Configuration
const barConfig = {
type: 'bar',
data: JSON.parse(JSON.stringify(chartData)), // Deep copy to allow independent modifications if needed
options: {
...commonOptions,
plugins: {
...commonOptions.plugins,
tooltip: { // Adjust tooltip for bar chart to show actual background color
...commonOptions.plugins.tooltip,
backgroundColor: 'rgba(0,0,0,0.7)',
borderColor: 'rgba(0,0,0,0.7)',
borderWidth: 1,
},
datalabels: { // Datalabels plugin configuration for bar chart
anchor: 'end',
align: 'start', // Align start to be inside the bar
rotation: 90, // Rotate labels by 90 degrees
color: '#ffffff', // White color for better contrast on bars
font: {
weight: 'bold',
size: 10
},
formatter: function(value) {
// Format numbers for readability, e.g., 53,182,651 becomes 53.2M
if (value >= 1000000) {
return (value / 1000000).toFixed(1) + 'M';
} else if (value >= 1000) {
return (value / 1000).toFixed(1) + 'K';
}
return value;
}
}
},
scales: {
...commonOptions.scales,
x: {
...commonOptions.scales.x,
grid: {
display: false
}
},
y: {
...commonOptions.scales.y,
// Ensure enough padding for rotated labels
grace: '5%' // Add 5% grace to the top of the Y-axis
}
}
}
};
// For bar chart, we want to use the backgroundColor property directly for bars
barConfig.data.datasets.forEach(dataset => {
// For bars, backgroundColor is the primary color, borderColor is usually the same or slightly darker
dataset.backgroundColor = dataset.borderColor;
});
const lineGrowthChart = new Chart(
document.getElementById('lineGrowthChart'),
lineConfig
);
const barGrowthChart = new Chart(
document.getElementById('barGrowthChart'),
barConfig
);
// Custom Legend Generation
const chartLegendContainer = document.getElementById('chart-legend');
chartData.datasets.forEach((dataset, index) => {
const legendItem = document.createElement('div');
legendItem.classList.add('legend-item', 'transition-colors', 'duration-200');
legendItem.innerHTML = `
<span class="legend-color-box" style="background-color: ${dataset.borderColor};"></span>
<span class="text-sm font-medium text-gray-700">${dataset.label}</span>
`;
legendItem.addEventListener('click', () => {
// Toggle visibility for both charts
const lineMeta = lineGrowthChart.getDatasetMeta(index);
const barMeta = barGrowthChart.getDatasetMeta(index);
lineMeta.hidden = !lineMeta.hidden;
barMeta.hidden = !barMeta.hidden;
lineGrowthChart.update();
barGrowthChart.update();
legendItem.style.textDecoration = lineMeta.hidden ? 'line-through' : 'none';
legendItem.style.opacity = lineMeta.hidden ? '0.6' : '1';
});
chartLegendContainer.appendChild(legendItem);
});
});
</script>
</body>