You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将流量统计JSON数据展示为分组柱状图(Grouped Bar Chart)

Got it, let's build a flexible grouped bar chart solution for your hourly traffic data. Below are two solid implementations—one using Chart.js (great for quick, clean charts with minimal code) and another with vanilla JS + D3.js (for full control over every detail). Both work with any grouped data structure, not just your traffic stats.

Grouped Bar Chart Implementation for Traffic Data

Option 1: Using Chart.js (Quick & User-Friendly)

Chart.js is perfect if you want a low-effort setup with built-in responsiveness and interactivity. Here's how to map your JSON data to a grouped bar chart:

Step 1: Set Up HTML Structure

First, add a canvas element where the chart will render:

<canvas id="trafficChart" width="800" height="400"></canvas>

Step 2: Include Chart.js

Download the latest version of Chart.js from its official repository, save it locally, and include it with a script tag:

<script src="./path/to/chart.min.js"></script>

Step 3: Parse & Render the Chart

Write the JavaScript to process your JSON data and generate the chart:

// Your traffic data
const trafficData = [
  {"call_time":"0","total_inc_traffic":"1363.10","total_out_traffic":"88.70"},
  {"call_time":"1","total_inc_traffic":"479.57","total_out_traffic":"36.98"},
  {"call_time":"2","total_inc_traffic":"239.57","total_out_traffic":"13.43"},
  {"call_time":"3","total_inc_traffic":"190.28","total_out_traffic":"8.20"},
  {"call_time":"4","total_inc_traffic":"223.80","total_out_traffic":"0.00"},
  {"call_time":"5","total_inc_traffic":"158.87","total_out_traffic":"19.58"},
  {"call_time":"6","total_inc_traffic":"27.52","total_out_traffic":"36.18"},
  {"call_time":"7","total_inc_traffic":"47.70","total_out_traffic":"69.57"},
  {"call_time":"8","total_inc_traffic":"2234.35","total_out_traffic":"137.60"},
  {"call_time":"9","total_inc_traffic":"150.67","total_out_traffic":"162.07"},
  {"call_time":"10","total_inc_traffic":"4497.05","total_out_traffic":"267.32"},
  {"call_time":"11","total_inc_traffic":"5049.87","total_out_traffic":"242.42"},
  {"call_time":"12","total_inc_traffic":"5227.67","total_out_traffic":"286.88"},
  {"call_time":"13","total_inc_traffic":"3384.30","total_out_traffic":"360.88"},
  {"call_time":"14","total_inc_traffic":"3650.73","total_out_traffic":"328.28"}
];

// Extract labels and datasets from the JSON
const labels = trafficData.map(item => `Hour ${item.call_time}`);
const incomingTraffic = trafficData.map(item => parseFloat(item.total_inc_traffic));
const outgoingTraffic = trafficData.map(item => parseFloat(item.total_out_traffic));

// Initialize the grouped bar chart
const ctx = document.getElementById('trafficChart').getContext('2d');
new Chart(ctx, {
  type: 'bar',
  data: {
    labels: labels,
    datasets: [
      {
        label: 'Incoming Traffic (MB)',
        data: incomingTraffic,
        backgroundColor: 'rgba(54, 162, 235, 0.6)',
        borderColor: 'rgba(54, 162, 235, 1)',
        borderWidth: 1
      },
      {
        label: 'Outgoing Traffic (MB)',
        data: outgoingTraffic,
        backgroundColor: 'rgba(255, 99, 132, 0.6)',
        borderColor: 'rgba(255, 99, 132, 1)',
        borderWidth: 1
      }
    ]
  },
  options: {
    responsive: true,
    scales: {
      y: {
        beginAtZero: true,
        title: {
          display: true,
          text: 'Traffic Volume (MB)'
        }
      },
      x: {
        title: {
          display: true,
          text: 'Hour of Day'
        }
      }
    },
    plugins: {
      legend: {
        position: 'top',
      },
      tooltip: {
        mode: 'index',
        intersect: false
      }
    }
  }
});

Adapting to Any Grouped Data

  • Swap the labels array with your category values (e.g., product names, regions).
  • Add more objects to the datasets array for additional data groups (e.g., a third traffic type).
  • Adjust the parseFloat step if your data uses different numeric formats (e.g., commas as decimal separators).

Option 2: Vanilla JavaScript + D3.js (Full Customization)

