Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,9 @@ describe('AreaSeries', () => {
{ x: 3, y: 10 },
{ x: 4, y: 20 },
],
highlight: {
drawingMode: 'cutout',
},
series: [
{
type: 'area',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1347,11 +1347,10 @@ export class AreaSeries extends CartesianSeries<AreaSeriesTypes> {
const drawingMode = this.getDrawingMode(isHighlight, opts.drawingMode);

datumSelection.each((node, datum) => {
const style =
datum.style ??
contextNodeData.styles[this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
const state = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
const style = datum.style ?? contextNodeData.styles[state];
this.applyMarkerStyle(style, node, datum.point, fillBBox, { selected: datum.selected });
node.drawingMode = drawingMode;
node.drawingMode = this.resolveMarkerDrawingModeForState(drawingMode, style);
});

if (!isHighlight) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -949,11 +949,8 @@ export class BubbleSeries extends CartesianSeries<BubbleSeriesTypes> {
area,
dilation,
} = datum;
let style =
datum.style ??
contextNodeData.styles[this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];

style = { ...style };
const state = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
const style = { ...(datum.style ?? contextNodeData.styles[state]) };
style.size = size;

if (dilation > 1) {
Expand All @@ -970,7 +967,7 @@ export class BubbleSeries extends CartesianSeries<BubbleSeriesTypes> {
}

this.applyMarkerStyle(style, node, datum.point, fillBBox, { selected: datum.selected });
node.drawingMode = drawingMode;
node.drawingMode = this.resolveMarkerDrawingModeForState(drawingMode, style);
node.zIndex = aggregated ? [-count, index] : 0;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,9 @@ describe('LineSeries', () => {
{ x: 3, y: 10 },
{ x: 4, y: 20 },
],
highlight: {
drawingMode: 'cutout',
},
series: [
{
type: 'line',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ export class LineSeries extends CartesianSeries<LineSeriesTypes> {
applyTranslation,
selected: datum.selected,
});
node.drawingMode = drawingMode;
node.drawingMode = this.resolveMarkerDrawingModeForState(drawingMode, style);
});

if (!isHighlight) {
Expand Down
8 changes: 6 additions & 2 deletions packages/ag-charts-community/src/chart/series/series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ import type {
SeriesNodeEventTypes,
} from './seriesTypes';
import { type ShapeFillBBox } from './shapeUtil';
import { hasDimmedOpacity } from './util';
import { hasDimmedOpacity, resolveMarkerDrawingMode } from './util';

export interface SeriesDataEvent {
readonly dataModel: DataModel<any, any, any>;
Expand Down Expand Up @@ -500,7 +500,7 @@ export abstract class Series<
if (isHighlight) {
return highlightDrawingMode;
}
return this.hasHighlightOpacity() ? 'cutout' : 'overlay';
return this.hasHighlightOpacity() ? this.ctx.chartService.highlight?.drawingMode ?? 'overlay' : 'overlay';
}

readonly events = new EventEmitter<{ 'data-update': SeriesDataEvent; 'data-processed': SeriesDataEvent }>();
Expand Down Expand Up @@ -801,6 +801,10 @@ export abstract class Series<
return this.properties.highlight.getStyle(highlightState);
}

protected resolveMarkerDrawingModeForState(drawingMode: AgDrawingMode, style?: AgSeriesMarkerStyle): AgDrawingMode {
return resolveMarkerDrawingMode(drawingMode, style);
}

protected abstract hasItemStylers(): boolean;
public filterItemStylerFillParams(fill: AgColorType | undefined): InternalAgColorType | undefined {
if (isGradientFill(fill)) {
Expand Down
52 changes: 24 additions & 28 deletions packages/ag-charts-community/src/chart/series/seriesProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ export const highlightStates = [
HighlightState.OtherItem,
];

export type HighlightStyleOptionKey =
| 'highlightedItem'
| 'unhighlightedItem'
| 'highlightedSeries'
| 'unhighlightedSeries';

export function getHighlightStyleOptionKeys(highlightState: HighlightState): HighlightStyleOptionKey[] {
switch (highlightState) {
case HighlightState.Item:
return ['highlightedItem', 'highlightedSeries'];
case HighlightState.OtherItem:
return ['unhighlightedItem', 'highlightedSeries'];
case HighlightState.Series:
return ['highlightedSeries'];
case HighlightState.OtherSeries:
return ['unhighlightedSeries'];
case HighlightState.None:
return [];
}
}

type HighlightMixins = {
fill: AgColorType;
fillOpacity: number;
Expand Down Expand Up @@ -117,35 +138,10 @@ export class HighlightProperties<TOpts extends object> extends BaseProperties {
@Property
readonly unhighlightedSeries: HighlightOptions<TOpts> = {};

private getItemHighlightStyle(highlightState: HighlightState): HighlightOptions<TOpts> | undefined {
switch (highlightState) {
case HighlightState.Item:
return this.highlightedItem;
case HighlightState.OtherItem:
return this.unhighlightedItem;
case HighlightState.Series:
return this.highlightedSeries;
case HighlightState.OtherSeries:
return this.unhighlightedSeries;
}
}

private getSeriesHighlightStyle(highlightState: HighlightState): HighlightOptions<TOpts> | undefined {
switch (highlightState) {
case HighlightState.Item:
case HighlightState.OtherItem:
case HighlightState.Series:
return this.highlightedSeries;
case HighlightState.OtherSeries:
return this.unhighlightedSeries;
}
}

getStyle(highlightState: HighlightState): HighlightOptions<TOpts> {
return mergeDefaults<HighlightOptions<TOpts>>(
this.getItemHighlightStyle(highlightState),
this.getSeriesHighlightStyle(highlightState)
);
const keys = getHighlightStyleOptionKeys(highlightState);
if (keys.length === 0) return {};
return mergeDefaults<HighlightOptions<TOpts>>(...keys.map((key) => this[key]));
}
}

Expand Down
37 changes: 35 additions & 2 deletions packages/ag-charts-community/src/chart/series/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type BoxBounds, findMaxIndex, findMinIndex } from 'ag-charts-core';
import type { AgActiveItemState } from 'ag-charts-types';
import { type BoxBounds, Color, findMaxIndex, findMinIndex, isString } from 'ag-charts-core';
import type { AgActiveItemState, AgDrawingMode } from 'ag-charts-types';

import { Transformable } from '../../scene/transformable';
import { type HighlightState, highlightStates } from './seriesProperties';
Expand Down Expand Up @@ -180,6 +180,39 @@ export function hasDimmedOpacity(style?: { opacity?: number; fillOpacity?: numbe
return (style?.opacity ?? 1) < 1 || (style?.fillOpacity ?? 1) < 1 || (style?.strokeOpacity ?? 1) < 1;
}

const opaqueMarkerFillCache = new Map<string, boolean>();

export function isOpaqueMarkerFillStyle(style?: { fill?: unknown; fillOpacity?: number; opacity?: number }): boolean {
if (style == null) return false;

const fill = style.fill;
if (!isString(fill)) return false;

const fillString = fill.trim();
const fillLower = fillString.toLowerCase();
if (fillLower === 'transparent' || fillLower === 'none') return false;

let cached = opaqueMarkerFillCache.get(fillString);
if (cached == null) {
try {
cached = Color.fromString(fillString).a === 1;
} catch {
cached = false;
}
opaqueMarkerFillCache.set(fillString, cached);
}

return cached;
}

export function resolveMarkerDrawingMode(
baseDrawingMode: AgDrawingMode,
style?: { fill?: unknown; fillOpacity?: number; opacity?: number }
): AgDrawingMode {
if (baseDrawingMode !== 'cutout') return baseDrawingMode;
return isOpaqueMarkerFillStyle(style) ? 'cutout' : 'overlay';
}

export function findNodeDatumInArray<D extends SeriesNodeDatum<DatumIndexType>>(
itemIdOrIndex: AgActiveItemState['itemId'],
nodeData: D[] | undefined
Expand Down
46 changes: 46 additions & 0 deletions packages/ag-charts-community/src/chart/themes/chartTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,34 @@ const PRESET_OVERRIDES_TYPES: Record<keyof AgPresetOverrides, true> = {
'linear-gauge': true,
};

function hasUserOptionLessThan1(key: string) {
return {
$some: [
{
$and: [
{
$or: [
{ $isSeriesType: 'line' },
{ $isSeriesType: 'scatter' },
{ $isSeriesType: 'area' },
{ $isSeriesType: 'radar' },
{ $isSeriesType: 'rangeArea' },
],
},
{
$isUserOption: [
`/series/$index/${key}`,
{ $lessThan: [{ $path: `/series/$index/${key}` }, 1] },
false,
],
},
],
},
{ $path: '/series' },
],
};
}

function isPresetOverridesType(type: OverridesKey): type is keyof AgPresetOverrides {
return PRESET_OVERRIDES_TYPES[type as keyof AgPresetOverrides] === true;
}
Expand Down Expand Up @@ -374,6 +402,24 @@ export class ChartTheme {
layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE,
textAlign: DEFAULT_CAPTION_ALIGNMENT,
},
highlight: {
drawingMode: {
$if: [
{
$or: [
hasUserOptionLessThan1('highlight/highlightedItem/opacity'),
hasUserOptionLessThan1('highlight/unhighlightedItem/opacity'),
hasUserOptionLessThan1('highlight/highlightedSeries/opacity'),
hasUserOptionLessThan1('highlight/unhighlightedSeries/opacity'),
hasUserOptionLessThan1('fillOpacity'),
hasUserOptionLessThan1('marker/fillOpacity'),
],
},
'overlap',
'cutout',
],
},
},
tooltip: {
enabled: true,
darkTheme: IS_DARK_THEME,
Expand Down
Loading
Loading