Correct wordwrapping
This commit is contained in:
parent
cfb07ce1c0
commit
b7791e4612
135
app.js
135
app.js
@ -119,6 +119,9 @@ function transformToSunburst(data) {
|
||||
}
|
||||
});
|
||||
|
||||
// Sort categories by value (largest to smallest)
|
||||
categories.sort((a, b) => b.value - a.value);
|
||||
|
||||
// Convert the map to an array structure for ECharts
|
||||
const result = [];
|
||||
|
||||
@ -134,11 +137,14 @@ function transformToSunburst(data) {
|
||||
}
|
||||
};
|
||||
|
||||
// Get subcategories and sort by value
|
||||
const subcategories = [];
|
||||
for (const subcatKey in category.children) {
|
||||
subcategories.push(category.children[subcatKey]);
|
||||
}
|
||||
subcategories.sort((a, b) => b.value - a.value);
|
||||
|
||||
// Process each subcategory
|
||||
subcategories.forEach(subcategory => {
|
||||
const subcategoryNode = {
|
||||
name: subcategory.name,
|
||||
@ -149,11 +155,14 @@ function transformToSunburst(data) {
|
||||
}
|
||||
};
|
||||
|
||||
// Get microcategories and sort by value
|
||||
const microcategories = [];
|
||||
for (const microKey in subcategory.children) {
|
||||
microcategories.push(subcategory.children[microKey]);
|
||||
}
|
||||
microcategories.sort((a, b) => b.value - a.value);
|
||||
|
||||
// Add microcategories to subcategory
|
||||
microcategories.forEach(micro => {
|
||||
subcategoryNode.children.push({
|
||||
name: micro.name,
|
||||
@ -202,14 +211,12 @@ function renderChart(data) {
|
||||
center: ['40%', '50%'], // Move chart to the left
|
||||
nodeClick: 'rootToNode', // To enable drill down on click
|
||||
data: sunburstData.data,
|
||||
sort: null, // Use 'null' to maintain the sorting we did in the data transformation
|
||||
label: {
|
||||
show: true,
|
||||
formatter: function(param) {
|
||||
if (param.depth === 0) {
|
||||
// Add line breaks for long category names
|
||||
if (param.name.length > 10) {
|
||||
return param.name.replace(/(.{1,10})(?: |$)/g, "$1\n").trim();
|
||||
}
|
||||
// No word wrapping for top-level categories
|
||||
return param.name;
|
||||
} else {
|
||||
return '';
|
||||
@ -237,11 +244,14 @@ function renderChart(data) {
|
||||
lineHeight: 15,
|
||||
verticalAlign: 'center',
|
||||
position: 'inside',
|
||||
formatter: function(param) {
|
||||
// No special formatting for level 1
|
||||
return param.name;
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 2
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
// Second level - Subcategories
|
||||
@ -253,7 +263,61 @@ function renderChart(data) {
|
||||
align: 'left',
|
||||
position: 'inside',
|
||||
distance: 5,
|
||||
formatter: function(param) {
|
||||
// If there's only one word, never wrap it
|
||||
if (!param.name.includes(' ')) {
|
||||
return param.name;
|
||||
}
|
||||
|
||||
// If the text contains spaces, consider word wrapping for better visibility
|
||||
const words = param.name.split(' ');
|
||||
|
||||
// Skip wrapping for single words or very small sectors
|
||||
// Estimate sector size from value percentage
|
||||
if (words.length === 1 || param.percent < 0.03) {
|
||||
return param.name;
|
||||
}
|
||||
|
||||
// Process words to keep short prepositions (< 4 chars) with the next word
|
||||
const processedWords = [];
|
||||
let i = 0;
|
||||
while (i < words.length) {
|
||||
if (i < words.length - 1 && words[i].length < 4) {
|
||||
// Combine short word with the next word
|
||||
processedWords.push(words[i] + ' ' + words[i+1]);
|
||||
i += 2;
|
||||
} else {
|
||||
processedWords.push(words[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip wrapping if we're down to just one processed word
|
||||
if (processedWords.length === 1) {
|
||||
return processedWords[0];
|
||||
}
|
||||
|
||||
// If only 2 processed words, put one on each line
|
||||
if (processedWords.length == 2) {
|
||||
return processedWords[0] + '\n' + processedWords[1];
|
||||
}
|
||||
// If 3 processed words, put each word on its own line
|
||||
else if (processedWords.length == 3) {
|
||||
return processedWords[0] + '\n' + processedWords[1] + '\n' + processedWords[2];
|
||||
}
|
||||
// For more words, split more aggressively
|
||||
else if (processedWords.length > 3) {
|
||||
// Try to create 3 relatively even lines
|
||||
const part1 = Math.floor(processedWords.length / 3);
|
||||
const part2 = Math.floor(processedWords.length * 2 / 3);
|
||||
|
||||
return processedWords.slice(0, part1).join(' ') + '\n' +
|
||||
processedWords.slice(part1, part2).join(' ') + '\n' +
|
||||
processedWords.slice(part2).join(' ');
|
||||
}
|
||||
|
||||
return param.name;
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 1
|
||||
@ -276,9 +340,58 @@ function renderChart(data) {
|
||||
silent: false,
|
||||
fontSize: 10,
|
||||
formatter: function(param) {
|
||||
if (param.name.length > 10) {
|
||||
return param.name.slice(0, 8) + '...';
|
||||
// If there's only one word, never wrap it
|
||||
if (!param.name.includes(' ')) {
|
||||
return param.name;
|
||||
}
|
||||
|
||||
// If the text contains spaces, consider word wrapping for better visibility
|
||||
const words = param.name.split(' ');
|
||||
|
||||
// Skip wrapping for single words or very small sectors
|
||||
// Estimate sector size from value percentage
|
||||
if (words.length === 1 || param.percent < 0.02) {
|
||||
return param.name;
|
||||
}
|
||||
|
||||
// Process words to keep short prepositions (< 4 chars) with the next word
|
||||
const processedWords = [];
|
||||
let i = 0;
|
||||
while (i < words.length) {
|
||||
if (i < words.length - 1 && words[i].length < 4) {
|
||||
// Combine short word with the next word
|
||||
processedWords.push(words[i] + ' ' + words[i+1]);
|
||||
i += 2;
|
||||
} else {
|
||||
processedWords.push(words[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip wrapping if we're down to just one processed word
|
||||
if (processedWords.length === 1) {
|
||||
return processedWords[0];
|
||||
}
|
||||
|
||||
// If only 2 processed words, put one on each line
|
||||
if (processedWords.length == 2) {
|
||||
return processedWords[0] + '\n' + processedWords[1];
|
||||
}
|
||||
// If 3 processed words, put each word on its own line
|
||||
else if (processedWords.length == 3) {
|
||||
return processedWords[0] + '\n' + processedWords[1] + '\n' + processedWords[2];
|
||||
}
|
||||
// For more words, split more aggressively
|
||||
else if (processedWords.length > 3) {
|
||||
// Try to create 3 relatively even lines
|
||||
const part1 = Math.floor(processedWords.length / 3);
|
||||
const part2 = Math.floor(processedWords.length * 2 / 3);
|
||||
|
||||
return processedWords.slice(0, part1).join(' ') + '\n' +
|
||||
processedWords.slice(part1, part2).join(' ') + '\n' +
|
||||
processedWords.slice(part2).join(' ');
|
||||
}
|
||||
|
||||
return param.name;
|
||||
}
|
||||
},
|
||||
@ -292,8 +405,6 @@ function renderChart(data) {
|
||||
},
|
||||
// Add more space between wedges
|
||||
gap: 2,
|
||||
// Allow the chart to sort segments by value
|
||||
sort: null,
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: function(info) {
|
||||
@ -365,6 +476,9 @@ function renderChart(data) {
|
||||
}
|
||||
|
||||
if (targetData && targetData.children && targetData.children.length > 0) {
|
||||
// Sort children by value before recoloring
|
||||
targetData.children.sort((a, b) => b.value - a.value);
|
||||
|
||||
// Recolor children with unique colors
|
||||
targetData.children.forEach((child, i) => {
|
||||
const color = colorPalette[i % colorPalette.length];
|
||||
@ -374,6 +488,9 @@ function renderChart(data) {
|
||||
|
||||
// If the child has children (microcategories), color them too
|
||||
if (child.children && child.children.length > 0) {
|
||||
// Sort microcategories by value
|
||||
child.children.sort((a, b) => b.value - a.value);
|
||||
|
||||
const microColors = generateColorGradient(color, child.children.length);
|
||||
child.children.forEach((micro, j) => {
|
||||
micro.itemStyle = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user