Browse Source

Fix colors of charts for light color scheme

pull/7975/head
Thomas Kaul 2 weeks ago
parent
commit
59aca4dbd7
  1. 8
      apps/client/src/app/app.component.ts
  2. 7
      apps/client/src/app/components/admin-market-data/asset-profile-dialog-host/asset-profile-dialog-host.component.ts
  3. 2
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/interfaces/interfaces.ts
  4. 22
      apps/client/src/app/components/investment-chart/investment-chart.component.ts
  5. 14
      libs/common/src/lib/chart-helper.ts
  6. 33
      libs/common/src/lib/helper.spec.ts
  7. 20
      libs/common/src/lib/helper.ts
  8. 2
      libs/ui/src/lib/chart/chart.options.ts
  9. 8
      libs/ui/src/lib/line-chart/line-chart.component.ts
  10. 6
      libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts

8
apps/client/src/app/app.component.ts

@ -1,4 +1,4 @@
import { getCssVariable } from '@ghostfolio/common/helper';
import { getCssVariable, isDarkColorScheme } from '@ghostfolio/common/helper';
import {
AssetProfileIdentifier,
InfoItem,
@ -260,11 +260,7 @@ export class GfAppComponent implements OnInit {
}
private initializeTheme(userPreferredColorScheme?: ColorScheme) {
const isDarkTheme = userPreferredColorScheme
? userPreferredColorScheme === 'DARK'
: window.matchMedia('(prefers-color-scheme: dark)').matches;
this.toggleTheme(isDarkTheme);
this.toggleTheme(isDarkColorScheme(userPreferredColorScheme));
// Default chart styles
Chart.defaults.font.family = getCssVariable('--font-family-sans-serif');

7
apps/client/src/app/components/admin-market-data/asset-profile-dialog-host/asset-profile-dialog-host.component.ts

@ -1,8 +1,5 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
DEFAULT_COLOR_SCHEME,
DEFAULT_LOCALE
} from '@ghostfolio/common/config';
import { DEFAULT_LOCALE } from '@ghostfolio/common/config';
import { AssetProfileIdentifier, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { DataSource } from '@ghostfolio/prisma/enums';
@ -150,7 +147,7 @@ export class GfAssetProfileDialogHostComponent implements OnDestroy, OnInit {
data: {
dataSource,
symbol,
colorScheme: user?.settings.colorScheme ?? DEFAULT_COLOR_SCHEME,
colorScheme: user?.settings?.colorScheme,
deviceType: this.deviceType(),
locale: user?.settings?.locale ?? DEFAULT_LOCALE
} satisfies AssetProfileDialogParams,

2
apps/client/src/app/components/admin-market-data/asset-profile-dialog/interfaces/interfaces.ts

@ -2,7 +2,7 @@ import { ColorScheme } from '@ghostfolio/common/types';
import { DataSource } from '@ghostfolio/prisma/enums';
export interface AssetProfileDialogParams {
colorScheme: ColorScheme;
colorScheme?: ColorScheme;
dataSource: DataSource;
deviceType: string;
locale: string;

22
apps/client/src/app/components/investment-chart/investment-chart.component.ts

@ -7,11 +7,7 @@ import {
getZeroLineAnnotation,
transformTickToAbbreviation
} from '@ghostfolio/common/chart-helper';
import {
DEFAULT_COLOR_SCHEME,
primaryColorRgb,
secondaryColorRgb
} from '@ghostfolio/common/config';
import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config';
import { getLocale, parseDate } from '@ghostfolio/common/helper';
import { LineChartItem } from '@ghostfolio/common/interfaces';
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
@ -174,15 +170,13 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy {
this.chart.update();
} else {
const colorScheme = this.colorScheme ?? DEFAULT_COLOR_SCHEME;
this.chart = new Chart<'bar' | 'line'>(
this.chartCanvas().nativeElement,
{
data: chartData,
options: {
animation: false,
elements: getChartElementsOptions(colorScheme),
elements: getChartElementsOptions(this.colorScheme),
interaction: { intersect: false, mode: 'index' },
maintainAspectRatio: true,
plugins: {
@ -210,7 +204,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy {
value: this.savingsRate
}
: undefined,
yAxis: getZeroLineAnnotation(colorScheme)
yAxis: getZeroLineAnnotation(this.colorScheme)
}
},
legend: {
@ -218,18 +212,18 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy {
},
tooltip: this.getTooltipPluginConfiguration(),
verticalHoverLine: {
color: getChartBorderColor(colorScheme)
color: getChartBorderColor(this.colorScheme)
}
},
responsive: true,
scales: {
x: getTimeAxisOptions({
colorScheme,
borderWidth: this.groupBy ? 0 : 1,
colorScheme: this.colorScheme,
locale: this.locale
}),
y: getValueAxisOptions({
colorScheme,
colorScheme: this.colorScheme,
display: !this.isInPercentage,
tickCallback: (tickValue) => {
return transformTickToAbbreviation(Number(tickValue));
@ -238,7 +232,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy {
}
},
plugins: [
getVerticalHoverLinePlugin(this.chartCanvas(), colorScheme)
getVerticalHoverLinePlugin(this.chartCanvas(), this.colorScheme)
],
type: this.groupBy ? 'bar' : 'line'
}
@ -251,7 +245,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy {
TooltipOptions<'bar' | 'line'>
> {
return getTimeSeriesTooltipOptions<'bar' | 'line'>({
colorScheme: this.colorScheme ?? DEFAULT_COLOR_SCHEME,
colorScheme: this.colorScheme,
currency: this.isInPercentage ? undefined : this.currency,
groupBy: this.groupBy,
locale: this.isInPercentage ? undefined : this.locale,

14
libs/common/src/lib/chart-helper.ts

@ -41,12 +41,12 @@ export function formatGroupedDate({
return format(date, DATE_FORMAT);
}
export function getChartBorderColor(colorScheme: ColorScheme) {
export function getChartBorderColor(colorScheme?: ColorScheme) {
return `rgba(${getTextColor(colorScheme)}, 0.1)`;
}
export function getChartElementsOptions(
colorScheme: ColorScheme
colorScheme?: ColorScheme
): ChartOptions<'bar' | 'line'>['elements'] {
return {
line: {
@ -67,7 +67,7 @@ export function getTimeAxisOptions({
locale = getLocale()
}: {
borderWidth?: number;
colorScheme: ColorScheme;
colorScheme?: ColorScheme;
display?: boolean;
locale?: string;
}): ScaleOptions<'time'> {
@ -95,7 +95,7 @@ export function getTooltipOptions<T extends ChartType>({
locale = getLocale(),
unit = ''
}: {
colorScheme: ColorScheme;
colorScheme?: ColorScheme;
currency?: string;
groupBy?: GroupBy;
locale?: string;
@ -174,7 +174,7 @@ export function getValueAxisOptions({
highlightedValues = [],
tickCallback
}: {
colorScheme: ColorScheme;
colorScheme?: ColorScheme;
display?: boolean;
highlightedValues?: number[];
tickCallback: (
@ -214,7 +214,7 @@ export function getValueAxisOptions({
export function getVerticalHoverLinePlugin<T extends 'line' | 'bar'>(
chartCanvas: ElementRef<HTMLCanvasElement>,
colorScheme: ColorScheme
colorScheme?: ColorScheme
): Plugin<T, { color: string; width: number }> {
return {
afterDatasetsDraw: (chart, _, options) => {
@ -249,7 +249,7 @@ export function getVerticalHoverLinePlugin<T extends 'line' | 'bar'>(
}
export function getZeroLineAnnotation(
colorScheme: ColorScheme
colorScheme?: ColorScheme
): AnnotationOptions<'line'> {
return {
borderColor: getChartBorderColor(colorScheme),

33
libs/common/src/lib/helper.spec.ts

@ -13,6 +13,7 @@ import {
isAccountExcluded,
isCurrency,
isCurrencySymbol,
isDarkColorScheme,
isSplitRatio,
isValidCurrencyCode,
isValidCustomAssetProfileSymbol,
@ -348,6 +349,38 @@ describe('Helper', () => {
});
});
describe('Is dark color scheme', () => {
const mockPrefersColorSchemeDark = (matches: boolean) => {
window.matchMedia = jest.fn(() => {
return { matches } as MediaQueryList;
});
};
afterEach(() => {
Reflect.deleteProperty(window, 'matchMedia');
});
it('Dark color scheme with operating system in light mode', () => {
mockPrefersColorSchemeDark(false);
expect(isDarkColorScheme('DARK')).toEqual(true);
});
it('Light color scheme with operating system in dark mode', () => {
mockPrefersColorSchemeDark(true);
expect(isDarkColorScheme('LIGHT')).toEqual(false);
});
it('Auto color scheme with operating system in dark mode', () => {
mockPrefersColorSchemeDark(true);
expect(isDarkColorScheme()).toEqual(true);
});
it('Auto color scheme with operating system in light mode', () => {
mockPrefersColorSchemeDark(false);
expect(isDarkColorScheme()).toEqual(false);
});
});
describe('Is split ratio', () => {
it('Forward split', () => {
expect(isSplitRatio({ denominator: 1, numerator: 2 })).toEqual(true);

20
libs/common/src/lib/helper.ts

@ -345,12 +345,9 @@ export function getAssetProfileIdentifier({
return `${dataSource}-${symbol}`;
}
export function getBackgroundColor(aColorScheme: ColorScheme) {
export function getBackgroundColor(aColorScheme?: ColorScheme) {
return getCssVariable(
aColorScheme === 'DARK' ||
window.matchMedia('(prefers-color-scheme: dark)').matches
? '--dark-background'
: '--light-background'
isDarkColorScheme(aColorScheme) ? '--dark-background' : '--light-background'
);
}
@ -531,10 +528,9 @@ export function getSum(aArray: Big[]) {
return new Big(0);
}
export function getTextColor(aColorScheme: ColorScheme) {
export function getTextColor(aColorScheme?: ColorScheme) {
const cssVariable = getCssVariable(
aColorScheme === 'DARK' ||
window.matchMedia('(prefers-color-scheme: dark)').matches
isDarkColorScheme(aColorScheme)
? '--light-primary-text'
: '--dark-primary-text'
);
@ -612,6 +608,14 @@ export function isCurrencySymbol(aSymbol: string) {
);
}
export function isDarkColorScheme(aColorScheme?: ColorScheme) {
if (aColorScheme) {
return aColorScheme === 'DARK';
}
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
export function isDerivedCurrency(aCurrency: string) {
if (aCurrency === 'USX') {
return true;

2
libs/ui/src/lib/chart/chart.options.ts

@ -12,7 +12,7 @@ export function getTimeSeriesTooltipOptions<T extends 'bar' | 'line'>({
locale,
unit
}: {
colorScheme: ColorScheme;
colorScheme?: ColorScheme;
currency?: string;
groupBy?: GroupBy;
locale?: string;

8
libs/ui/src/lib/line-chart/line-chart.component.ts

@ -4,11 +4,7 @@ import {
getValueAxisOptions,
getVerticalHoverLinePlugin
} from '@ghostfolio/common/chart-helper';
import {
DEFAULT_COLOR_SCHEME,
primaryColorRgb,
secondaryColorRgb
} from '@ghostfolio/common/config';
import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config';
import { getBackgroundColor, getLocale } from '@ghostfolio/common/helper';
import { LineChartItem } from '@ghostfolio/common/interfaces';
import { ColorScheme } from '@ghostfolio/common/types';
@ -56,7 +52,7 @@ export class GfLineChartComponent
{
@Input() benchmarkDataItems: LineChartItem[] = [];
@Input() benchmarkLabel = '';
@Input() colorScheme: ColorScheme = DEFAULT_COLOR_SCHEME;
@Input() colorScheme?: ColorScheme;
@Input() currency: string;
@Input() historicalDataItems: LineChartItem[];
@Input() isAnimated = false;

6
libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts

@ -1,5 +1,5 @@
import { getTooltipOptions } from '@ghostfolio/common/chart-helper';
import { DEFAULT_COLOR_SCHEME, UNKNOWN_KEY } from '@ghostfolio/common/config';
import { UNKNOWN_KEY } from '@ghostfolio/common/config';
import { getLocale, getSum, getTextColor } from '@ghostfolio/common/helper';
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import { ColorScheme } from '@ghostfolio/common/types';
@ -124,7 +124,7 @@ export class GfPortfolioProportionChartComponent
};
} = {};
const textColor = getTextColor(this.colorScheme ?? DEFAULT_COLOR_SCHEME);
const textColor = getTextColor(this.colorScheme);
this.colorMap = {
[this.OTHER_KEY]: `rgba(${textColor}, 0.24)`,
@ -448,7 +448,7 @@ export class GfPortfolioProportionChartComponent
): Partial<TooltipOptions<'doughnut'>> {
return {
...getTooltipOptions({
colorScheme: this.colorScheme ?? DEFAULT_COLOR_SCHEME,
colorScheme: this.colorScheme,
currency: this.baseCurrency,
locale: this.locale
}),

Loading…
Cancel
Save