Skip to content

Commit

Permalink
create a flexible plots prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
mattseddon committed Sep 15, 2022
1 parent 998a8c4 commit 1519e4d
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 27 deletions.
2 changes: 1 addition & 1 deletion extension/src/cli/dvc/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const MIN_CLI_VERSION = '2.24.0'
export const MIN_CLI_VERSION = '2.0.0'
export const LATEST_TESTED_CLI_VERSION = '2.24.0'
export const MAX_CLI_VERSION = '3'

Expand Down
61 changes: 60 additions & 1 deletion extension/src/plots/model/collect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,20 @@ const collectDatapoints = (
values: Record<string, unknown>[] = []
) => {
for (const value of values) {
;(acc[rev][path] as unknown[]).push({ ...value, rev })
const filename = (
value?.dvc_data_version_info as {
filename: string | undefined
}
)?.filename
const data: { rev: string; filename?: string } = {
...value,
rev
}

if (filename) {
data.filename = filename
}
;(acc[rev][path] as unknown[]).push(data)
}
}

Expand Down Expand Up @@ -413,6 +426,46 @@ export const collectData = (
return acc
}

const collectFlexiblePlot = (
acc: Record<string, boolean>,
path: string,
plot: TemplatePlot
// eslint-disable-next-line sonarjs/cognitive-complexity
) => {
acc[path] = false
const files = new Set()
for (const value of Object.values(plot.datapoints || {}).flat()) {
const filename = (
value?.dvc_data_version_info as {
filename: string | undefined
}
)?.filename
if (filename) {
files.add(filename)
}
if (files.size > 1) {
acc[path] = true
return
}
}
}

// eslint-disable-next-line sonarjs/cognitive-complexity
export const collectFlexiblePlots = (data: PlotsOutput) => {
const acc = {}
for (const [path, plots] of Object.entries(data)) {
for (const plot of plots) {
if (isImagePlot(plot)) {
continue
}

collectFlexiblePlot(acc, path, plot)
}
}

return acc
}

