553 lines
20 KiB
HTML
553 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Gráficos com Canvas e JavaScript</title>
|
|
<style>
|
|
canvas {
|
|
border: 1px solid #000;
|
|
margin: 20px;
|
|
display: block;
|
|
max-width: 100%;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<h1>Exemplos de Gráficos com Canvas e JavaScript</h1>
|
|
|
|
<!-- Gráficos -->
|
|
<h2>Gráfico de Linha do Tempo</h2>
|
|
<canvas id="timelineChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Linhas</h2>
|
|
<canvas id="lineChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Barras</h2>
|
|
<canvas id="barChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Pizza</h2>
|
|
<canvas id="pieChart" width="400" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Área</h2>
|
|
<canvas id="areaChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Calor</h2>
|
|
<canvas id="heatmapChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico Donut</h2>
|
|
<canvas id="donutChart" width="400" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Dispersão</h2>
|
|
<canvas id="scatterChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Bolhas</h2>
|
|
<canvas id="bubbleChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Barras Empilhadas</h2>
|
|
<canvas id="stackedBarChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Linhas com Anotação</h2>
|
|
<canvas id="annotatedLineChart" width="600" height="400"></canvas>
|
|
|
|
<h2>Gráfico de Velocímetro</h2>
|
|
<canvas id="gaugeChart" width="400" height="400"></canvas>
|
|
|
|
<script>
|
|
// Função para desenhar o gráfico de linha do tempo
|
|
function drawTimelineChart(ctx, data, labels) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const maxData = Math.max(...data);
|
|
const minData = Math.min(...data);
|
|
const lineColor = 'blue';
|
|
const labelColor = 'black';
|
|
const pointRadius = 5;
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Draw data points and lines
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, height - padding - ((data[0] - minData) / (maxData - minData) * (height - 2 * padding)));
|
|
data.forEach((point, i) => {
|
|
const x = padding + i * (width - 2 * padding) / (data.length - 1);
|
|
const y = height - padding - ((point - minData) / (maxData - minData) * (height - 2 * padding));
|
|
ctx.lineTo(x, y);
|
|
ctx.arc(x, y, pointRadius, 0, 2 * Math.PI);
|
|
});
|
|
ctx.strokeStyle = lineColor;
|
|
ctx.stroke();
|
|
ctx.fillStyle = lineColor;
|
|
ctx.fill();
|
|
|
|
// Draw labels
|
|
ctx.fillStyle = labelColor;
|
|
labels.forEach((label, i) => {
|
|
const x = padding + i * (width - 2 * padding) / (labels.length - 1);
|
|
const y = height - padding + 20;
|
|
ctx.fillText(label, x, y);
|
|
});
|
|
}
|
|
|
|
// Função para desenhar o gráfico de linhas
|
|
function drawLineChart(ctx, data) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const maxData = Math.max(...data);
|
|
const minData = Math.min(...data);
|
|
const lineColor = 'blue';
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Draw line
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, height - padding - ((data[0] - minData) / (maxData - minData) * (height - 2 * padding)));
|
|
data.forEach((point, i) => {
|
|
const x = padding + i * (width - 2 * padding) / (data.length - 1);
|
|
const y = height - padding - ((point - minData) / (maxData - minData) * (height - 2 * padding));
|
|
ctx.lineTo(x, y);
|
|
});
|
|
ctx.strokeStyle = lineColor;
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Função para desenhar o gráfico de barras
|
|
function drawBarChart(ctx, data) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const barWidth = (width - 2 * padding) / data.length - 10;
|
|
const maxData = Math.max(...data);
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw bars
|
|
data.forEach((point, i) => {
|
|
const x = padding + i * ((width - 2 * padding) / data.length);
|
|
const barHeight = (point / maxData) * (height - 2 * padding);
|
|
ctx.fillStyle = 'blue';
|
|
ctx.fillRect(x, height - padding - barHeight, barWidth, barHeight);
|
|
});
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Função para desenhar o gráfico de pizza
|
|
function drawPieChart(ctx, data) {
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const radius = Math.min(width, height) / 2 - 20;
|
|
const centerX = width / 2;
|
|
const centerY = height / 2;
|
|
|
|
let startAngle = 0;
|
|
const total = data.reduce((acc, val) => acc + val, 0);
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
data.forEach((value, i) => {
|
|
const sliceAngle = (value / total) * 2 * Math.PI;
|
|
const endAngle = startAngle + sliceAngle;
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(centerX, centerY);
|
|
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
|
|
ctx.closePath();
|
|
ctx.fillStyle = `hsl(${i * 360 / data.length}, 70%, 70%)`;
|
|
ctx.fill();
|
|
|
|
startAngle = endAngle;
|
|
});
|
|
}
|
|
|
|
// Função para desenhar o gráfico de área
|
|
function drawAreaChart(ctx, data) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const maxData = Math.max(...data);
|
|
const minData = Math.min(...data);
|
|
const lineColor = 'blue';
|
|
const fillColor = 'rgba(0, 0, 255, 0.2)';
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Draw area
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, height - padding);
|
|
data.forEach((point, i) => {
|
|
const x = padding + i * (width - 2 * padding) / (data.length - 1);
|
|
const y = height - padding - ((point - minData) / (maxData - minData) * (height - 2 * padding));
|
|
ctx.lineTo(x, y);
|
|
});
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.closePath();
|
|
ctx.fillStyle = fillColor;
|
|
ctx.fill();
|
|
ctx.strokeStyle = lineColor;
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Função para desenhar o gráfico de calor
|
|
function drawHeatmapChart(ctx, data) {
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const cellSize = 30;
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw heatmap
|
|
data.forEach((row, y) => {
|
|
row.forEach((value, x) => {
|
|
const color = `rgba(255, 0, 0, ${value})`;
|
|
ctx.fillStyle = color;
|
|
ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Função para desenhar o gráfico Donut
|
|
function drawDonutChart(ctx, data) {
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const radius = Math.min(width, height) / 2 - 20;
|
|
const innerRadius = radius / 2;
|
|
const centerX = width / 2;
|
|
const centerY = height / 2;
|
|
|
|
let startAngle = 0;
|
|
const total = data.reduce((acc, val) => acc + val, 0);
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
data.forEach((value, i) => {
|
|
const sliceAngle = (value / total) * 2 * Math.PI;
|
|
const endAngle = startAngle + sliceAngle;
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
|
|
ctx.arc(centerX, centerY, innerRadius, endAngle, startAngle, true);
|
|
ctx.closePath();
|
|
ctx.fillStyle = `hsl(${i * 360 / data.length}, 70%, 70%)`;
|
|
ctx.fill();
|
|
|
|
startAngle = endAngle;
|
|
});
|
|
}
|
|
|
|
// Função para desenhar o gráfico de dispersão
|
|
function drawScatterChart(ctx, data) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const maxX = Math.max(...data.map(p => p[0]));
|
|
const minX = Math.min(...data.map(p => p[0]));
|
|
const maxY = Math.max(...data.map(p => p[1]));
|
|
const minY = Math.min(...data.map(p => p[1]));
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Draw points
|
|
data.forEach(([x, y]) => {
|
|
const px = padding + (x - minX) / (maxX - minX) * (width - 2 * padding);
|
|
const py = height - padding - (y - minY) / (maxY - minY) * (height - 2 * padding);
|
|
ctx.beginPath();
|
|
ctx.arc(px, py, 5, 0, 2 * Math.PI);
|
|
ctx.fillStyle = 'blue';
|
|
ctx.fill();
|
|
});
|
|
}
|
|
|
|
// Função para desenhar o gráfico de bolhas
|
|
function drawBubbleChart(ctx, data) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const maxX = Math.max(...data.map(p => p[0]));
|
|
const minX = Math.min(...data.map(p => p[0]));
|
|
const maxY = Math.max(...data.map(p => p[1]));
|
|
const minY = Math.min(...data.map(p => p[1]));
|
|
const maxSize = Math.max(...data.map(p => p[2]));
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Draw bubbles
|
|
data.forEach(([x, y, size]) => {
|
|
const px = padding + (x - minX) / (maxX - minX) * (width - 2 * padding);
|
|
const py = height - padding - (y - minY) / (maxY - minY) * (height - 2 * padding);
|
|
const radius = (size / maxSize) * 20;
|
|
ctx.beginPath();
|
|
ctx.arc(px, py, radius, 0, 2 * Math.PI);
|
|
ctx.fillStyle = 'blue';
|
|
ctx.fill();
|
|
});
|
|
}
|
|
|
|
// Função para desenhar o gráfico de barras empilhadas
|
|
function drawStackedBarChart(ctx, data) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const barWidth = (width - 2 * padding) / data[0].length - 10;
|
|
const maxData = Math.max(...data.flat());
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw bars
|
|
for (let i = 0; i < data.length; i++) {
|
|
data[i].forEach((point, j) => {
|
|
const x = padding + j * ((width - 2 * padding) / data[0].length);
|
|
const barHeight = (point / maxData) * (height - 2 * padding);
|
|
ctx.fillStyle = `rgba(0, 0, 255, ${i / data.length})`;
|
|
ctx.fillRect(x, height - padding - barHeight, barWidth, barHeight);
|
|
});
|
|
}
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
}
|
|
|
|
|
|
function drawAnnotatedLineChart(ctx, data, annotations) {
|
|
const padding = 40;
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const maxData = Math.max(...data);
|
|
const minData = Math.min(...data);
|
|
const lineColor = 'blue';
|
|
const annotationColor = 'red';
|
|
const gridColor = 'lightgray';
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw axes
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, padding);
|
|
ctx.lineTo(padding, height - padding);
|
|
ctx.lineTo(width - padding, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Draw grid lines and Y-axis labels
|
|
const numGridLinesX = 10; // Número de linhas de grade no eixo X
|
|
const numGridLinesY = 10; // Número de linhas de grade no eixo Y
|
|
|
|
// Linhas verticais e rótulos do eixo X
|
|
for (let i = 0; i <= numGridLinesX; i++) {
|
|
const x = padding + (i * (width - 2 * padding) / numGridLinesX);
|
|
ctx.strokeStyle = gridColor;
|
|
ctx.beginPath();
|
|
ctx.moveTo(x, padding);
|
|
ctx.lineTo(x, height - padding);
|
|
ctx.stroke();
|
|
|
|
// Rótulo do eixo X
|
|
ctx.fillText(`X${i}`, x, height - padding + 20);
|
|
}
|
|
|
|
// Linhas horizontais e rótulos do eixo Y
|
|
for (let i = 0; i <= numGridLinesY; i++) {
|
|
const y = height - padding - (i * (height - 2 * padding) / numGridLinesY);
|
|
ctx.strokeStyle = gridColor;
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, y);
|
|
ctx.lineTo(width - padding, y);
|
|
ctx.stroke();
|
|
|
|
// Rótulo do eixo Y
|
|
const yValue = minData + (i * (maxData - minData) / numGridLinesY);
|
|
ctx.fillText(yValue.toFixed(2), padding - 30, y);
|
|
}
|
|
|
|
// Draw line
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, height - padding - ((data[0] - minData) / (maxData - minData) * (height - 2 * padding)));
|
|
data.forEach((point, i) => {
|
|
const x = padding + i * (width - 2 * padding) / (data.length - 1);
|
|
const y = height - padding - ((point - minData) / (maxData - minData) * (height - 2 * padding));
|
|
ctx.lineTo(x, y);
|
|
});
|
|
ctx.strokeStyle = lineColor;
|
|
ctx.stroke();
|
|
|
|
// Draw annotations
|
|
annotations.forEach(([x, y, text]) => {
|
|
ctx.fillStyle = annotationColor;
|
|
ctx.beginPath();
|
|
ctx.arc(x, y, 5, 0, 2 * Math.PI);
|
|
ctx.fill();
|
|
ctx.fillText(text, x + 10, y);
|
|
});
|
|
}
|
|
|
|
|
|
|
|
// Função para desenhar o gráfico de velocímetro
|
|
function drawGaugeChart(ctx, value) {
|
|
const width = ctx.canvas.width;
|
|
const height = ctx.canvas.height;
|
|
const radius = Math.min(width, height) / 2 - 20;
|
|
const centerX = width / 2;
|
|
const centerY = height / 2;
|
|
const maxValue = 100;
|
|
const angle = (value / maxValue) * Math.PI;
|
|
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw gauge
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, radius, Math.PI, Math.PI + Math.PI);
|
|
ctx.lineTo(centerX, centerY);
|
|
ctx.closePath();
|
|
ctx.fillStyle = 'lightgrey';
|
|
ctx.fill();
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, radius, Math.PI, Math.PI + angle);
|
|
ctx.lineTo(centerX, centerY);
|
|
ctx.closePath();
|
|
ctx.fillStyle = 'blue';
|
|
ctx.fill();
|
|
|
|
// Draw needle
|
|
ctx.beginPath();
|
|
ctx.moveTo(centerX, centerY);
|
|
const needleX = centerX + (radius - 10) * Math.cos(Math.PI + angle);
|
|
const needleY = centerY + (radius - 10) * Math.sin(Math.PI + angle);
|
|
ctx.lineTo(needleX, needleY);
|
|
ctx.strokeStyle = 'black';
|
|
ctx.stroke();
|
|
}
|
|
|
|
const timelineCanvas = document.getElementById('timelineChart');
|
|
const lineCanvas = document.getElementById('lineChart');
|
|
const barCanvas = document.getElementById('barChart');
|
|
const pieCanvas = document.getElementById('pieChart');
|
|
const areaCanvas = document.getElementById('areaChart');
|
|
const heatmapCanvas = document.getElementById('heatmapChart');
|
|
const donutCanvas = document.getElementById('donutChart');
|
|
const scatterCanvas = document.getElementById('scatterChart');
|
|
const bubbleCanvas = document.getElementById('bubbleChart');
|
|
const stackedBarCanvas = document.getElementById('stackedBarChart');
|
|
const annotatedLineCanvas = document.getElementById('annotatedLineChart');
|
|
const gaugeCanvas = document.getElementById('gaugeChart');
|
|
|
|
const timelineCtx = timelineCanvas.getContext('2d');
|
|
const lineCtx = lineCanvas.getContext('2d');
|
|
const barCtx = barCanvas.getContext('2d');
|
|
const pieCtx = pieCanvas.getContext('2d');
|
|
const areaCtx = areaCanvas.getContext('2d');
|
|
const heatmapCtx = heatmapCanvas.getContext('2d');
|
|
const donutCtx = donutCanvas.getContext('2d');
|
|
const scatterCtx = scatterCanvas.getContext('2d');
|
|
const bubbleCtx = bubbleCanvas.getContext('2d');
|
|
const stackedBarCtx = stackedBarCanvas.getContext('2d');
|
|
const annotatedLineCtx = annotatedLineCanvas.getContext('2d');
|
|
const gaugeCtx = gaugeCanvas.getContext('2d');
|
|
|
|
const timelineData = [5, 10, 15, 20, 25];
|
|
const timelineLabels = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
|
|
|
|
const lineData = [10, 20, 15, 25, 30];
|
|
const barData = [12, 19, 3];
|
|
const pieData = [300, 50, 100];
|
|
const areaData = [10, 20, 15, 25, 30];
|
|
const heatmapData = [
|
|
[0.1, 0.3, 0.5, 0.7],
|
|
[0.2, 0.4, 0.6, 0.8],
|
|
[0.3, 0.5, 0.7, 0.9],
|
|
[0.4, 0.6, 0.8, 1.0]
|
|
];
|
|
const donutData = [300, 50, 100];
|
|
const scatterData = [
|
|
[10, 20], [15, 25], [20, 30]
|
|
];
|
|
const bubbleData = [
|
|
[10, 20, 30], [15, 25, 20], [20, 30, 10]
|
|
];
|
|
const stackedBarData = [
|
|
[10, 20, 30],
|
|
[15, 25, 35]
|
|
];
|
|
const annotatedLineData = [10, 20, 15, 25, 30];
|
|
const annotations = [
|
|
[100, 200, 'A'],
|
|
[200, 300, 'B']
|
|
];
|
|
const gaugeValue = 75;
|
|
|
|
drawTimelineChart(timelineCtx, timelineData, timelineLabels);
|
|
drawLineChart(lineCtx, lineData);
|
|
drawBarChart(barCtx, barData);
|
|
drawPieChart(pieCtx, pieData);
|
|
drawAreaChart(areaCtx, areaData);
|
|
drawHeatmapChart(heatmapCtx, heatmapData);
|
|
drawDonutChart(donutCtx, donutData);
|
|
drawScatterChart(scatterCtx, scatterData);
|
|
drawBubbleChart(bubbleCtx, bubbleData);
|
|
drawStackedBarChart(stackedBarCtx, stackedBarData);
|
|
drawAnnotatedLineChart(annotatedLineCtx, annotatedLineData, annotations);
|
|
drawGaugeChart(gaugeCtx, gaugeValue);
|
|
</script>
|
|
</body>
|
|
|
|
</html> |