如何用AJAX请求PHP接口的JSON数据实现D3.js咖啡轮图动态更新?
Hey there! As a fellow D3.js learner, I totally get where you're stuck—switching from static local JSON to dynamic database-backed data can feel a bit daunting at first, but it's absolutely achievable. Let's break down a solid, actionable solution step by step:
First, you need to ensure your PHP endpoint spits out JSON that matches the exact structure of the original wheel.json (this is probably where things went wrong before!). Here's a sample PHP script to fetch data from your database and format it correctly:
<?php // Set the correct content type for JSON header('Content-Type: application/json'); // Allow CORS if your frontend and backend are on different domains (adjust for production!) header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET"); // Connect to your database (replace with your credentials) $dbConn = new mysqli('localhost', 'your_username', 'your_password', 'your_database'); if ($dbConn->connect_error) { die(json_encode(['error' => 'Failed to connect to database'])); } // Query your coffee data (adjust the query to match your table structure) $queryResult = $dbConn->query("SELECT * FROM coffee_hierarchy"); $coffeeData = []; // Map database rows to match the original wheel.json structure while ($row = $queryResult->fetch_assoc()) { $coffeeData[] = [ 'name' => $row['coffee_category'], 'children' => json_decode($row['subcategories'], true) // If subdata is stored as JSON in DB // Adjust fields to exactly match the keys in the original wheel.json! ]; } // Output the formatted JSON echo json_encode($coffeeData); $dbConn->close(); ?>
Test this by visiting the PHP file directly in your browser—you should see JSON that looks identical to the original wheel.json. If not, tweak the PHP code until the structure matches perfectly.
The original coffee wheel example uses D3's d3.json() to load local data. Swap that out for a call to your PHP endpoint. D3's native AJAX works seamlessly with its data flow, so this is the most reliable approach:
// Original code (loads local file): // d3.json("wheel.json", function(error, root) { ... }) // Updated code (loads from PHP endpoint): d3.json("your-coffee-endpoint.php") .then(function(root) { // Paste ALL the original coffee wheel initialization code here // This includes setting up the cluster layout, diagonal projection, drawing nodes/links, etc. // Example snippet from the original: var radius = 960 / 2; var cluster = d3.layout.cluster() .size([360, radius - 120]); var diagonal = d3.svg.diagonal.radial() .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; }); var svg = d3.select("body").append("svg") .attr("width", radius * 2) .attr("height", radius * 2) .append("g") .attr("transform", "translate(" + radius + "," + radius + ")"); // Continue with the rest of the drawing logic using the dynamically loaded `root` data }) .catch(function(error) { console.error("Oops, failed to load data:", error); // Add user-friendly error handling here, like showing a message on the page });
If you still want to use jQuery's $.ajax, here's how to make it work—just ensure you pass the data correctly to D3's logic and fix these common issues:
$.ajax({ url: "your-coffee-endpoint.php", dataType: "json", success: function(root) { // Important: Make sure `root` matches the original wheel.json structure exactly // Clear any existing chart elements first (if you're updating) d3.select("svg").remove(); // Then run the full coffee wheel initialization code here, using `root` as your data }, error: function(xhr, status, err) { console.error("AJAX Error:", err); // Check the browser console for details—common issues include: // - 404: Wrong PHP endpoint path // - 500: PHP code errors (check your server logs) // - Invalid JSON: PHP is returning non-JSON content } });
To make the chart refresh when your database changes, add a refresh function that re-fetches the data and redraws the chart:
function refreshCoffeeWheel() { d3.json("your-coffee-endpoint.php") .then(function(root) { // Clear old chart d3.select("svg").remove(); // Re-run the full initialization code with new data // ... (paste your chart code here) ... }) .catch(function(error) { console.error("Refresh failed:", error); }); } // Load on page load refreshCoffeeWheel(); // Add a button to trigger refresh d3.select("body").append("button") .text("Refresh Coffee Wheel") .on("click", refreshCoffeeWheel);
内容的提问来源于stack exchange,提问作者Francis Katalinic

