Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

188616847 stroke point plot background color import/export V2 #1802

Merged
merged 10 commits into from
Feb 13, 2025
2 changes: 1 addition & 1 deletion v3/src/components/container/free-tile-row.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

.free-tile-component {
position: absolute;
background: white;
background: transparent;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 25%);
border-radius: 6px;
// https://stackoverflow.com/a/17117992
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const DataDisplayContentModel = TileContentModel
pointDescription: types.optional(DisplayItemDescriptionModel, () => DisplayItemDescriptionModel.create()),
pointDisplayType: types.optional(types.enumeration([...PointDisplayTypes]), "points"),
plotBackgroundColor: defaultBackgroundColor,
plotBackgroundOpacity: 1,
isTransparent: false,
})
.volatile(() => ({
Expand Down
3 changes: 3 additions & 0 deletions v3/src/components/graph/models/graph-content-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@
setPlotBackgroundColor(color: string) {
self.plotBackgroundColor = color
},
setPlotBackgroundOpacity(opacity: number) {
self.plotBackgroundOpacity = opacity

Check warning on line 638 in v3/src/components/graph/models/graph-content-model.ts

View check run for this annotation

Codecov / codecov/patch

v3/src/components/graph/models/graph-content-model.ts#L637-L638

Added lines #L637 - L638 were not covered by tests
},
setIsTransparent(transparent: boolean) {
self.isTransparent = transparent
},
Expand Down
27 changes: 18 additions & 9 deletions v3/src/components/graph/v2-graph-exporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,8 @@ describe("V2GraphImporter", () => {
const kNotImplementedProps = [
"numberOfLegendQuantiles",
"legendQuantilesAreLocked",
"pointColor",
"pointSizeMultiplier",
"plotBackgroundColor",
"plotBackgroundImage",
"plotBackgroundImageLockInfo",
"plotBackgroundOpacity",
"strokeColor",
"strokeSameAsFill",
"isTransparent",
"transparency",
"strokeTransparency"
]
const kIgnoreProps = [
// standard properties handled externally
Expand Down Expand Up @@ -227,4 +218,22 @@ describe("V2GraphImporter", () => {
expect(v2GraphTileOutStorage).toEqual(v2GraphTileStorage)
})
})

it("exports graph components with plot formatting", () => {
const { v2Document } = loadCodapDocument("mammals-graph-formats.codap")
const v2GraphTiles = v2Document.components.filter(c => c.type === "DG.GraphView")
v2GraphTiles.forEach(v2GraphTile => {
logGraphTitleMaybe(true, v2GraphTile)
const v3GraphTile = v2GraphImporter({
v2Component: v2GraphTile,
v2Document,
insertTile: mockInsertTile
})
// tests round-trip import/export of every graph component
const v2GraphTileOut = v2GraphExporter({ tile: v3GraphTile! })
const v2GraphTileStorage = transformObject(v2GraphTile.componentStorage, kIgnoreProps, kRoundProps)
const v2GraphTileOutStorage = transformObject(v2GraphTileOut?.componentStorage, kIgnoreProps, kRoundProps)
expect(v2GraphTileOutStorage).toEqual(v2GraphTileStorage)
})
})
})
28 changes: 28 additions & 0 deletions v3/src/components/graph/v2-graph-exporter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { colord } from "colord"
import { SetRequired } from "type-fest"
import { AttributeType } from "../../models/data/attribute-types"
import { toV2Id } from "../../utilities/codap-utils"
import { removeAlphaFromColor } from "../../utilities/color-utils"
import { V2TileExportFn } from "../../v2/codap-v2-tile-exporters"
import { guidLink, ICodapV2Adornment, ICodapV2GraphStorage, IGuidLink } from "../../v2/codap-v2-types"
import { IAxisModel, isNumericAxisModel } from "../axis/models/axis-model"
Expand Down Expand Up @@ -230,13 +232,39 @@ function getPlotModels(graph: IGraphContentModel): Partial<ICodapV2GraphStorage>
return storage
}

const getTransparency = (color: string, type: "point" | "stroke") => {
const rgbaColor = colord(color).toRgb()
return rgbaColor.a ?? (type === "point" ? 0.84 : 1)
Copy link
Member

Choose a reason for hiding this comment

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

I moved this function here because it contains graph-specific logic rather than something appropriate to all clients of color-utils. That said, in practice it doesn't matter because toRgb() is documented to always return an alpha, so the ?? (type === "point" ? 0.84 : 1) will never have any effect. If there are some circumstances in which 0.84 should be returned, then the logic will need to be clarified.

}

// v2 uses color names for default stroke colors
const strokeColorStr = (color: string) => {
const colorHex = removeAlphaFromColor(color).toLowerCase()
return colorHex === "#ffffff" ? "white"
: colorHex === "#d3d3d3" ? "lightgrey"
: colorHex
}

export const v2GraphExporter: V2TileExportFn = ({ tile }) => {
const graph = isGraphContentModel(tile.content) ? tile.content : undefined
if (!graph) return

const componentStorage: Partial<ICodapV2GraphStorage> = {
_links_: getLinks(graph),
displayOnlySelected: !!graph.dataConfiguration.displayOnlySelectedCases,
pointColor: removeAlphaFromColor(graph.pointDescription.pointColor),
transparency: getTransparency(graph.pointDescription.pointColor, "point"),
strokeColor: graph.pointDescription.pointStrokeSameAsFill
? "white" // v2 uses white for stroke when stroke is same as fill
: strokeColorStr(graph.pointDescription.pointStrokeColor),
strokeTransparency: graph.pointDescription.pointStrokeSameAsFill
? 0.4 : getTransparency(graph.pointDescription.pointStrokeColor, "stroke"),
pointSizeMultiplier: graph.pointDescription.pointSizeMultiplier,
strokeSameAsFill: graph.pointDescription.pointStrokeSameAsFill,
plotBackgroundColor: graph.plotBackgroundColor === "#FFFFFF"
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to worry about other variations (e.g. #ffffff or white?) or is this string canonicalized to this format?

? null : removeAlphaFromColor(graph.plotBackgroundColor),
plotBackgroundOpacity: getTransparency(graph.plotBackgroundColor, "stroke"),
isTransparent: graph.isTransparent,
// attribute roles and types
...getAttrRoleAndType(graph, "x", "x"),
...getAttrRoleAndType(graph, "y", "y"),
Expand Down
21 changes: 12 additions & 9 deletions v3/src/components/graph/v2-graph-importer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ITileModelSnapshotIn} from "../../models/tiles/tile-model"
import {toV3Id} from "../../utilities/codap-utils"
import {defaultBackgroundColor, parseColorToHex} from "../../utilities/color-utils"
import {V2TileImportArgs} from "../../v2/codap-v2-tile-importers"
import {IGuidLink, isV2GraphComponent} from "../../v2/codap-v2-types"
import {v3TypeFromV2TypeIndex} from "../../v2/codap-v2-data-set-types"
Expand All @@ -14,7 +15,6 @@
import {AxisPlace} from "../axis/axis-types"
import {IAxisModelSnapshotUnion} from "../axis/models/axis-model"
import {v2AdornmentImporter} from "./adornments/v2-adornment-importer"
import {defaultBackgroundColor} from "../../utilities/color-utils"

const attrKeys = ["x", "y", "y2", "legend", "top", "right"] as const
type AttrKey = typeof attrKeys[number]
Expand Down Expand Up @@ -45,19 +45,21 @@
componentStorage: {
name, title = "", _links_: links, plotModels,

pointColor, strokeColor, pointSizeMultiplier,
pointColor, transparency, strokeColor, strokeTransparency, pointSizeMultiplier,
strokeSameAsFill, isTransparent,
plotBackgroundImageLockInfo,
/* TODO_V2_IMPORT: [Story: #188694812]
The following are present in the componentStorage but not used in the V3 content model (yet):
displayOnlySelected, legendRole, legendAttributeType, numberOfLegendQuantiles,
legendQuantilesAreLocked, plotBackgroundImage, transparency, strokeTransparency,
plotBackgroundOpacity,
legendQuantilesAreLocked, plotBackgroundImage, plotBackgroundOpacity,
*/
}
} = v2Component
const plotBackgroundColor: string | null | undefined = v2Component.componentStorage.plotBackgroundColor ||
defaultBackgroundColor
const plotBackgroundOpacity = v2Component.componentStorage.plotBackgroundOpacity ?? 1
const plotBackgroundColor =
(v2Component.componentStorage.plotBackgroundColor &&
parseColorToHex(v2Component.componentStorage.plotBackgroundColor, {alpha: plotBackgroundOpacity})) ||
defaultBackgroundColor
type TLinksKey = keyof typeof links
const contextId = links.context?.id
const {data, metadata} = v2Document.getDataAndMetadata(contextId)
Expand Down Expand Up @@ -171,7 +173,7 @@
axes,
plotType,
plotBackgroundColor,
// plotBackgroundOpacity,
plotBackgroundOpacity,
// plotBackgroundImage,
// V2 plotBackgroundImageLockInfo can be null, V3 only accepts undefined
plotBackgroundImageLockInfo: plotBackgroundImageLockInfo ?? undefined,
Expand All @@ -180,8 +182,9 @@
* displayOnlySelected,legendRole, legendAttributeType, numberOfLegendQuantiles, legendQuantilesAreLocked,
* */
pointDescription: {
_itemColors: pointColor ? [pointColor] : [],
_itemStrokeColor: strokeColor,
_itemColors: pointColor ? [parseColorToHex(pointColor, {colorNames: true, alpha: transparency})] : [],
_itemStrokeColor: strokeColor ? parseColorToHex(strokeColor, {colorNames: true, alpha: strokeTransparency})
: strokeColor,

Check warning on line 187 in v3/src/components/graph/v2-graph-importer.ts

View check run for this annotation

Codecov / codecov/patch

v3/src/components/graph/v2-graph-importer.ts#L187

Added line #L187 was not covered by tests
_pointSizeMultiplier: pointSizeMultiplier,
/*transparency, strokeTransparency*/
_itemStrokeSameAsFill: strokeSameAsFill
Expand Down
Loading