chartjs / chartjs/Chart.js

Legend pointStyle: 'line' does not apply dataset borderDash pattern

Open
#12,291 0 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
JavaScript
Stars
67.7k
Forks
11.9k
Avg merge
7h 39m
Merged PRs (30d)
5

Description

### Expected behavior

When using usePointStyle: true with pointStyle: 'line' in legend labels, the legend line segment should render with the same borderDash pattern as the dataset it represents (e.g., dashed lines should appear dashed in the legend).

### Current behavior

The legend renders a solid line segment regardless of the dataset's borderDash setting. Only the color and width are inherited — the dash pattern is ignored.

### Reproducible sample

Inline code sample provided below (no external link needed).

### Optional extra steps/info to reproduce

**Steps to Reproduce**
```
const options = {
plugins: {
legend: {
labels: {
usePointStyle: true,
pointStyle: 'line',
pointStyleWidth: 40,
},
},
},
};

const data = {
datasets: [
{
label: 'Solid Line',
borderColor: '#1a5276',
borderWidth: 2,
// no borderDash — should render solid in legend ✓
},
{
label: 'Dashed Line',
borderColor: '#e74c3c',
borderWidth: 2,
borderDash: [6, 3],
// should render dashed in legend ✗ (renders solid)
},
],
};
```

### Possible solution

The fix would be to pass lineDash into drawPointLegend (via the options parameter) and apply it before stroking:

```
// In drawPointLegend, before the switch statement:
if (options.lineDash) {
ctx.setLineDash(options.lineDash);
} else {
ctx.setLineDash([]);
}

// ... existing switch/case logic ...

// After ctx.stroke():
ctx.setLineDash([]); // reset
```

The drawOptions object constructed in the legend plugin's draw method (where drawPointLegend is called) would need to include the lineDash property from the legend item:

```
// In the legend plugin draw method, where drawOptions is constructed:
const drawOptions = {
radius: boxHeight * Math.SQRT2 / 2,
pointStyle: legendItem.pointStyle,
rotation: legendItem.rotation,
borderWidth: lineWidth,
lineDash: legendItem.lineDash || [], // ← add this
lineDashOffset: legendItem.lineDashOffset || 0, // ← and this
};

```
This ensures the dash context is explicitly set within drawPointLegend rather than relying on it being set in the parent scope and surviving through the beginPath() call.

### Context

**RCA**
In the legend rendering code, ctx.setLineDash(valueOrDefault(legendItem.lineDash, [])) is called before the if (labelOpts.usePointStyle) branch. However, drawPointLegend() (in helpers.dataset.js) for case 'line' calls ctx.beginPath() then
ctx.moveTo/lineTo and relies on the parent ctx.stroke(). The lineDash context IS set, but it appears not to be applied to the point-style rendering path.

When usePointStyle: false (box rendering), dashes render correctly on the legend box — confirming legendItem.lineDash is populated. It's only the drawPointLegend path that doesn't produce dashed output.

### chart.js version

v4.5.1

### Browser name and version

Chrome (all browsers affected - it's a canvas rendering path issue)

### Link to your project

Can't share but the framework is Angular 21 via ng2-charts (not framework specific)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.