如何修改D3环形柱状图代码以接收本地对象而非CSV文件?
Hey there! Let's work through this D3 circular bar plot modification step by step.
First, let's clear up the confusion about data loading methods
You don't need d3.json or any of the d3-fetch file-loading functions here—those are meant for pulling data from external files/APIs. Since your data already exists in the current scope, we can skip the async loading entirely and work directly with your object.
Do you need to add CSV-like column names?
Yes, you do. The original code is built around the CSV structure where each entry has Country and Value properties. To keep the rest of the plotting logic intact, we'll convert your flat key-value object into an array of objects that matches this structure.
Step-by-step code modification
Let's break this down with concrete examples:
Convert your scope object to a structured array
Suppose your local data object looks like this:const localData = {0: 3, 1: 7, 2: 9, 3: 2, 4: 5};We'll use
Object.entries()to turn this into an array of objects with theCountryandValuefields the original code expects:const formattedData = Object.entries(localData).map(([country, value]) => ({ Country: country, // Use the object's key as the "Country" value Value: Number(value) // Convert the value to a number (matches CSV data type) }));If your keys are actual country names (like
{ "USA": 10, "China": 15 }), this works even better—just replace the key variable name with something more descriptive if you want.Replace the CSV loading code
The original code usesd3.csv()to fetch and process data. We'll remove that async wrapper and directly use our formatted array:// Remove this original code block: // d3.csv("your-remote-file.csv").then(function(data) { // // Plotting logic here // }) // Instead, use our formatted local data directly const data = formattedData; // Now run the rest of the original plotting logic exactly as-is // For example: data.forEach(d => { d.Value = +d.Value; // Optional: already converted to number, but safe to keep }); // Then proceed with creating the SVG, scales, arcs, labels, etc.
Full modified example snippet
Here's how the core part of your code will look after the change:
// Your local scope data object const localData = {0: 3, 1: 7, 2: 9, 3: 2, 4: 5}; // Convert to CSV-compatible structure const formattedData = Object.entries(localData).map(([country, value]) => ({ Country: country, Value: Number(value) })); // Set up SVG and dimensions (same as original) const width = 450; const height = 450; const margin = 40; const radius = Math.min(width, height) / 2 - margin; const svg = d3.select("#my_dataviz") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", `translate(${width/2}, ${height/2})`); // Scales (uses formattedData instead of CSV data) const x = d3.scaleBand() .range([0, 2 * Math.PI]) .domain(formattedData.map(d => d.Country)) .padding(0.05); const y = d3.scaleRadial() .range([0, radius]) .domain([0, d3.max(formattedData, d => d.Value)]); // Draw the circular bars (same as original, uses formattedData) svg.append("g") .selectAll("path") .data(formattedData) .enter() .append("path") .attr("d", d3.arc() .innerRadius(0) .outerRadius(d => y(d.Value)) .startAngle(d => x(d.Country)) .endAngle(d => x(d.Country) + x.bandwidth()) .padAngle(0.01) .padRadius(radius)) .attr("fill", "#69b3a2"); // Add labels (same as original) svg.append("g") .selectAll("g") .data(formattedData) .enter() .append("g") .attr("text-anchor", function(d) { return (x(d.Country) + x.bandwidth() / 2 + Math.PI) % (2 * Math.PI) < Math.PI ? "end" : "start"; }) .attr("transform", function(d) { return "rotate(" + ((x(d.Country) + x.bandwidth() / 2) * 180 / Math.PI - 90) + ")"+"translate(" + (y(d.Value)+10) + ",0)"; }) .append("text") .text(d => d.Country) .attr("transform", function(d) { return (x(d.Country) + x.bandwidth() / 2 + Math.PI) % (2 * Math.PI) < Math.PI ? "rotate(180)" : "rotate(0)"; }) .style("font-size", "11px") .attr("alignment-baseline", "middle");
This approach keeps all the original plotting logic intact—we're just swapping out the external data source with your local scope data, formatted to match what the code expects.
内容的提问来源于stack exchange,提问作者otk

