Legend pointStyle: 'line' does not apply dataset borderDash pattern
- 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.