oym*_*onk 6 html javascript d3.js
我有一个数据集,CategoryLevel1其中包含一个名为组的名称的列。我将nest函数应用于Categorylevel1并基于键生成了一系列svg。然后,我创建了代表整个数据集中项目的矩形,并在每个svg中重复了这些矩形。我对每个svg应用了一个过滤器,因此只能看到带有该svg键的数据集项。
我的真实数据集大于此处表示的玩具数据集。上面代码的结果是svgs的网页很长-非常混乱。为了使事情更清楚,我希望将svgs根据称为的列进行分组CategoryLevel2。这是我追求的效果:
这是我到目前为止的内容:
var doc = `Manual Name CategoryLevel1 CategoryLevel2
DOG "General Furry, Program and Subject Files" Average Quantity and Planning Edibles
TR Senate Committee on animal Standards Bowl and Plate Design Edibles
TR Published Canine Bowl and Plate Design Edibles
TR Canine case files Bowl and Plate Design Edibles
DOG Canine Files Avoiding Neck Strain Edibles
DOG Canine Files Drooling Edibles
DOG Canine Files Drooling Edibles
DG ADVERTISING At home At home
DG PROMOTIONS At home At home
DG3 Publications At home At home
TR Public and Information Services At home At home
TR Petting Services Getting special treats At home
TR Petting Services Getting special treats At home
TR Petting Services Getting special treats At home
TR Petting Services Getting special treats At home
TR Petting Services Getting special treats At home
TR Petting Services Getting special treats At home
DG DEVELOPMENT Optimal time of day - walking Walks and outings
DG INCOME AND REVENUE Optimal time of day - walking Walks and outings
TR Fundraising Optimal time of day - walking Walks and outings
TR Fundraising Optimal time of day - walking Walks and outings
DG DEVELOPMENT Optimal time of day - walking Walks and outings
DG INCOME AND REVENUE Optimal time of day - walking Walks and outings
TR Wishbone Protective Measures Walks and outings
TR Wishbone Protective Measures Walks and outings
DG Wishbone Observant of Limps Etc Walks and outings
DOG Wishbone Observant of Limps Etc Walks and outings
TR Wishbone Observant of Limps Etc Walks and outings`;
const data = d3.tsvParse(doc, function(d) {
return {
Manual: d.Manual,
Name: d.Name,
CategoryLevel1: d.CategoryLevel1,
CategoryLevel2: d.CategoryLevel2
};
});
var nest = d3.nest()
.key(function(d) {
return d.CategoryLevel1;
})
.entries(data);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0)
var height = 100,
width = 300;
var color = d3.scaleOrdinal(["#edf8fb", "#b3cde3", "#8c96c6", "#88419d"]);
/* var svg = d3.select("body").append("svg").attr("height", "100%").attr("width", "100%");
var g = d3.select("svg").attr("height", "100%").attr("width", "100%"); */
var svgs = d3.select("body")
.selectAll("svg")
.data(nest)
.enter()
.append('svg')
.attr("width", width)
.attr("height", height + 20);
svgs.append("text")
.attr('class', 'label')
.data(nest)
.attr('x', width / 2)
.attr('y', height)
.text(function(d) {
return d.key;
})
.attr('text-anchor', 'middle')
svgs.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.filter(function(d, i) {
const x = d3.select(this.parentNode).datum();
return x.key == d.CategoryLevel1 ? 1 : 0;
})
.attr("height", function(d) {
return 50;
})
.attr("width", "5")
.attr("x", function(d, i) {
return i * 10;
})
.attr("y", 0)
.attr("fill", function(d) {
return color(d.Manual)
})
.on("mouseover", function(d, i) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(`${d.Name}`)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 50) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});Run Code Online (Sandbox Code Playgroud)
.page {
width: 90%;
margin: auto;
}
.menu {
height: 100px;
background-color: #B2D6FF;
/* Medium blue */
}
.sidebar {
height: 50px;
width: 15%;
background-color: #F09A9D;
float: inline-start;
display: block;
margin: 0.1%;
/* Red */
}
.title {
width: 100%;
background-color: none;
display: inline-block;
float: inline-start;
/* Yellow */
}
div.tooltip {
position: absolute;
text-align: center;
width: auto;
height: auto;
padding: 3px;
font: 12px sans-serif;
border: 0px;
border-radius: 3px;
pointer-events: none;
background: lightgrey;
}Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Mapping Dog Care Manuals</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
</html>Run Code Online (Sandbox Code Playgroud)
我尝试过的
我尝试创建表示CategoryLevel2的svg,然后附加“ innerSVG”并运行将生成CategoryLevel1 svgs的代码。问题出在过滤器行中-它无法访问CategoryLevel1的正确父级:
.filter(function(d, i) {
const x = d3.select(this.parentNode).datum();
return x.key == d.CategoryLevel1 ? 1 : 0;
})
Run Code Online (Sandbox Code Playgroud)
我还尝试使用“转换,转换”功能基于Categorylevel1分隔矩形,但是拒绝了此操作,因为移动与CategoryLevel1相关联的文本会很棘手。
我现在正在尝试使用d3.hierarchy布局之一。问题是,一旦我将d3.stratify应用于数据集,结果就无法用于生成一系列svg。也就是说,应用以下代码后,DOM中什么都不会显示:(仅供参考,我还用root.descendants()等替换了treeData,
var treeData = d3.stratify()
.id(function(d) { return d.CategoryLevel1; })
.parentId(function(d) { return d.CategoryLevel2; })
(data);
var svgs = d3.select("chart")
.selectAll("svg")
.data(treeData)
.enter()
.append('svg')
.attr("width", width)
.attr("height", height + 20);
Run Code Online (Sandbox Code Playgroud)
这里缺少一个重要信息:您没有告诉我们您要如何分隔CategoryLevel2组:在同一行中?在同一列?还有其他模式吗?
因此,在我的解决方案中,我将使用一个容器<div>将display: flex组分成 3列,每个值对应一个组CategoryLevel2(分别是Edibles, At Home Walks and outings)。
CategoryLevel2只需使用嵌套函数中的第一个键即可完成此操作:
var nest = d3.nest()
.key(function(d) {
return d.CategoryLevel2;
})
.key(function(d) {
return d.CategoryLevel1;
})
.entries(data);
Run Code Online (Sandbox Code Playgroud)
这将创建以下数组:
[{key: "Edibles", values: Array},
{key: "At home", values: Array},
{key: "Walks and outings", values: Array}];
Run Code Online (Sandbox Code Playgroud)
在每个values值中,您将拥有原始的巢,例如:
{
"key": "Edibles",
"values": [{
"key": "Average Quantity and Planning",
"values": [
//etc...
]
}, {
"key": "Bowl and Plate Design",
"values": [
//etc..
]
}, {
"key": "Avoiding Neck Strain",
"values": [
//etc...
]
}, {
"key": "Drooling",
"values": [
//etc
]
}]
}
Run Code Online (Sandbox Code Playgroud)
然后使用嵌套数据附加 div:
var divs = d3.select(".container")
.selectAll(null)
.data(nest)
.enter()
.append("div")
.attr("class", "innerdiv");
Run Code Online (Sandbox Code Playgroud)
当然,不要忘记将内部数组用于真正的 SVG:
var svgs = divs.selectAll(null)
.data(function(d) {
return d.values;
})
.enter()
//etc...
Run Code Online (Sandbox Code Playgroud)
以下是经过这些更改的代码:
var nest = d3.nest()
.key(function(d) {
return d.CategoryLevel2;
})
.key(function(d) {
return d.CategoryLevel1;
})
.entries(data);
Run Code Online (Sandbox Code Playgroud)
[{key: "Edibles", values: Array},
{key: "At home", values: Array},
{key: "Walks and outings", values: Array}];
Run Code Online (Sandbox Code Playgroud)
{
"key": "Edibles",
"values": [{
"key": "Average Quantity and Planning",
"values": [
//etc...
]
}, {
"key": "Bowl and Plate Design",
"values": [
//etc..
]
}, {
"key": "Avoiding Neck Strain",
"values": [
//etc...
]
}, {
"key": "Drooling",
"values": [
//etc
]
}]
}
Run Code Online (Sandbox Code Playgroud)