Align text element to middle in treemap2019 Community Moderator ElectionGetting text area using getBBox()How do I detect a click outside an element?How do I check if an element is hidden in jQuery?How to align checkboxes and their labels consistently cross-browsersVertically align text next to an image?How do I give text or an image a transparent background using CSS?How to disable text selection highlighting?How to align a <div> to the middle (horizontally/width) of the pageHow do I remove a particular element from an array in JavaScript?jQuery scroll to elementHow do I vertically center text with CSS?
How do hiring committees for research positions view getting "scooped"?
World War I as a war of liberals against authoritarians?
Variable completely messes up echoed string
Recruiter wants very extensive technical details about all of my previous work
Optimising a list searching algorithm
Hausdorff dimension of the boundary of fibres of Lipschitz maps
Maths symbols and unicode-math input inside siunitx commands
Is it true that good novels will automatically sell themselves on Amazon (and so on) and there is no need for one to waste time promoting?
Fewest number of steps to reach 200 using special calculator
Geography in 3D perspective
What should I install to correct "ld: cannot find -lgbm and -linput" so that I can compile a Rust program?
Wrapping homogeneous Python objects
Do US professors/group leaders only get a salary, but no group budget?
PTIJ What is the inyan of the Konami code in Uncle Moishy's song?
Usage and meaning of "up" in "...worth at least a thousand pounds up in London"
Print last inputted byte
Have the tides ever turned twice on any open problem?
What are substitutions for coconut in curry?
What is the relationship between relativity and the Doppler effect?
Why is there so much iron?
Writing in a Christian voice
What does "Four-F." mean?
Are dual Irish/British citizens bound by the 90/180 day rule when travelling in the EU after Brexit?
Practical application of matrices and determinants
Align text element to middle in treemap
2019 Community Moderator ElectionGetting text area using getBBox()How do I detect a click outside an element?How do I check if an element is hidden in jQuery?How to align checkboxes and their labels consistently cross-browsersVertically align text next to an image?How do I give text or an image a transparent background using CSS?How to disable text selection highlighting?How to align a <div> to the middle (horizontally/width) of the pageHow do I remove a particular element from an array in JavaScript?jQuery scroll to elementHow do I vertically center text with CSS?
How I can set a text-align of text
element to the center of SVG g
element (parent box)?
like text-align: center
on html div element.
I try to build treemap by D3.js
JSFiddle Demo
Here is a code that I try :
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
//.style("text-anchor", "middle")
.attr("dy", "1.1em")
.attr("x", "5")
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
.attr("font-size", (d) => d.value)
.text(d => d);
Please view the sample code on JSFiddle
javascript css d3.js svg
add a comment |
How I can set a text-align of text
element to the center of SVG g
element (parent box)?
like text-align: center
on html div element.
I try to build treemap by D3.js
JSFiddle Demo
Here is a code that I try :
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
//.style("text-anchor", "middle")
.attr("dy", "1.1em")
.attr("x", "5")
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
.attr("font-size", (d) => d.value)
.text(d => d);
Please view the sample code on JSFiddle
javascript css d3.js svg
You can get the bounding box of the g element with element.getBBox() to get the center and then set the x attribute to the center with text-align: middle. See also related SO question stackoverflow.com/questions/13922862/…
– ee2Dev
Mar 6 at 23:20
1
@ee2DevgetBBox()
is a computer-intensive solution, which is not needed anyway because the treemap generator populates the boxes' values (x0
,x1
,y0
andy1
).
– Gerardo Furtado
Mar 6 at 23:30
add a comment |
How I can set a text-align of text
element to the center of SVG g
element (parent box)?
like text-align: center
on html div element.
I try to build treemap by D3.js
JSFiddle Demo
Here is a code that I try :
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
//.style("text-anchor", "middle")
.attr("dy", "1.1em")
.attr("x", "5")
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
.attr("font-size", (d) => d.value)
.text(d => d);
Please view the sample code on JSFiddle
javascript css d3.js svg
How I can set a text-align of text
element to the center of SVG g
element (parent box)?
like text-align: center
on html div element.
I try to build treemap by D3.js
JSFiddle Demo
Here is a code that I try :
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
//.style("text-anchor", "middle")
.attr("dy", "1.1em")
.attr("x", "5")
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
.attr("font-size", (d) => d.value)
.text(d => d);
Please view the sample code on JSFiddle
javascript css d3.js svg
javascript css d3.js svg
edited Mar 6 at 23:36
Gerardo Furtado
66.4k65293
66.4k65293
asked Mar 6 at 22:02
Arman FeyziArman Feyzi
384216
384216
You can get the bounding box of the g element with element.getBBox() to get the center and then set the x attribute to the center with text-align: middle. See also related SO question stackoverflow.com/questions/13922862/…
– ee2Dev
Mar 6 at 23:20
1
@ee2DevgetBBox()
is a computer-intensive solution, which is not needed anyway because the treemap generator populates the boxes' values (x0
,x1
,y0
andy1
).
– Gerardo Furtado
Mar 6 at 23:30
add a comment |
You can get the bounding box of the g element with element.getBBox() to get the center and then set the x attribute to the center with text-align: middle. See also related SO question stackoverflow.com/questions/13922862/…
– ee2Dev
Mar 6 at 23:20
1
@ee2DevgetBBox()
is a computer-intensive solution, which is not needed anyway because the treemap generator populates the boxes' values (x0
,x1
,y0
andy1
).
– Gerardo Furtado
Mar 6 at 23:30
You can get the bounding box of the g element with element.getBBox() to get the center and then set the x attribute to the center with text-align: middle. See also related SO question stackoverflow.com/questions/13922862/…
– ee2Dev
Mar 6 at 23:20
You can get the bounding box of the g element with element.getBBox() to get the center and then set the x attribute to the center with text-align: middle. See also related SO question stackoverflow.com/questions/13922862/…
– ee2Dev
Mar 6 at 23:20
1
1
@ee2Dev
getBBox()
is a computer-intensive solution, which is not needed anyway because the treemap generator populates the boxes' values (x0
, x1
, y0
and y1
).– Gerardo Furtado
Mar 6 at 23:30
@ee2Dev
getBBox()
is a computer-intensive solution, which is not needed anyway because the treemap generator populates the boxes' values (x0
, x1
, y0
and y1
).– Gerardo Furtado
Mar 6 at 23:30
add a comment |
1 Answer
1
active
oldest
votes
SVG elements have none of those HTML properties you're using in your code.
The simple solution here is setting the x
property to the middle of the rectangle, by using the x0
and x1
properties created by the treemap generator, combined with text-anchor: middle
. However, due to the strange data bound to the <tspan>
elements, we have to bend over backwards to get the datum from the parents:
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
);
Here is your code with that change only:
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
PS: I wrote "with that change only" because your code has several evident issues, such as assigning a width
and a margin
to a text element, which I left untouched.
It's work correctly for LTR languages but when change value ofname
child in JSON object to unicode character like Persian text also alignment is damaged!
– Arman Feyzi
Mar 7 at 8:16
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55032873%2falign-text-element-to-middle-in-treemap%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
SVG elements have none of those HTML properties you're using in your code.
The simple solution here is setting the x
property to the middle of the rectangle, by using the x0
and x1
properties created by the treemap generator, combined with text-anchor: middle
. However, due to the strange data bound to the <tspan>
elements, we have to bend over backwards to get the datum from the parents:
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
);
Here is your code with that change only:
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
PS: I wrote "with that change only" because your code has several evident issues, such as assigning a width
and a margin
to a text element, which I left untouched.
It's work correctly for LTR languages but when change value ofname
child in JSON object to unicode character like Persian text also alignment is damaged!
– Arman Feyzi
Mar 7 at 8:16
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
add a comment |
SVG elements have none of those HTML properties you're using in your code.
The simple solution here is setting the x
property to the middle of the rectangle, by using the x0
and x1
properties created by the treemap generator, combined with text-anchor: middle
. However, due to the strange data bound to the <tspan>
elements, we have to bend over backwards to get the datum from the parents:
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
);
Here is your code with that change only:
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
PS: I wrote "with that change only" because your code has several evident issues, such as assigning a width
and a margin
to a text element, which I left untouched.
It's work correctly for LTR languages but when change value ofname
child in JSON object to unicode character like Persian text also alignment is damaged!
– Arman Feyzi
Mar 7 at 8:16
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
add a comment |
SVG elements have none of those HTML properties you're using in your code.
The simple solution here is setting the x
property to the middle of the rectangle, by using the x0
and x1
properties created by the treemap generator, combined with text-anchor: middle
. However, due to the strange data bound to the <tspan>
elements, we have to bend over backwards to get the datum from the parents:
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
);
Here is your code with that change only:
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
PS: I wrote "with that change only" because your code has several evident issues, such as assigning a width
and a margin
to a text element, which I left untouched.
SVG elements have none of those HTML properties you're using in your code.
The simple solution here is setting the x
property to the middle of the rectangle, by using the x0
and x1
properties created by the treemap generator, combined with text-anchor: middle
. However, due to the strange data bound to the <tspan>
elements, we have to bend over backwards to get the datum from the parents:
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
);
Here is your code with that change only:
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
PS: I wrote "with that change only" because your code has several evident issues, such as assigning a width
and a margin
to a text element, which I left untouched.
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
let data =
"name": "topLevel element",
"children": [
"name": "group 1",
"children": [
"name": "first child",
"volume": 567.2,
"value": 1250,
"price": 1201,
"pc": 1
,
"name": "secondary",
"volume": 7809.1,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "another",
"volume": 2163.7,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "like svg",
"volume": 1756.5,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "abc",
"volume": 1201.7,
"value": 12450,
"price": 13201,
"pc": 5
]
,
"name": "Group 2",
"children": [
"name": "tripppp",
"volume": 2999.3,
"value": 12450,
"price": 13201,
"pc": 6
,
"name": "pardon",
"volume": 10398.3,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "world d3",
"volume": 10150.5,
"value": 12450,
"price": 13201,
"pc": 8
,
"name": "other bit",
"volume": 2652.6,
"value": 12450,
"price": 13201,
"pc": 7
,
"name": "rest train",
"volume": 2894,
"value": 12450,
"price": 13201,
"pc": 4
,
"name": "big data",
"volume": 6281.2,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "relase note",
"volume": 2431.3,
"value": 12450,
"price": 13201,
"pc": 3
,
"name": "seventeen",
"volume": 2373.5,
"value": 12450,
"price": 13201,
"pc": 2
,
"name": "fourth",
"volume": 1377.1,
"value": 12450,
"price": 13201,
"pc": 1
]
]
;
let chartDiv = document.getElementById("chart");
let svg = d3.select(chartDiv).append("svg");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
let chart = () =>
const root = treemap(filteredData);
const svg = d3.select("svg");
svg
.attr("width", width)
.attr("height", height)
.classed("svg-content-responsive", true)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 $width $height`);
const leaf = svg.selectAll("g")
.data(root.leaves())
.enter().append("g")
.attr("transform", d => `translate($d.x0,$d.y0)`);
leaf.append("title")
.text(d => `$d.ancestors().reverse().map(d => d.data.name).join("/")n$format(d.value)`);
leaf.append("rect")
.attr("fill", "green")
.attr("fill-opacity", 1.0)
// .attr("text-anchor", "start")
// .attr("dominant-baseline", "central")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("class", function(d)
return "node level-" + d.depth;
);
// .on("mouseover", (d) =>
// d3.select(this)
// .style("stroke", "yellow")
// .style("opacity", 1)
// );
// leaf.append("clipPath")
// .attr("id", d => (d.clipUid = ("#clip")).id)
// .append("use")
// .attr("xlink:href", d => d.leafUid.href);
leaf.append("text")
.attr("fill", "#fff")
//.style("text-anchor", "end")
// .attr("clip-path", d => d.clipUid)
.attr("text-anchor", "middle")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
// .attr("y", 0)
// .attr("x", 0)
// .attr("dy", 0)
.attr("font-size", d => Math.min(d.x1 - d.x0, d.y1 - d.y0) / 6)
.selectAll("tspan")
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.data.volume)).concat(format(d.data.pc)))
.enter().append("tspan")
// .style("width", d => d.x1 - d.x0)
// .style("height", d => d.y1 - d.y0)
// .attr("lengthAdjust" ,"spacingAndGlyphs")
// .attr("transform", "(250 250 250 250)")
//.style("text-anchor", "middle")
// .attr("dominant-baseline", "central")
.attr("dy", "1.1em")
.attr("x", function()
const parentData = d3.select(this.parentNode).datum();
return (parentData.x1 - parentData.x0) / 2;
)
// .attr("dx", 0)
// .attr("y", 18)
// .attr("y", (d, i, nodes) => `$(i === nodes.length ) * 1.3 + 1.2 + i * 1.9em`)
.attr("font-weight", (d, i, nodes) => i === nodes.length - 1 ? "200" : "700")
// .attr("font-family", "Vazir")
.attr("font-size", (d) => d.value)
.text(d => d);
return svg.node();
let filteredData = d3.hierarchy(data)
.sum(d => d.volume)
.sort((a, b) => b.height - a.height || b.value - a.value);
let treemap = d3.treemap()
.size([width, height])
.padding(1)
.paddingRight(3)
.round(true);
let format = d3.format(",d");
chart();
*
font-family: 'Vazir', sans-serif;
/* Make the chart container fill the page using CSS. */
#chart
background: #212121;
position: fixed;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
font-family: 'Vazir', sans-serif;
g text
text-shadow: 1px 2px 0 #555;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<link href="https://cdn.rawgit.com/rastikerdar/vazir-font/v19.2.0/dist/font-face.css" rel="stylesheet" type="text/css" />
<div id="chart"></div>
answered Mar 6 at 23:27
Gerardo FurtadoGerardo Furtado
66.4k65293
66.4k65293
It's work correctly for LTR languages but when change value ofname
child in JSON object to unicode character like Persian text also alignment is damaged!
– Arman Feyzi
Mar 7 at 8:16
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
add a comment |
It's work correctly for LTR languages but when change value ofname
child in JSON object to unicode character like Persian text also alignment is damaged!
– Arman Feyzi
Mar 7 at 8:16
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
It's work correctly for LTR languages but when change value of
name
child in JSON object to unicode character like Persian text also alignment is damaged!– Arman Feyzi
Mar 7 at 8:16
It's work correctly for LTR languages but when change value of
name
child in JSON object to unicode character like Persian text also alignment is damaged!– Arman Feyzi
Mar 7 at 8:16
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
I edit your code snippet for the show this problem. Thanks, @gerado-furtado and excuse me for my bad English writing
– Arman Feyzi
Mar 7 at 8:23
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
In fact, when the text is on the RTL, the written lines mingle with each other :/
– Arman Feyzi
Mar 7 at 8:26
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
@ArmanFeyzi That's a different problem. Therefore, please ask a new question, with the relevant details.
– Gerardo Furtado
Mar 7 at 9:17
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55032873%2falign-text-element-to-middle-in-treemap%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can get the bounding box of the g element with element.getBBox() to get the center and then set the x attribute to the center with text-align: middle. See also related SO question stackoverflow.com/questions/13922862/…
– ee2Dev
Mar 6 at 23:20
1
@ee2Dev
getBBox()
is a computer-intensive solution, which is not needed anyway because the treemap generator populates the boxes' values (x0
,x1
,y0
andy1
).– Gerardo Furtado
Mar 6 at 23:30