Correct wordwrapping
This commit is contained in:
parent
cfb07ce1c0
commit
b7791e4612
137
app.js
137
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
|
// Convert the map to an array structure for ECharts
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
@ -134,11 +137,14 @@ function transformToSunburst(data) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get subcategories and sort by value
|
||||||
const subcategories = [];
|
const subcategories = [];
|
||||||
for (const subcatKey in category.children) {
|
for (const subcatKey in category.children) {
|
||||||
subcategories.push(category.children[subcatKey]);
|
subcategories.push(category.children[subcatKey]);
|
||||||
}
|
}
|
||||||
|
subcategories.sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
|
// Process each subcategory
|
||||||
subcategories.forEach(subcategory => {
|
subcategories.forEach(subcategory => {
|
||||||
const subcategoryNode = {
|
const subcategoryNode = {
|
||||||
name: subcategory.name,
|
name: subcategory.name,
|
||||||
@ -149,11 +155,14 @@ function transformToSunburst(data) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get microcategories and sort by value
|
||||||
const microcategories = [];
|
const microcategories = [];
|
||||||
for (const microKey in subcategory.children) {
|
for (const microKey in subcategory.children) {
|
||||||
microcategories.push(subcategory.children[microKey]);
|
microcategories.push(subcategory.children[microKey]);
|
||||||
}
|
}
|
||||||
|
microcategories.sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
|
// Add microcategories to subcategory
|
||||||
microcategories.forEach(micro => {
|
microcategories.forEach(micro => {
|
||||||
subcategoryNode.children.push({
|
subcategoryNode.children.push({
|
||||||
name: micro.name,
|
name: micro.name,
|
||||||
@ -202,14 +211,12 @@ function renderChart(data) {
|
|||||||
center: ['40%', '50%'], // Move chart to the left
|
center: ['40%', '50%'], // Move chart to the left
|
||||||
nodeClick: 'rootToNode', // To enable drill down on click
|
nodeClick: 'rootToNode', // To enable drill down on click
|
||||||
data: sunburstData.data,
|
data: sunburstData.data,
|
||||||
|
sort: null, // Use 'null' to maintain the sorting we did in the data transformation
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
formatter: function(param) {
|
formatter: function(param) {
|
||||||
if (param.depth === 0) {
|
if (param.depth === 0) {
|
||||||
// Add line breaks for long category names
|
// No word wrapping for top-level categories
|
||||||
if (param.name.length > 10) {
|
|
||||||
return param.name.replace(/(.{1,10})(?: |$)/g, "$1\n").trim();
|
|
||||||
}
|
|
||||||
return param.name;
|
return param.name;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
@ -237,11 +244,14 @@ function renderChart(data) {
|
|||||||
lineHeight: 15,
|
lineHeight: 15,
|
||||||
verticalAlign: 'center',
|
verticalAlign: 'center',
|
||||||
position: 'inside',
|
position: 'inside',
|
||||||
|
formatter: function(param) {
|
||||||
|
// No special formatting for level 1
|
||||||
|
return param.name;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
borderWidth: 2
|
borderWidth: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Second level - Subcategories
|
// Second level - Subcategories
|
||||||
@ -253,7 +263,61 @@ function renderChart(data) {
|
|||||||
align: 'left',
|
align: 'left',
|
||||||
position: 'inside',
|
position: 'inside',
|
||||||
distance: 5,
|
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: {
|
itemStyle: {
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
@ -276,9 +340,58 @@ function renderChart(data) {
|
|||||||
silent: false,
|
silent: false,
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
formatter: function(param) {
|
formatter: function(param) {
|
||||||
if (param.name.length > 10) {
|
// If there's only one word, never wrap it
|
||||||
return param.name.slice(0, 8) + '...';
|
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;
|
return param.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -292,8 +405,6 @@ function renderChart(data) {
|
|||||||
},
|
},
|
||||||
// Add more space between wedges
|
// Add more space between wedges
|
||||||
gap: 2,
|
gap: 2,
|
||||||
// Allow the chart to sort segments by value
|
|
||||||
sort: null,
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
formatter: function(info) {
|
formatter: function(info) {
|
||||||
@ -365,6 +476,9 @@ function renderChart(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (targetData && targetData.children && targetData.children.length > 0) {
|
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
|
// Recolor children with unique colors
|
||||||
targetData.children.forEach((child, i) => {
|
targetData.children.forEach((child, i) => {
|
||||||
const color = colorPalette[i % colorPalette.length];
|
const color = colorPalette[i % colorPalette.length];
|
||||||
@ -374,6 +488,9 @@ function renderChart(data) {
|
|||||||
|
|
||||||
// If the child has children (microcategories), color them too
|
// If the child has children (microcategories), color them too
|
||||||
if (child.children && child.children.length > 0) {
|
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);
|
const microColors = generateColorGradient(color, child.children.length);
|
||||||
child.children.forEach((micro, j) => {
|
child.children.forEach((micro, j) => {
|
||||||
micro.itemStyle = {
|
micro.itemStyle = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user