Skip to content

Conversation

@GordonSmith
Copy link
Member

@GordonSmith GordonSmith commented Oct 23, 2025

Checklist:

  • The commit message is properly formatted and free of typos.
    • The commit message title makes sense in a changelog, by itself.
    • The commit message includes a "fixes" reference if appropriate.
    • The commit is signed.
  • The change has been fully tested:
    • I have viewed all related gallery items
    • I have viewed all related dermatology items
  • There are no similar instances of the same problem that should be addressed
    • I have addressed them here
    • I have raised new issues to address them separately

Testing:

@GordonSmith GordonSmith requested a review from Copilot October 23, 2025 12:55
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds keyboard navigation functionality to Column and Pie chart components, enabling users to navigate and interact with chart elements using the Tab key and Space/Enter keys for selection. The changes also update repository references from "trunk" to "main" branch across multiple package.json files.

Key changes:

  • Adds keyboard navigation support with Tab, Space, and Enter keys for Column and Pie charts
  • Implements ARIA attributes and focus states for improved accessibility
  • Updates CSS styling for hover, focus, and selection states with visual feedback
  • Updates homepage URLs from "trunk" to "main" branch in package.json files

Reviewed Changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/util/package.json Updated homepage URL from trunk to main branch
packages/observablehq-compiler/package.json Updated homepage URL from trunk to main branch
packages/markdown-it-plugins/package.json Updated homepage URL from trunk to main branch (with typo)
packages/dataflow/package.json Updated homepage URL from trunk to main branch
packages/chart/src/Pie.ts Added keyboard navigation, ARIA attributes, and slice padding functionality to Pie chart
packages/chart/src/Pie.css Added CSS for focus states, hover effects, and keyboard navigation styling
packages/chart/src/Column.ts Added keyboard navigation, ARIA attributes, and Tabster integration to Column chart
packages/chart/src/Column.css Updated CSS for selected state, added focus and hover styles
packages/chart/index.html Added demo controls for testing keyboard navigation on both chart types

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

"url": "https://github.com/hpcc-systems/Visualization/issues"
},
"homepage": "https://github.com/hpcc-systems/Visualization/tree/trunk/packages/markdonw-it-plugins"
"homepage": "https://github.com/hpcc-systems/Visualization/tree/main/packages/markdonw-it-plugins"
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'markdonw' to 'markdown' in the homepage URL path.

Suggested change
"homepage": "https://github.com/hpcc-systems/Visualization/tree/main/packages/markdonw-it-plugins"
"homepage": "https://github.com/hpcc-systems/Visualization/tree/main/packages/markdown-it-plugins"

Copilot uses AI. Check for mistakes.
this._totalValue = this.calcTotalValue();
const innerRadius = this.calcInnerRadius();
const outerRadius = this.calcOuterRadius();
const innerRadius = Math.max(this.calcInnerRadius(), Math.min(outerRadius / 30, 6));
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic numbers 30 and 6 should be defined as named constants to clarify their purpose (e.g., MIN_INNER_RADIUS_RATIO = 30, MIN_INNER_RADIUS_PIXELS = 6).

Copilot uses AI. Check for mistakes.
const paddingValue = this.slicePadding();

// Use a small pad angle for visual separation
const padAngleRadians = paddingValue > 0 ? Math.min(paddingValue, 0.05) : 0;
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 0.05 should be defined as a named constant (e.g., MAX_PAD_ANGLE = 0.05) to clarify the maximum allowed pad angle.

Copilot uses AI. Check for mistakes.
.domain(context.layerColumns(host).filter(function (_d, idx) { return idx > 0; }))
.rangeRound(isHorizontal ? [0, dataLen] : [dataLen, 0])
.paddingInner(this.xAxisSeriesPaddingInner())
.paddingInner(Math.max(this.xAxisSeriesPaddingInner(), 0.05))
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 0.05 should be defined as a named constant (e.g., MIN_SERIES_PADDING = 0.05) to clarify the minimum padding value.

