基于每日数据的Highcharts堆叠柱状图日期分组异常问题
Fixing X-Axis Grouping & Stacking for Highcharts Column Chart
Let's break down why your stacked column chart isn't grouping dates correctly, and walk through actionable fixes step by step.
Core Issues in Your Current Implementation
- Duplicate X-Axis Categories: You're pushing every individual entry's date into
brandsValue.x, creating duplicates (e.g.,2019-06-10appears twice). Highcharts requires unique, sorted categories for proper stacking behavior. - Mismatched Series Data: Your series data isn't aligned with X-axis categories. Each series needs a value for every category (even
0if there's no data for that date), otherwise stacking will break. - Incorrect Configuration: Your
series: { stacking: 'true' }uses a string instead of a booleantrue, and thegroupingproperty was misplaced in thexAxisconfig instead ofplotOptions.column.
Step-by-Step Fix
1. Rewrite Data Processing Logic
Update your data handling to ensure unique dates and aligned series data:
const brandsValue = { x: [], y: [] }; const colorIndex = 0; // Step 1: Preprocess data - normalize brands, calculate finalCost, parse dates const processedData = _.chain(data) .map(brand => ({ ...brand, day: brand.date, brand: _.capitalize(brand.brand.toLowerCase()), finalCost: values.mediaTypeSelected === 'posts' ? 100 * parseFloat(brand.ER) : 0, dateObj: new Date(brand.date) })) .value(); // Step 2: Get unique, sorted dates for X-axis categories const uniqueDates = _.chain(processedData) .map(item => item.day) .uniq() .sortBy(date => new Date(date)) .value(); brandsValue.x = uniqueDates; // Step 3: Group by brand and build category-aligned series data _.chain(processedData) .groupBy('brand') .forEach((items, brandName) => { // Create a date-to-value map for quick lookup const dateValueMap = _.keyBy(items, 'day'); // Build data array that matches the order of uniqueDates const seriesData = uniqueDates.map(date => { const item = dateValueMap[date]; return item ? parseInt(item.finalCost) : 0; // Use 0 if no data for the date }); brandsValue.y.push({ name: brandName, color: "#cccccc", // You can cycle through custom colors here if needed data: seriesData }); }) .value();
2. Correct Highcharts Configuration
Adjust your chart options to fix stacking and grouping settings:
const brandsValueChartOptions = { chart: { type: 'column' }, credits: { enabled: false }, xAxis: { title: { text: 'Date' }, categories: brandsValue.x, labels: { formatter: function() { return moment(this.value).format('Do MMM'); } }, crosshair: true }, yAxis: { min: 0, title: { text: 'Value (in USD)' } }, tooltip: { headerFormat: '<span style="font-size:10px">{point.key}</span>', // Optional: Add custom tooltip to show profile ID formatter: function() { const matchingItem = processedData.find(d => d.brand === this.series.name && d.day === this.x ); return `${this.series.name}: ${this.y} USD<br>Profile ID: ${matchingItem?.profileId || 'N/A'}`; } }, plotOptions: { column: { pointPadding: 0.2, borderWidth: 0, stacking: 'normal', grouping: true // Grouping belongs here, not in xAxis config } }, series: brandsValue.y // Use the aligned series data we built };
Key Explanations
- Unique Categories: Extracting and sorting unique dates ensures the X-axis has one entry per date, which is mandatory for consistent stacking.
- Aligned Series Data: Each series now has a value for every date in the categories array. Using
0for missing data keeps the alignment intact. - Proper Configuration: Moving
groupingtoplotOptions.columnand using a booleantruefor stacking ensures Highcharts applies stacking correctly across matching date categories.
With these changes, your sample data will stack both Pepsi entries under the 10th Jun column as expected.
内容的提问来源于stack exchange,提问作者M1M6
相关产品推荐
相关产品推荐

