fix(VendorDataView): assign distinct color per market in all three charts

Each market line (DE/ES/FR/IT/UK) now renders with its own color across
Top Level BSR, Detail Level BSR, and Average Rating charts, along with
per-market legend entries. Removes hardcoded single-color approach.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Vidal Wolf
2026-03-04 09:06:05 +01:00
co-authored by Claude Sonnet 4.6
parent 1d0ea2f485
commit 07461031b8
+70 -56
View File
@@ -417,13 +417,20 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [], asinMetad
); );
} }
// Exact color values based on the screenshot
const cardBg = '#161b24'; const cardBg = '#161b24';
const orangeHex = '#f37526';
const cyanHex = '#2acbd6';
const purpleHex = '#7950f2';
const gridLineColor = '#ffffff'; const gridLineColor = '#ffffff';
// One distinct color per market
const MARKET_COLORS: Record<string, string> = {
'Amazon DE': '#f37526',
'Amazon ES': '#2acbd6',
'Amazon FR': '#7950f2',
'Amazon IT': '#10b981',
'Amazon UK': '#f59e0b',
};
const FALLBACK_COLORS = ['#f37526', '#2acbd6', '#7950f2', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6'];
const getMarketColor = (m: string, idx: number) => MARKET_COLORS[m] ?? FALLBACK_COLORS[idx % FALLBACK_COLORS.length];
return ( return (
<div className="p-4 md:p-6 lg:px-8 pb-24 max-w-[800px] mx-auto space-y-6"> <div className="p-4 md:p-6 lg:px-8 pb-24 max-w-[800px] mx-auto space-y-6">
@@ -499,32 +506,34 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [], asinMetad
labelStyle={{ color: '#9ca3af', fontSize: '11px', marginBottom: '4px' }} labelStyle={{ color: '#9ca3af', fontSize: '11px', marginBottom: '4px' }}
cursor={{ stroke: '#374151', strokeWidth: 1, strokeDasharray: '3 3' }} cursor={{ stroke: '#374151', strokeWidth: 1, strokeDasharray: '3 3' }}
/> />
{activeMarkets.map((m) => ( {activeMarkets.map((m, i) => {
<Area const color = getMarketColor(m, i);
key={m} return (
type="monotone" <Area
dataKey={`${m}_bsr`} key={m}
name={`${m} BSR`} type="monotone"
stroke={orangeHex} dataKey={`${m}_bsr`}
strokeWidth={2.5} name={`${m} BSR`}
fillOpacity={1} stroke={color}
fill="transparent" strokeWidth={2.5}
activeDot={{ r: 6, strokeWidth: 0, fill: orangeHex }} fillOpacity={1}
dot={{ r: 4, fill: cardBg, strokeWidth: 2, stroke: orangeHex }} fill="transparent"
/> activeDot={{ r: 6, strokeWidth: 0, fill: color }}
))} dot={{ r: 4, fill: cardBg, strokeWidth: 2, stroke: color }}
/>
);
})}
</AreaChart> </AreaChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
{/* Exact Legend matching screenshot */} <div className="mt-6 flex justify-center items-center gap-3 flex-wrap">
<div className="mt-6 flex justify-center items-center gap-2"> {activeMarkets.map((m, i) => (
{activeMarkets.length > 0 && ( <div key={m} className="flex items-center gap-2">
<div className="flex items-center gap-2"> <div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: getMarketColor(m, i) }}></div>
<div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: orangeHex }}></div> <span className="text-[12px] text-[#8b9bb4]">{m} BSR</span>
<span className="text-[12px] text-[#8b9bb4]">{activeMarkets[0]} BSR</span>
</div> </div>
)} ))}
</div> </div>
</div> </div>
@@ -568,30 +577,34 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [], asinMetad
labelStyle={{ color: '#9ca3af', fontSize: '11px', marginBottom: '4px' }} labelStyle={{ color: '#9ca3af', fontSize: '11px', marginBottom: '4px' }}
cursor={{ stroke: '#374151', strokeWidth: 1, strokeDasharray: '3 3' }} cursor={{ stroke: '#374151', strokeWidth: 1, strokeDasharray: '3 3' }}
/> />
{activeMarkets.map((m) => ( {activeMarkets.map((m, i) => {
<Area const color = getMarketColor(m, i);
key={m} return (
type="monotone" <Area
dataKey={`${m}_bsr`} key={m}
name="Category Rank" type="monotone"
stroke={cyanHex} dataKey={`${m}_bsr`}
strokeWidth={2.5} name={`${m} Rank`}
fillOpacity={1} stroke={color}
fill="transparent" strokeWidth={2.5}
activeDot={{ r: 6, strokeWidth: 0, fill: cyanHex }} fillOpacity={1}
dot={{ r: 4, fill: cardBg, strokeWidth: 2, stroke: cyanHex }} fill="transparent"
/> activeDot={{ r: 6, strokeWidth: 0, fill: color }}
))} dot={{ r: 4, fill: cardBg, strokeWidth: 2, stroke: color }}
/>
);
})}
</AreaChart> </AreaChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
{/* Exact Legend matching screenshot */} <div className="mt-6 flex justify-center items-center gap-3 flex-wrap">
<div className="mt-6 flex justify-center items-center gap-2"> {activeMarkets.map((m, i) => (
<div className="flex items-center gap-2"> <div key={m} className="flex items-center gap-2">
<div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: cyanHex }}></div> <div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: getMarketColor(m, i) }}></div>
<span className="text-[12px] text-[#8b9bb4]">Category Rank</span> <span className="text-[12px] text-[#8b9bb4]">{m} Rank</span>
</div> </div>
))}
</div> </div>
</div> </div>
@@ -626,30 +639,31 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [], asinMetad
labelStyle={{ color: '#9ca3af', fontSize: '11px', marginBottom: '4px' }} labelStyle={{ color: '#9ca3af', fontSize: '11px', marginBottom: '4px' }}
cursor={{ stroke: '#374151', strokeWidth: 1, strokeDasharray: '3 3' }} cursor={{ stroke: '#374151', strokeWidth: 1, strokeDasharray: '3 3' }}
/> />
{activeMarkets.map((m) => ( {activeMarkets.map((m, i) => (
<Area <Area
key={m} key={m}
type="monotone" type="monotone"
dataKey={`${m}_rating`} dataKey={`${m}_rating`}
name="Star Rating" name={m}
stroke={purpleHex} stroke={getMarketColor(m, i)}
strokeWidth={2.5} strokeWidth={2.5}
fillOpacity={1} fillOpacity={1}
fill="transparent" fill="transparent"
activeDot={{ r: 6, strokeWidth: 0, fill: purpleHex }} activeDot={{ r: 6, strokeWidth: 0, fill: getMarketColor(m, i) }}
dot={{ r: 4, fill: cardBg, strokeWidth: 2, stroke: purpleHex }} dot={{ r: 4, fill: cardBg, strokeWidth: 2, stroke: getMarketColor(m, i) }}
/> />
))} ))}
</AreaChart> </AreaChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
{/* Exact Legend matching screenshot */} <div className="mt-6 flex justify-center items-center gap-3 flex-wrap">
<div className="mt-6 flex justify-center items-center gap-2"> {activeMarkets.map((m, i) => (
<div className="flex items-center gap-2"> <div key={m} className="flex items-center gap-2">
<div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: purpleHex }}></div> <div className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: getMarketColor(m, i) }}></div>
<span className="text-[12px] text-[#8b9bb4]">Star Rating</span> <span className="text-[12px] text-[#8b9bb4]">{m} Rating</span>
</div> </div>
))}
</div> </div>
</div> </div>