Copilot uses AI. Check for mistakes.
@GordonSmith GordonSmith force-pushed the main branch 3 times, most recently from ac285a3 to 136469b Compare October 29, 2025 15:37
@GordonSmith GordonSmith requested a review from Copilot November 26, 2025 14:00
@GordonSmith GordonSmith marked this pull request as ready for review November 26, 2025 14:05
Copilot finished reviewing on behalf of GordonSmith November 26, 2025 14:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 24 comments.

Comments suppressed due to low confidence (2)

packages/common/src/TitleBar.ts:36

  • The button element (anchor tag) should have role="button" and tabindex="0" attributes for proper accessibility. While anchor tags are naturally focusable, explicitly setting these attributes ensures correct ARIA semantics when the element behaves as a button rather than a link.
        this._i = this._element
            .attr("href", "#")
            .on("click", function () {
                context.click();
                d3Event.preventDefault();
            })
            .on("keydown", function (this: HTMLElement) {
                if (d3Event.key === " " || d3Event.key === "Spacebar" || d3Event.code === "Space") {
                    this.click();
                    d3Event.preventDefault();
                }
            })
            .on("mousemove", this.mouseMove)
            .on("mouseout", this.mouseOut)
            .append("i")
            ;

packages/graph/tests/test6.ts:75

  • Unused variable g.
        const g = genData2();

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.