const collectWorkspaceRevisionData = (
overwriteRevisionData: RevisionPathData
) => {
Expand Down Expand Up @@ -497,6 +550,7 @@ const collectTemplateGroup = (
selectedRevisions: string[],
templates: TemplateAccumulator,
revisionData: RevisionData,
flexiblePlots: Record<string, boolean>,
size: PlotSize,
revisionColors: ColorScale | undefined
): TemplatePlotEntry[] => {
Expand All @@ -509,9 +563,12 @@ const collectTemplateGroup = (
.flatMap(revision => revisionData?.[revision]?.[path])
.filter(Boolean)

const isFlexiblePlot = flexiblePlots[path]

const content = extendVegaSpec(
fillTemplate(template, datapoints),
size,
isFlexiblePlot,
revisionColors
)

Expand All @@ -532,6 +589,7 @@ export const collectSelectedTemplatePlots = (
selectedRevisions: string[],
templates: TemplateAccumulator,
revisionData: RevisionData,
flexiblePlots: Record<string, boolean>,
size: PlotSize,
revisionColors: ColorScale | undefined
): TemplatePlotSection[] | undefined => {
Expand All @@ -543,6 +601,7 @@ export const collectSelectedTemplatePlots = (
selectedRevisions,
templates,
revisionData,
flexiblePlots,
size,
revisionColors
)
Expand Down
16 changes: 11 additions & 5 deletions extension/src/plots/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
ComparisonData,
RevisionData,
TemplateAccumulator,
collectBranchRevisionDetails
collectBranchRevisionDetails,
collectFlexiblePlots
} from './collect'
import {
CheckpointPlot,
Expand Down Expand Up @@ -49,6 +50,7 @@ export class PlotsModel extends ModelWithPersistence {

private revisionData: RevisionData = {}
private templates: TemplateAccumulator = {}
private flexiblePlots: Record<string, boolean> = {}

private checkpointPlots?: CheckpointPlot[]
private selectedMetrics?: string[]
Expand Down Expand Up @@ -104,10 +106,12 @@ export class PlotsModel extends ModelWithPersistence {
...revs.map(rev => cliIdToLabel[rev])
])

const [{ comparisonData, revisionData }, templates] = await Promise.all([
collectData(data, cliIdToLabel),
collectTemplates(data)
])
const [{ comparisonData, revisionData }, templates, flexiblePlots] =
await Promise.all([
collectData(data, cliIdToLabel),
collectTemplates(data),
collectFlexiblePlots(data)
])

const { overwriteComparisonData, overwriteRevisionData } =
collectWorkspaceRaceConditionData(
Expand All @@ -127,6 +131,7 @@ export class PlotsModel extends ModelWithPersistence {
...overwriteRevisionData
}
this.templates = { ...this.templates, ...templates }
this.flexiblePlots = { ...this.flexiblePlots, ...flexiblePlots }

this.setComparisonOrder()

Expand Down Expand Up @@ -421,6 +426,7 @@ export class PlotsModel extends ModelWithPersistence {
selectedRevisions,
this.templates,
this.revisionData,
this.flexiblePlots,
this.getPlotSize(Section.TEMPLATE_PLOTS),
this.getRevisionColors()
)
Expand Down
15 changes: 8 additions & 7 deletions extension/src/plots/vega/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('getColorScale', () => {

describe('extendVegaSpec', () => {
it('should not add encoding if no color scale is provided', () => {
const extendedSpec = extendVegaSpec(linearTemplate, PlotSize.REGULAR)
const extendedSpec = extendVegaSpec(linearTemplate, PlotSize.REGULAR, false)
expect(extendedSpec.encoding).toBeUndefined()
})

Expand All @@ -90,6 +90,7 @@ describe('extendVegaSpec', () => {
const extendedSpec = extendVegaSpec(
linearTemplate,
PlotSize.REGULAR,
false,
colorScale
)

Expand Down Expand Up @@ -132,7 +133,7 @@ describe('extendVegaSpec', () => {

it('should truncate all titles from the left to 50 characters for large plots', () => {
const spec = withLongTemplatePlotTitle()
const updatedSpec = extendVegaSpec(spec, PlotSize.LARGE)
const updatedSpec = extendVegaSpec(spec, PlotSize.LARGE, false)

const truncatedTitle = '…-many-many-characters-at-least-seventy-characters'
const truncatedHorizontalTitle =
Expand All @@ -158,7 +159,7 @@ describe('extendVegaSpec', () => {

it('should truncate all titles from the left to 50 characters for regular plots', () => {
const spec = withLongTemplatePlotTitle()
const updatedSpec = extendVegaSpec(spec, PlotSize.REGULAR)
const updatedSpec = extendVegaSpec(spec, PlotSize.REGULAR, false)

const truncatedTitle = '…-many-many-characters-at-least-seventy-characters'
const truncatedHorizontalTitle =
Expand All @@ -184,7 +185,7 @@ describe('extendVegaSpec', () => {

it('should truncate all titles from the left to 30 characters for small plots', () => {
const spec = withLongTemplatePlotTitle()
const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL)
const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL, false)

const truncatedTitle = '…s-at-least-seventy-characters'
const truncatedHorizontalTitle = '…at-least-seventy-characters-x'
Expand Down Expand Up @@ -214,7 +215,7 @@ describe('extendVegaSpec', () => {
text: repeatedTitle
})

const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL)
const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL, false)

const truncatedTitle = '…ghijklmnopqrstuvwyz1234567890'

Expand All @@ -231,7 +232,7 @@ describe('extendVegaSpec', () => {
const repeatedTitle = 'abcdefghijklmnopqrstuvwyz1234567890'
const spec = withLongTemplatePlotTitle([repeatedTitle, repeatedTitle])

const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL)
const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL, false)

const truncatedTitle = '…ghijklmnopqrstuvwyz1234567890'

Expand All @@ -251,7 +252,7 @@ describe('extendVegaSpec', () => {
text: [repeatedTitle, repeatedTitle]
})

const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL)
const updatedSpec = extendVegaSpec(spec, PlotSize.SMALL, false)

const truncatedTitle = '…ghijklmnopqrstuvwyz1234567890'

Expand Down
41 changes: 29 additions & 12 deletions extension/src/plots/vega/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,43 @@ export const getColorScale = (
return acc.domain.length > 0 ? acc : undefined
}

type EncodingUpdate = {
encoding: {
color: {
legend: {
disable: boolean
}
scale: ColorScale
type Encoding = {
strokeDash?: {
field: string
legend: {
disable: boolean
}
}
color: {
legend: {
disable: boolean
}
scale: ColorScale
}
}

type EncodingUpdate = {
encoding: Encoding
}

export const getSpecEncodingUpdate = (
colorScale: ColorScale
): EncodingUpdate => ({
encoding: {
colorScale: ColorScale,
hasMultipleFiles: boolean
): EncodingUpdate => {
const encoding: Encoding = {
color: {
legend: { disable: true },
scale: colorScale
}
}
})
if (hasMultipleFiles) {
encoding.strokeDash = { field: 'filename', legend: { disable: true } }
}

return {
encoding
}
}

const mergeUpdate = (spec: TopLevelSpec, update: EncodingUpdate) => {
let newSpec = cloneDeep(spec) as any
Expand Down Expand Up @@ -230,6 +246,7 @@ export const truncateTitles = (
export const extendVegaSpec = (
spec: TopLevelSpec,
size: PlotSize,
isFlexiblePlot: boolean,
colorScale?: ColorScale
) => {
const updatedSpec = truncateTitles(spec, size) as unknown as TopLevelSpec
Expand All @@ -238,7 +255,7 @@ export const extendVegaSpec = (
return updatedSpec
}

const update = getSpecEncodingUpdate(colorScale)
const update = getSpecEncodingUpdate(colorScale, isFlexiblePlot)

return mergeUpdate(updatedSpec, update)
}
1 change: 1 addition & 0 deletions extension/src/test/fixtures/plotsDiff/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ const extendedSpecs = (plotsOutput: TemplatePlots): TemplatePlotSection[] => {
}
} as TopLevelSpec,
PlotSize.REGULAR,
false,
{
domain: expectedRevisions,
range: copyOriginalColors().slice(0, 5)
Expand Down
7 changes: 6 additions & 1 deletion webview/src/plots/components/ZoomedInPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ export const ZoomedInPlot: React.FC<ZoomedInPlotProps> = ({
{...merge(
{ ...cloneDeep(props) },
{
spec: { encoding: { color: { legend: { disable: false } } } }
spec: {
encoding: {
color: { legend: { disable: false } },
strokeDash: { legend: { disable: false } }
}
}
}
)}
config={{
Expand Down

0 comments on commit 1519e4d

Please sign in to comment.