这里有一个d3新手。我正在尝试将csv文件中的所有元素分组,以便在饼图上显示为单个segemnt。
这是csv文件。 (一个更大的文件的简化版本,我将20-30个条目分组):
colors,count
red,34
blue,33
green,21
yellow,41
red,16
red, 21
orange,51
这就是我现在所得到的: http://bricbracs.com/test/
我想要将红色元素和相应的计数分组,以便它看起来像这样: http://bricbracs.com/test1/
可能有一个简单的解决方案。这是d3脚本。没什么好看的,只是你是标准的饼图。
<script>
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.count; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.csv("data.csv", function(error, data) {
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.colors); });
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.colors; });
})
</script>
答案 0 :(得分:1)
有很多方法可以做到这一点。如果您想要一个直接d3
解决方案,那么d3.nest:
d3.csv("data.csv", function(error, data) {
var data = d3.nest()
.key(function(d) {
return d.colors;
})
.rollup(function(d) {
return d3.sum(d, function(g) {
return g.count;
});
}).entries(data);
...
完整示例here。
答案 1 :(得分:0)
当我必须为d3执行数据转换任务时,我更喜欢在后端执行此操作,因为您可以模拟数据并针对转换引擎运行测试。然后你只是将数据发送到d3。即:
(C#MVC Web Api示例)
public class RestaurantViewModel
{
public List<RestaurantDataSeries> RestaurantData { get; set; }
}
public class RestaurantDataSeries
{
public string Zipcode { get; set; }
public List<ScoreDataPoint> DataSeries { get; set; }
}
public class ScoreDataPoint
{
public string Score { get; set; }
public int Count { get; set; }
}
public RestaurantViewModel GetRestaurantSeries()
{
var csvConfiguration = new CsvConfiguration();
csvConfiguration.RegisterClassMap<RestaurantDataMap>();
const string fileName = "Restaurant_Inspection_Scores_Chart.csv";
using (var streamReader = _fileSource.GetFile(fileName))
{
var csvReader = new CsvReader(streamReader, csvConfiguration);
var restaurantDataPoints = csvReader.GetRecords<RestaurantData>().ToList();
var zipcodes =
restaurantDataPoints.DistinctBy(point => point.Zipcode).Select(point => point.Zipcode).ToList(); //Distinct zips
var restaurantDataSeries = new List<RestaurantDataSeries>();
var scoreList = new List<string> {"A", "B", "C", "D"};
foreach (var zipcode in zipcodes)
{
var currentRestaurantDataSeries = new RestaurantDataSeries
{
Zipcode = zipcode,
DataSeries = new List<ScoreDataPoint>()
};
foreach (var score in scoreList)
{
currentRestaurantDataSeries.DataSeries.Add(new ScoreDataPoint
{
Score = score,
Count =
restaurantDataPoints.Count(
point => point.Zipcode == zipcode && ScoreConverter.GetScore(point.Score) == score)
});
}
restaurantDataSeries.Add(currentRestaurantDataSeries);
}
return new RestaurantViewModel {RestaurantData = restaurantDataSeries};
}
}
然后我在D3中使用格式化的列表,所有这些都很简单,而无需在javascript中进行数据转换。但话说回来,我发现在静态类型语言中使用数据很多更简单,我可以在编译时而不是运行时对名称和转换进行验证。