Skip to content

Commit

Permalink
Merge pull request #2398 from concord-consortium/188127118-bar-graph-…
Browse files Browse the repository at this point in the history
…link

bar graph link
  • Loading branch information
bgoldowsky committed Sep 17, 2024
2 parents 812c3c4 + de397eb commit 7a65c8c
Show file tree
Hide file tree
Showing 30 changed files with 1,382 additions and 425 deletions.
329 changes: 306 additions & 23 deletions cypress/e2e/functional/tile_tests/bar_graph_tile_spec.js

Large diffs are not rendered by default.

30 changes: 6 additions & 24 deletions cypress/e2e/functional/tile_tests/xy_plot_tool_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,6 @@ const queryParamsPlotVariables = `${Cypress.config("qaNoGroupShareUnitStudent5")

const problemDoc = '1.1 Unit Toolbar Configuration';

// Construct and fill in a table tile with the given data (a list of lists)
function buildTable(data) {
// at least two cols, or as many as the longest row in the data array
const cols = Math.max(2, ...data.map(row => row.length));
clueCanvas.addTile('table');
tableToolTile.getTableTile().last().should('be.visible');
tableToolTile.getTableTile().last().within((tile) => {
// tile will start with two columns; make more if desired
for (let i=2; i<cols; i++) {
tile.getAddColumnButton().click();
}
for (let i=0; i<data.length; i++) {
for (let j=0; j<data[i].length; j++) {
const cellContent = data[i][j];
tableToolTile.typeInTableCellXY(i, j, cellContent);
tableToolTile.getTableCellXY(i, j).should('contain', cellContent);
}
}
});
}

// Parse `transform` attributes (used for point positioning)
function xAttributeOfTransform(matcher) {
return attributeOfTransform(matcher, 1);
Expand Down Expand Up @@ -256,7 +235,8 @@ context('XYPlot Tool Tile', function () {
beforeTest(queryParamsMultiDataset);
cy.collapseResourceTabs();

buildTable([[1, 2], [2, 4], [3, 9], [4, 16]]);
clueCanvas.addTile("table");
tableToolTile.fillTable(tableToolTile.getTableTile(), [[1, 2], [2, 4], [3, 9], [4, 16]]);

clueCanvas.addTile("graph");
xyTile.getTile().should("have.length", 1).should('be.visible');
Expand Down Expand Up @@ -432,8 +412,10 @@ context('XYPlot Tool Tile', function () {
clueCanvas.addTile("graph");
xyTile.getTile().should('be.visible');

buildTable([[1, 2], [2, 4], [3, 9]]);
buildTable([[1, 1], [2, 5], [3, 1], [4, 5]]);
clueCanvas.addTile("table");
tableToolTile.fillTable(tableToolTile.getTableTile().last(), [[1, 2], [2, 4], [3, 9]]);
clueCanvas.addTile("table");
tableToolTile.fillTable(tableToolTile.getTableTile().last(), [[1, 1], [2, 5], [3, 1], [4, 5]]);

tableToolTile.getTableTile().should('have.length', 2);

Expand Down
5 changes: 5 additions & 0 deletions cypress/support/elements/common/cCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ExpressionToolTile from '../tile/ExpressionToolTile';
import Canvas from './Canvas';
import Dialog from './Dialog';
import XYPlotToolTile from '../tile/XYPlotToolTile';
import BarGraphTile from '../tile/BarGraphTile';

let graphToolTile = new GeometryToolTile,
imageToolTile = new ImageToolTile,
Expand All @@ -23,6 +24,7 @@ let graphToolTile = new GeometryToolTile,
numberlineToolTile = new NumberlineToolTile,
expressionToolTile = new ExpressionToolTile,
xyPlotToolTile = new XYPlotToolTile,
barGraphTile = new BarGraphTile,
canvas = new Canvas,
dialog = new Dialog;

Expand Down Expand Up @@ -295,6 +297,9 @@ class ClueCanvas {
case 'xyplot':
tileElement = xyPlotToolTile.getTile().last().click({ force: true });
break;
case 'bargraph':
tileElement = barGraphTile.getTile().last().click({ force: true });
break;
}
tileElement.should('have.class','selected');
}
Expand Down
74 changes: 57 additions & 17 deletions cypress/support/elements/tile/BarGraphTile.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,79 @@
class BarGraphTile {

getTiles(workspaceClass) {
return cy.get(`${workspaceClass || ".primary-workspace"} .canvas-area .bar-graph-tile`);
return cy.get(`${workspaceClass || ".primary-workspace"} .canvas .bar-graph-tile`);
}

getTile(tileIndex = 0, workspaceClass) {
return this.getTiles().eq(tileIndex);
getTile(workspaceClass, tileIndex = 0) {
return this.getTiles(workspaceClass).eq(tileIndex);
}

getTileTitle(tileIndex = 0, workspaceClass) {
return this.getTile(tileIndex, workspaceClass).find(`.editable-tile-title-text`);
getTileTitle(workspaceClass, tileIndex = 0) {
return this.getTile(workspaceClass, tileIndex).find(`.editable-tile-title-text`);
}

getYAxisLabel(tileIndex = 0, workspaceClass) {
return this.getTile(tileIndex, workspaceClass).find(`.editable-axis-label`);
getTileContent(workspaceClass, tileIndex = 0) {
return this.getTile(workspaceClass, tileIndex).find(`[data-testid="bar-graph-content"]`);
}

getYAxisLabelButton(tileIndex = 0, workspaceClass) {
return this.getTile(tileIndex, workspaceClass).find(`[data-testid="axis-label-button"]`);
getChakraMenuItem(workspaceClass, tileIndex = 0) {
return cy.get(`body .chakra-portal button`).filter(':visible');
}

getYAxisLabelEditor(tileIndex = 0, workspaceClass) {
return this.getTile(tileIndex, workspaceClass).find(`[data-testid="axis-label-editor"] input`);
getChartArea(workspaceClass, tileIndex = 0) {
return this.getTile(workspaceClass, tileIndex).find(`svg.bar-graph-svg`);
}

getXAxisPulldown(tileIndex = 0, workspaceClass) {
return this.getTile(tileIndex, workspaceClass).find(`[data-testid="category-pulldown"]`);
getYAxisLabel(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`.editable-axis-label`);
}

getXAxisPulldownButton(tileIndex = 0, workspaceClass) {
return this.getXAxisPulldown(tileIndex, workspaceClass).find(`button`);
getYAxisLabelButton(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`[data-testid="axis-label-button"]`);
}

getXAxisPulldownMenuItem(tileIndex = 0, workspaceClass) {
return cy.get(`body .chakra-portal button`).filter(':visible');
getYAxisLabelEditor(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`[data-testid="axis-label-editor"] input`);
}

getXAxisPulldown(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`[data-testid="category-pulldown"]`);
}

getXAxisPulldownButton(workspaceClass, tileIndex = 0) {
return this.getXAxisPulldown(workspaceClass, tileIndex).find(`button`);
}

getYAxisTickLabel(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`.visx-axis-left text`);
}

getXAxisTickLabel(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`.visx-axis-bottom text`);
}

getBar(workspaceClass, tileIndex = 0) {
return this.getChartArea(workspaceClass, tileIndex).find(`.visx-bar`);
}

getLegendArea(workspaceClass, tileIndex = 0) {
return this.getTile(workspaceClass, tileIndex).find(`.bar-graph-legend`);
}

getDatasetLabel(workspaceClass, tileIndex = 0) {
return this.getLegendArea(workspaceClass, tileIndex).find(`.dataset-header .dataset-name`);
}

getDatasetUnlinkButton(workspaceClass, tileIndex = 0) {
return this.getLegendArea(workspaceClass, tileIndex).find(`.dataset-header .dataset-icon a`);
}

getSortByMenuButton(workspaceClass, tileIndex = 0) {
return this.getLegendArea(workspaceClass, tileIndex).find(`.sort-by button.chakra-menu__menu-button`);
}

getSecondaryValueName(workspaceClass, tileIndex = 0) {
return this.getLegendArea(workspaceClass, tileIndex).find(`.secondary-values .secondary-value-name`);
}

}
Expand Down
28 changes: 24 additions & 4 deletions cypress/support/elements/tile/TableToolTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ function wsclass(workspaceClass) {

class TableToolTile{
getTableTile(workspaceClass) {
return cy.get(`${wsclass(workspaceClass)} .canvas-area .table-tool`);
return cy.get(`${wsclass(workspaceClass)} .canvas .table-tool`);
}
getTableTitle(workspaceClass){
return cy.get(`${wsclass(workspaceClass)} .canvas-area .table-title`);
return cy.get(`${wsclass(workspaceClass)} .canvas .table-title`);
}
getAddColumnButton(){
return cy.get('.add-column-button');
Expand Down Expand Up @@ -39,7 +39,7 @@ class TableToolTile{
this.getRemoveRowButton().click();
}
getTableRow(){
return cy.get('.canvas-area .rdg-row');
return cy.get('.canvas .rdg-row');
}
getColumnHeaderText(i){
return cy.get('.column-header-cell .editable-header-cell .header-name').text();
Expand Down Expand Up @@ -89,8 +89,28 @@ class TableToolTile{
this.getTableCell().eq(cell).type(num+'{enter}');
}
getTableIndexColumnCell(){
return cy.get('.canvas-area .rdg-cell.index-column');
return this.getTableTile().find('.rdg-cell.index-column');
}
// Fill in a table tile with the given data (a list of lists)
// Table tile should in the default state (2 columns, no rows)
fillTable($tile, data) {
// at least two cols, or as many as the longest row in the data array
const cols = Math.max(2, ...data.map(row => row.length));
$tile.within((tile) => {
// tile will start with two columns; make more if desired
for (let i=2; i<cols; i++) {
this.getAddColumnButton().click();
}
for (let i=0; i<data.length; i++) {
for (let j=0; j<data[i].length; j++) {
const cellContent = data[i][j];
this.typeInTableCellXY(i, j, cellContent);
this.getTableCellXY(i, j).should('contain', cellContent);
}
}
});
}

getLinkGraphButton(){
return cy.get('.link-tile-button');
}
Expand Down
6 changes: 6 additions & 0 deletions docs/unit-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ Under 'dataset', there is one option:

- `cellsSelectCases`: boolean

#### Bar Graph

Common toolbar framework. One default button:

- `link-tile`: bring up the linking dialog to connect/disconnect a dataset

#### Data Deck

Not updated to common toolbar framework. However, supports toolbar configuration in a similar manner. Default buttons:
Expand Down
File renamed without changes
File renamed without changes
5 changes: 5 additions & 0 deletions src/clue/app-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@
"placeholderText": "",
"stamps": [],
"settings": {
"bargraph": {
"tools": [
"link-tile"
]
},
"dataset": {
"cellsSelectCases": false
},
Expand Down
8 changes: 4 additions & 4 deletions src/components/doc-editor/doc-editor-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ export const DocEditorApp = observer(function DocEditorApp() {
{ showLocalReadOnly &&
<>
<div className="readonly-header">Read Only Local</div>
<ReadonlyCanvas document={document}/>
<ReadonlyCanvas document={document} className="read-only-local-workspace"/>
</>
}
{ showRemoteReadOnly &&
<>
<div className="readonly-header">Read Only Remote (emulated)</div>
<ReadonlyCanvas document={remoteDocument}/>
<ReadonlyCanvas document={remoteDocument} className="read-only-remote-workspace"/>
</>
}
</div>
Expand All @@ -243,7 +243,7 @@ export const DocEditorApp = observer(function DocEditorApp() {
);
});

const ReadonlyCanvas = ({document}:{document: DocumentModelType}) => {
const ReadonlyCanvas = ({document, className}:{document: DocumentModelType, className: string}) => {
const readOnlyScale = 0.5;
const scaledStyle = {
position: "absolute",
Expand All @@ -254,7 +254,7 @@ const ReadonlyCanvas = ({document}:{document: DocumentModelType}) => {
} as const;

return (
<div className="canvas-container">
<div className={`canvas-container ${className}`}>
<div className="canvas-scaler" style={scaledStyle} >
<CanvasComponent
document={document}
Expand Down
18 changes: 12 additions & 6 deletions src/hooks/use-provider-tile-linking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { isGraphModel } from "../plugins/graph/models/graph-model";
import { getSharedModelManager } from "../models/tiles/tile-environment";
import { SharedModelType } from "../models/shared/shared-model";
import { LogEventName } from "../lib/logger-types";

import { logSharedModelDocEvent } from "../models/document/log-shared-model-document-event";
import { getTileContentInfo } from "../models/tiles/tile-content-info";
import { useAppConfig } from "./use-stores";

interface IProps {
actionHandlers?: any;
Expand Down Expand Up @@ -36,6 +37,7 @@ interface IProps {
export const useProviderTileLinking = ({
actionHandlers, model, readOnly, sharedModelTypes, allowMultipleGraphDatasets
}: IProps) => {
const appConfig = useAppConfig();
const {handleRequestTileLink, handleRequestTileUnlink} = actionHandlers || {};
const sharedModelManager = getSharedModelManager(model);
const sharedModels: SharedModelType[] = [];
Expand All @@ -55,10 +57,14 @@ export const useProviderTileLinking = ({

const linkTile = useCallback((sharedModel: SharedModelType) => {
if (!readOnly && sharedModelManager?.isReady) {
// TODO: this is temporary while we are working on getting Graph to work with multiple datasets
// Once multiple datasets are fully implemented, we should look at the "consumesMultipleDataSets"
// setting for the tile type; but for now graph has to allow multiples while not having that be the default.
if (!allowMultipleGraphDatasets && isGraphModel(model.content)) {
// Depending on the unit configuration, graphs sometimes allow multiple datasets and sometimes not.
// Other tiles register their ability to consume multiple datasets as part of their content info.
const allowsMultiple = isGraphModel(model.content)
? allowMultipleGraphDatasets
: getTileContentInfo(model.content.type)?.consumesMultipleDataSets?.(appConfig);

if (!allowsMultiple) {
// Remove any existing shared models before adding the new one
for (const shared of sharedModelManager.getTileSharedModels(model.content)) {
sharedModelManager.removeTileSharedModel(model.content, shared);
}
Expand All @@ -68,7 +74,7 @@ export const useProviderTileLinking = ({
logSharedModelDocEvent(LogEventName.TILE_LINK, model, sharedTiles, sharedModel);

}
}, [readOnly, sharedModelManager, model, allowMultipleGraphDatasets]);
}, [appConfig, readOnly, sharedModelManager, model, allowMultipleGraphDatasets]);

const unlinkTile = useCallback((sharedModel: SharedModelType) => {
if (!readOnly && sharedModelManager?.isReady) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/logger-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export enum LogEventName {
HIDE_SOLUTIONS,
SHOW_SOLUTIONS,

BARGRAPH_TOOL_CHANGE,
GEOMETRY_TOOL_CHANGE,
DRAWING_TOOL_CHANGE,
TABLE_TOOL_CHANGE,
Expand Down
Loading

0 comments on commit 7a65c8c

Please sign in to comment.