If you need complete control over animations, styling, or complex interactions, D3.js is the way to go. Here's a flexible implementation:

Step 1: HTML Structure

Add a container for the SVG chart:

<div id="chartContainer" style="width: 800px; height: 400px;"></div>

Step 2: Include D3.js

Download D3.js v7 from its official repository, save it locally, and include it:

<script src="./path/to/d3.v7.min.js"></script>

Step 3: D3.js Code for Grouped Bars

const trafficData = [/* Paste your JSON data here */];

// Set up chart dimensions and margins
const margin = {top: 30, right: 30, bottom: 70, left: 60};
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;

// Create SVG container
const svg = d3.select("#chartContainer")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left}, ${margin.top})`);

// Prepare data: Convert string values to numbers
trafficData.forEach(d => {
  d.total_inc_traffic = +d.total_inc_traffic;
  d.total_out_traffic = +d.total_out_traffic;
});

// Define groups and their display names
const groups = ["total_inc_traffic", "total_out_traffic"];
const groupLabels = {
  "total_inc_traffic": "Incoming Traffic (MB)",
  "total_out_traffic": "Outgoing Traffic (MB)"
};
const hourLabels = trafficData.map(d => `Hour ${d.call_time}`);

// Set up scales for axes and bar positioning
const x0 = d3.scaleBand()
  .domain(hourLabels)
  .range([0, width])
  .padding(0.2);

const x1 = d3.scaleBand()
  .domain(groups)
  .range([0, x0.bandwidth()])
  .padding(0.1);

const y = d3.scaleLinear()
  .domain([0, d3.max(trafficData, d => Math.max(d.total_inc_traffic, d.total_out_traffic))])
  .range([height, 0]);

// Add X and Y axes
svg.append("g")
  .attr("transform", `translate(0, ${height})`)
  .call(d3.axisBottom(x0))
  .selectAll("text")
  .attr("transform", "rotate(-45)")
  .style("text-anchor", "end");

svg.append("g")
  .call(d3.axisLeft(y));

// Render grouped bars
svg.append("g")
  .selectAll("g")
  .data(trafficData)
  .enter()
  .append("g")
  .attr("transform", d => `translate(${x0(`Hour ${d.call_time}`)}, 0)`)
  .selectAll("rect")
  .data(d => groups.map(key => ({key: key, value: d[key]})))
  .enter()
  .append("rect")
  .attr("x", d => x1(d.key))
  .attr("y", d => y(d.value))
  .attr("width", x1.bandwidth())
  .attr("height", d => height - y(d.value))
  .attr("fill", d => d.key === "total_inc_traffic" ? "#36a2eb" : "#ff6384");

// Add axis titles
svg.append("text")
  .attr("transform", `translate(${width/2}, ${height + margin.bottom - 10})`)
  .style("text-anchor", "middle")
  .text("Hour of Day");

svg.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 0 - margin.left)
  .attr("x", 0 - (height / 2))
  .attr("dy", "1em")
  .style("text-anchor", "middle")
  .text("Traffic Volume (MB)");

// Add legend
const legend = svg.append("g")
  .attr("transform", `translate(${width - 150}, 0)`);

groups.forEach((group, index) => {
  const legendRow = legend.append("g")
    .attr("transform", `translate(0, ${index * 25})`);

  legendRow.append("rect")
    .attr("width", 15)
    .attr("height", 15)
    .attr("fill", group === "total_inc_traffic" ? "#36a2eb" : "#ff6384");

  legendRow.append("text")
    .attr("x", 20)
    .attr("y", 12)
    .style("font-size", "12px")
    .text(groupLabels[group]);
});

Flexibility for Any Grouped Data

  • To add more data groups, extend the groups array and update groupLabels with new display names.
  • Adjust colors, padding, or axis behavior by modifying scale attributes and styling properties.
  • The code uses a generic approach to map data keys to bars, so it works with any JSON structure where each object has category labels and numeric group values.

Quick Tips for Adaptation

  • Data Parsing: Always convert string-based numeric values to actual numbers (using parseFloat or the + operator) to ensure proper chart rendering.
  • Responsiveness: Both solutions can be made responsive by using relative container widths/heights and adjusting scale ranges dynamically.
  • Customization: Tweak colors, labels, tooltips, and animations to match your design requirements.

内容的提问来源于stack exchange,提问作者Tanvir Nabil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:40:40