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?










1















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










share|improve this question
























  • 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 and y1).

    – Gerardo Furtado
    Mar 6 at 23:30
















1















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










share|improve this question
























  • 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 and y1).

    – Gerardo Furtado
    Mar 6 at 23:30














1












1








1








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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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





    @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


















  • 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 and y1).

    – 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













1 Answer
1






active

oldest

votes


















3














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.






share|improve this answer























  • 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











  • 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










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
);



);













draft saved

draft discarded


















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









3














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.






share|improve this answer























  • 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











  • 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















3














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.






share|improve this answer























  • 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











  • 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













3












3








3







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.






share|improve this answer













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>






share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 6 at 23:27









Gerardo FurtadoGerardo Furtado

66.4k65293




66.4k65293












  • 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











  • 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











  • 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



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

1928 у кіно

Захаров Федір Захарович

Ель Греко