Reputation:
I've taught myself d3 (still learning), and have a finished visualisation that I'm more than happy with.
But i think (know) that the code can be improved and made more efficient. For instance, use a csv file for the data (don't know where to begin with that). But more specifically, i'd like to know how the hard coded colours can be used directly with d3, but categorised by cancer, diabetes, CHD (exactly how i've hardcoded them). Additionally, rather than use the messy html and css i have for the titles, is there anything that can be done via d3?
I believe i'm pretty good with html and css, but i was a little daunted by d3 and the html/css are inherently mess.
I've attached an image of what it looks like (please ignore the data under South England: I know it's duplicated; I have to replace them with the actual data).
@import url("https://fonts.googleapis.com/css?family=Lato:300");
rect {
stroke: white;
}
text {
font-family: "Lato";
fill: white;
font-size: 8px;
text-anchor: middle;
}
svg {
padding-left: 60px;
padding-top:17px;
position: fixed;
}
p {
font-size: 14px;
}
.p1 {
position: absolute;
font-family: "Lato";
font-size: 17px;
padding-left: 60px;
}
.p2 {
position: absolute;
font-family: "Lato";
font-size: 17px;
padding-left: 550px;
}
.p3 {
position: absolute;
font-family: "Lato";
padding-left: 60px;
padding-top: 35px;
}
.p4 {
position: absolute;
font-family: "Lato";
padding-left: 230px;
padding-top: 35px;
}
.p5 {
position: absolute;
font-family: "Lato";
padding-left: 380px;
padding-top: 35px;
}
.p6 {
position: absolute;
font-family: "Lato";
padding-left: 60px;
padding-top: 390px;
}
.p7 {
position: absolute;
font-family: "Lato";
padding-left: 283px;
padding-top: 390px;
}
.p8 {
position: absolute;
font-family: "Lato";
padding-left: 553px;
padding-top: 35px;
}
.p9 {
position: absolute;
font-family: "Lato";
padding-left: 723px;
padding-top: 35px;
}
.p10 {
position: absolute;
font-family: "Lato";
padding-left: 896px;
padding-top: 35px;
}
.p11 {
position: absolute;
font-family: "Lato";
padding-left: 552px;
padding-top: 380px;
}
.p12 {
position: absolute;
font-family: "Lato";
padding-left: 810px;
padding-top: 380px;
}
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<title>TreeMap</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
</head>
<body>
<svg width="1200" height="720">
<g></g>
<section class="container1">
<p class="p1"> North England </p><p class="p2"> South England </p>
<p class="p3"> Bradford City </p><p class="p4"> Leeds </p>
<p class="p5"> Liverpool </p><p class="p6"> Manchester </p>
<p class="p7"> Sheffield </p><p class="p8"> Brighton </p>
<p class="p9"> Bristol </p><p class="p10"> Luton </p>
<p class="p11"> Milton Keynes </p><p class="p12"> Southampton </p>
<object class="Box" class="cancer"></object>
</section>
</svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<script>
var data = {
"name": "England",
"children": [
{
"name": "North England",
"children": [
{
"name": "Bradford City",
"children": [
{
"name": "Cancer",
"value": 1.18,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.21,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 2.57,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 11.92,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.18,
"color": "#CC527A",
}
]
},
{
"name": "Leeds",
"children": [
{
"name": "Cancer",
"value": 2.50,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.52,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 3.29,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 6.71,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.82,
"color": "#CC527A",
}
]
},
{
"name": "Liverpool",
"children": [
{
"name": "Cancer",
"value": 2.50,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 5.90,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 3.71,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 6.70,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.88,
"color": "#CC527A",
}
]
},
{
"name": "Manchester",
"children": [
{
"name": "Cancer",
"value": 1.78,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 2.95,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 2.61,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 7.05,
"color": "#474747",
},
{
"name": "Stroke",
"value": 2.13,
"color": "#CC527A",
}
]
},
{
"name": "Sheffield",
"children": [
{
"name": "Cancer",
"value": 2.54,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 4.57,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 3.85,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 7.08,
"color": "#474747",
},
{
"name": "Stroke",
"value": 2.13,
"color": "#CC527A",
}
]
},
]
},
{
"name": "South England",
"children": [
{
"name": "Brighton",
"children": [
{
"name": "Cancer",
"value": 1.18,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.21,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 2.57,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 11.92,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.18,
"color": "#CC527A",
}
]
},
{
"name": "Bristol",
"children": [
{
"name": "Cancer",
"value": 1.18,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.21,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 2.57,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 11.92,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.18,
"color": "#CC527A",
}
]
},
{
"name": "Luton",
"children": [
{
"name": "Cancer",
"value": 1.18,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.21,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 2.57,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 11.92,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.18,
"color": "#CC527A",
}
]
},
{
"name": "Milton Keynes",
"children": [
{
"name": "Cancer",
"value": 1.18,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.21,
"color":"#2F9599",
},
{
"name": "CHD",
"value": 2.57,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 11.92,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.18,
"color": "#CC527A",
}
]
},
{
"name": "Southampton",
"children": [
{
"name": "Cancer",
"value": 1.18,
"color": "#A8A7A7",
},
{
"name": "CKD",
"value": 3.21,
"color": "#2F9599",
},
{
"name": "CHD",
"value": 2.57,
"color": "#E8175D",
},
{
"name": "Diabetes",
"value": 11.92,
"color": "#474747",
},
{
"name": "Stroke",
"value": 1.18,
"color": "#CC527A",
}
]
},
]
}
]
};
var treemapLayout = d3.treemap()
.size([1000, 600])
.paddingTop(20)
.paddingInner(8);
var rootNode = d3.hierarchy(data)
rootNode.sum(function(d) {
return d.value;
});
treemapLayout(rootNode);
var nodes = d3.select('svg g')
.selectAll('g')
.data(rootNode.descendants())
.enter()
.append('g')
.attr('transform', function(d) {return 'translate(' + [d.x0, d.y0] + ')'})
nodes
.append('rect')
.attr('width', function(d) { return d.x1 - d.x0; })
.attr('height', function(d) { return d.y1 - d.y0; })
.attr('opacity', function(d) { return 0.8 /* has to be like d.value / max or so */ })
.attr('fill', function(d) { if (d.data.color) {
return d.data.color
} else {
return "white"
}})
nodes
.append('text')
.attr('dx', 10)
.attr('dy', 8)
.text(function(d) {
return d.data.value;
});
</script>
</body>
Upvotes: 1
Views: 200
Reputation: 8509
Normal way for d3 - it is a using ordinal color scale. You should associate names of disease with appropriate colors:
var namesOfDisease = ["Cancer", "CKD", "CHD", "Diabetes", "Stroke"];
var color = d3.scaleOrdinal()
.domain(namesOfDisease)
.range(["#A8A7A7", "#2F9599" , "#E8175D", "#474747", "#CC527A"]);
It returns appropriate color when you pass desease name as argument:
console.log(color("Cancer")) // ==> #A8A7A7
console.log(color("CHD")) // ==> #E8175D
console.log(color("Stroke")) // ==> #CC527A
And use this scale for color applying:
...
.attr('fill', function(d) {
var result = null;
if (namesOfDisease.indexOf(d.data.name) >= 0) {
result = color(d.data.name);
} else {
result = 'white'
}
return result;
})
...
Check demo without hardcoded colors in the hidden snippet:
var data = {
"name": "England",
"children": [
{
"name": "North England",
"children": [
{
"name": "Bradford City",
"children": [
{
"name": "Cancer",
"value": 1.18,
},
{
"name": "CKD",
"value": 3.21,
},
{
"name": "CHD",
"value": 2.57,
},
{
"name": "Diabetes",
"value": 11.92,
},
{
"name": "Stroke",
"value": 1.18,
}
]
},
{
"name": "Leeds",
"children": [
{
"name": "Cancer",
"value": 2.50,
},
{
"name": "CKD",
"value": 3.52,
},
{
"name": "CHD",
"value": 3.29,
},
{
"name": "Diabetes",
"value": 6.71,
},
{
"name": "Stroke",
"value": 1.82,
}
]
},
{
"name": "Liverpool",
"children": [
{
"name": "Cancer",
"value": 2.50,
},
{
"name": "CKD",
"value": 5.90,
},
{
"name": "CHD",
"value": 3.71,
},
{
"name": "Diabetes",
"value": 6.70,
},
{
"name": "Stroke",
"value": 1.88,
}
]
},
{
"name": "Manchester",
"children": [
{
"name": "Cancer",
"value": 1.78,
},
{
"name": "CKD",
"value": 2.95,
},
{
"name": "CHD",
"value": 2.61,
},
{
"name": "Diabetes",
"value": 7.05,
},
{
"name": "Stroke",
"value": 2.13,
}
]
},
{
"name": "Sheffield",
"children": [
{
"name": "Cancer",
"value": 2.54,
},
{
"name": "CKD",
"value": 4.57,
},
{
"name": "CHD",
"value": 3.85,
},
{
"name": "Diabetes",
"value": 7.08,
},
{
"name": "Stroke",
"value": 2.13,
}
]
},
]
},
{
"name": "South England",
"children": [
{
"name": "Brighton",
"children": [
{
"name": "Cancer",
"value": 1.18,
},
{
"name": "CKD",
"value": 3.21,
},
{
"name": "CHD",
"value": 2.57,
},
{
"name": "Diabetes",
"value": 11.92,
},
{
"name": "Stroke",
"value": 1.18,
}
]
},
{
"name": "Bristol",
"children": [
{
"name": "Cancer",
"value": 1.18,
},
{
"name": "CKD",
"value": 3.21,
},
{
"name": "CHD",
"value": 2.57,
},
{
"name": "Diabetes",
"value": 11.92,
},
{
"name": "Stroke",
"value": 1.18,
}
]
},
{
"name": "Luton",
"children": [
{
"name": "Cancer",
"value": 1.18,
},
{
"name": "CKD",
"value": 3.21,
},
{
"name": "CHD",
"value": 2.57,
},
{
"name": "Diabetes",
"value": 11.92,
},
{
"name": "Stroke",
"value": 1.18,
}
]
},
{
"name": "Milton Keynes",
"children": [
{
"name": "Cancer",
"value": 1.18,
},
{
"name": "CKD",
"value": 3.21,
},
{
"name": "CHD",
"value": 2.57,
},
{
"name": "Diabetes",
"value": 11.92,
},
{
"name": "Stroke",
"value": 1.18,
}
]
},
{
"name": "Southampton",
"children": [
{
"name": "Cancer",
"value": 1.18,
},
{
"name": "CKD",
"value": 3.21,
},
{
"name": "CHD",
"value": 2.57,
},
{
"name": "Diabetes",
"value": 11.92,
},
{
"name": "Stroke",
"value": 1.18,
}
]
},
]
}
]
};
var treemapLayout = d3.treemap()
.size([1000, 600])
.paddingTop(20)
.paddingInner(8);
var rootNode = d3.hierarchy(data)
rootNode.sum(function(d) {
return d.value;
});
treemapLayout(rootNode);
var namesOfDisease = ["Cancer", "CKD", "CHD", "Diabetes", "Stroke"];
var color = d3.scaleOrdinal()
.domain(namesOfDisease)
.range(["#A8A7A7", "#2F9599" , "#E8175D", "#474747", "#CC527A"]);
var nodes = d3.select('svg g')
.selectAll('g')
.data(rootNode.descendants())
.enter()
.append('g')
.attr('transform', function(d) {return 'translate(' + [d.x0, d.y0] + ')'})
nodes
.append('rect')
.attr('width', function(d) { return d.x1 - d.x0; })
.attr('height', function(d) { return d.y1 - d.y0; })
.attr('opacity', function(d) { return 0.8 /* has to be like d.value / max or so */ })
.attr('fill', function(d) {
var result = null;
if (namesOfDisease.indexOf(d.data.name) >= 0) {
result = color(d.data.name);
} else {
result = 'white'
}
return result;
})
nodes
.append('text')
.attr('dx', 10)
.attr('dy', 8)
.text(function(d) {
return d.data.value;
});
rect {
stroke: white;
}
text {
font-family: "Lato";
fill: white;
font-size: 8px;
text-anchor: middle;
}
svg {
padding-left: 60px;
padding-top:17px;
position: fixed;
}
p {
font-size: 14px;
}
.p1 {
position: absolute;
font-family: "Lato";
font-size: 17px;
padding-left: 60px;
}
.p2 {
position: absolute;
font-family: "Lato";
font-size: 17px;
padding-left: 550px;
}
.p3 {
position: absolute;
font-family: "Lato";
padding-left: 60px;
padding-top: 35px;
}
.p4 {
position: absolute;
font-family: "Lato";
padding-left: 230px;
padding-top: 35px;
}
.p5 {
position: absolute;
font-family: "Lato";
padding-left: 380px;
padding-top: 35px;
}
.p6 {
position: absolute;
font-family: "Lato";
padding-left: 60px;
padding-top: 390px;
}
.p7 {
position: absolute;
font-family: "Lato";
padding-left: 283px;
padding-top: 390px;
}
.p8 {
position: absolute;
font-family: "Lato";
padding-left: 553px;
padding-top: 35px;
}
.p9 {
position: absolute;
font-family: "Lato";
padding-left: 723px;
padding-top: 35px;
}
.p10 {
position: absolute;
font-family: "Lato";
padding-left: 896px;
padding-top: 35px;
}
.p11 {
position: absolute;
font-family: "Lato";
padding-left: 552px;
padding-top: 380px;
}
.p12 {
position: absolute;
font-family: "Lato";
padding-left: 810px;
padding-top: 380px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg width="1200" height="720">
<g></g>
<section class="container1">
<p class="p1"> North England </p><p class="p2"> South England </p>
<p class="p3"> Bradford City </p><p class="p4"> Leeds </p>
<p class="p5"> Liverpool </p><p class="p6"> Manchester </p>
<p class="p7"> Sheffield </p><p class="p8"> Brighton </p>
<p class="p9"> Bristol </p><p class="p10"> Luton </p>
<p class="p11"> Milton Keynes </p><p class="p12"> Southampton </p>
<object class="Box" class="cancer"></object>
</section>
</svg>
Upvotes: 1