constructor() {
super();
const g = genData2();
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable g is assigned but never used. It appears to be dead code that should be removed.

Suggested change
const g = genData2();

Copilot uses AI. Check for mistakes.
Comment on lines +58 to 110
.common_IconBar {
display: flex;
flex-flow: row;
justify-content: space-between;
}

.common_IconBar .icon-bar {
display: flex;
opacity: 0.95;
flex-wrap: nowrap;
margin: 0px;
white-space: nowrap;
line-height: 28px;
z-index: 1;
}

.common_IconBar .icon-bar a {
position: relative;
z-index: 0;
text-align: center;
padding-top: 4px;
padding-left: 2px;
padding-right: 2px;
padding-bottom: 4px;
transition: all 0.3s ease;
color: darkgray;
}

.common_IconBar .icon-bar a:focus,
.common_IconBar .icon-bar a:focus-visible {
outline: 2px solid #0078d4;
outline-offset: 2px;
z-index: 2;
}

.common_IconBar .icon-bar a.disabled {
opacity: 0.3;
pointer-events: none;
color: darkgray;
}

.common_IconBar .icon-bar a:hover {
background-color: whitesmoke;
}

.common_IconBar .icon-bar a {
background-color: white;
}

.common_IconBar .icon-bar a.selected {
background-color: #efe5e5;
}

Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This CSS block is completely duplicated from lines 1-56. The entire section from .common_IconBar through .common_IconBar .icon-bar a.selected is repeated. This duplication should be removed to improve maintainability and reduce file size.

Suggested change
.common_IconBar {
display: flex;
flex-flow: row;
justify-content: space-between;
}
.common_IconBar .icon-bar {
display: flex;
opacity: 0.95;
flex-wrap: nowrap;
margin: 0px;
white-space: nowrap;
line-height: 28px;
z-index: 1;
}
.common_IconBar .icon-bar a {
position: relative;
z-index: 0;
text-align: center;
padding-top: 4px;
padding-left: 2px;
padding-right: 2px;
padding-bottom: 4px;
transition: all 0.3s ease;
color: darkgray;
}
.common_IconBar .icon-bar a:focus,
.common_IconBar .icon-bar a:focus-visible {
outline: 2px solid #0078d4;
outline-offset: 2px;
z-index: 2;
}
.common_IconBar .icon-bar a.disabled {
opacity: 0.3;
pointer-events: none;
color: darkgray;
}
.common_IconBar .icon-bar a:hover {
background-color: whitesmoke;
}
.common_IconBar .icon-bar a {
background-color: white;
}
.common_IconBar .icon-bar a.selected {
background-color: #efe5e5;
}

Copilot uses AI. Check for mistakes.
import { format as d3Format } from "d3-format";
import { scaleBand as d3ScaleBand } from "d3-scale";
import { local as d3Local, select as d3Select } from "d3-selection";
// import { createTabster, getGroupper, getTabster, type Types as TabsterTypes } from "tabster";
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commented import for tabster should be removed if it's not being used. Leaving commented-out imports reduces code clarity.

Suggested change
// import { createTabster, getGroupper, getTabster, type Types as TabsterTypes } from "tabster";

Copilot uses AI. Check for mistakes.
private textLocal = d3Local<Text>();
private stackedTextLocal = d3Local<Text>();
private isHorizontal: boolean;
// protected _tabster: TabsterTypes.TabsterCore | null = null;
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commented-out protected property for tabster should be removed if it's not being used. Leaving commented-out code reduces maintainability.

Suggested change
// protected _tabster: TabsterTypes.TabsterCore | null = null;

Copilot uses AI. Check for mistakes.
columnGEnter.merge(columnGRect as any)
.attr("tabindex", context.tabNavigation() ? 0 : undefined) // Tabster Groupper manages these inner focusables
.attr("role", context.tabNavigation() ? "button" : undefined) // ARIA role for accessibility
.attr("aria-label", context.tabNavigation() ? (d: any) => `${d.column}: ${d.value instanceof Array ? d.value[1] - d.value[0] : d.value}` : undefined) // ARIA label for screen readers
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aria-label for column data should include the category/label from the domain (d.origRow[0]) to provide better context. For example: ${d.origRow[0]} - ${d.column}: ${...} would be more descriptive than just the column name and value.

Suggested change
.attr("aria-label", context.tabNavigation() ? (d: any) => `${d.column}: ${d.value instanceof Array ? d.value[1] - d.value[0] : d.value}` : undefined) // ARIA label for screen readers
.attr("aria-label", context.tabNavigation() ? (d: any) => `${d.origRow[0]} - ${d.column}: ${d.value instanceof Array ? d.value[1] - d.value[0] : d.value}` : undefined) // ARIA label for screen readers

Copilot uses AI. Check for mistakes.

this.d3Pie
.padAngle(0.0025)
.padAngle(0) // No geometric padding - CSS-only solution
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line sets padAngle to 0, but in the update method (lines 206-209, 215), the padAngle is calculated from slicePadding() and applied to d3Arc. There's a conflict: d3Pie.padAngle(0) here will be overridden by the calculated padAngle in the arc generator. Either remove this line or reconcile the padding logic between the pie generator and arc generator. The comment "No geometric padding - CSS-only solution" appears outdated given the new slicePadding implementation.

Copilot uses AI. Check for mistakes.

<script type="module">
import { Area, Column } from "@hpcc-js/chart";
import { Area, Bar, Column, Pie } from "./src/index.ts";
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused imports Area, Bar, Pie.

Suggested change
import { Area, Bar, Column, Pie } from "./src/index.ts";
import { Column } from "./src/index.ts";

Copilot uses AI. Check for mistakes.
</script>

<script type="module">
import { Area, Column, Pie } from "./src/index.ts";
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused imports Area, Column.

Suggested change
import { Area, Column, Pie } from "./src/index.ts";
import { Pie } from "./src/index.ts";

Copilot uses AI. Check for mistakes.
@@ -1,5 +1,5 @@
import { INDChart, ITooltip } from "@hpcc-js/api";
import { InputField } from "@hpcc-js/common";
import { d3Event, InputField, SVGWidget } from "@hpcc-js/common";
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import SVGWidget.

Suggested change
import { d3Event, InputField, SVGWidget } from "@hpcc-js/common";
import { d3Event, InputField } from "@hpcc-js/common";

Copilot uses AI. Check for mistakes.
.text("Hello World")
.render()
;
const iconBar = new IconBar()
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable iconBar.

Suggested change
const iconBar = new IconBar()
new IconBar()

Copilot uses AI. Check for mistakes.
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant