Skip to content

Commit

Permalink
feat: make the webview prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Paraskos committed Aug 5, 2023
1 parent 6112363 commit b65cf5e
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 56 deletions.
42 changes: 27 additions & 15 deletions client/src/FountainPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class FountainPanel {
case 'alert':
return vscode.window.showErrorMessage(message.text);
case 'open':
return this.handleOpenLink(message, uri);
return this.handleOpenLink(message);
}
},
null,
Expand Down Expand Up @@ -120,24 +120,36 @@ export class FountainPanel {
this._panel.webview.postMessage({ command: "fountain.analyseCharacter", uri, name });
}
public setUri(uri) {
// Send a message to the webview webview.
// You can send any JSON serializable data.
this._panel.webview.postMessage({ command: 'opened', uri });
}

private async handleOpenLink(message: any, uri: string) {
private async handleOpenLink(message: any) {
console.log("handleOpenLink")
const link = URI.parse(message.link);

console.log("Open file `" + message.link + "` relative to `" + uri + '`')

let base = URI.parse(uri);
const fileToOpen = Utils.joinPath(Utils.dirname(base), link.path);
console.log(fileToOpen)

const line = (+link.fragment.substring(1)) - 1;

const editor = await vscode.window.showTextDocument(fileToOpen, {});
editor.revealRange(new vscode.Range(line, 0, line, 0), vscode.TextEditorRevealType.InCenterIfOutsideViewport);
const line = link.fragment ? (+link.fragment.substring(1)) - 1 : 0;
const candidates = await vscode.workspace.findFiles(link.path);
const absolutePath = Utils.joinPath(vscode.workspace.workspaceFolders[0].uri, link.path);
if(candidates.length > 0) {
const doc = await vscode.workspace.openTextDocument(candidates[0])
const editor = await vscode.window.showTextDocument(doc, {});
editor.revealRange(new vscode.Range(line, 0, line, 0), vscode.TextEditorRevealType.InCenterIfOutsideViewport);
} else {
if (link.query.includes('create')) {
console.log("create")
try {
await vscode.workspace.fs.writeFile(absolutePath, new Uint8Array([20,20,20]))
const doc = await vscode.workspace.openTextDocument(absolutePath)
const editor = await vscode.window.showTextDocument(doc, {});
editor.revealRange(new vscode.Range(line, 0, line, 0), vscode.TextEditorRevealType.InCenterIfOutsideViewport);
} catch (e) {
console.log(`create failed ${e}`)
await vscode.window.showErrorMessage(`Could not create ${absolutePath}, ${e}`);
}
} else {
console.log("nocreate")
await vscode.window.showErrorMessage(`Could not find ${link}`);
}
}
}

public dispose() {
Expand Down
Empty file added sample/.fountainrc
Empty file.
9 changes: 7 additions & 2 deletions webviews/src/bar-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class BarChart extends HTMLElement {
.attr("viewBox", [0, 0, this.width, this.height])
.attr("style", this.style.cssText + "; max-width: 100%; height: auto; height: intrinsic;");

applySeriesBaackgrounds(svg);
applySeriesBaackgrounds(svg, this.visualImpaired);


svg.append("g")
Expand Down Expand Up @@ -128,6 +128,11 @@ export class BarChart extends HTMLElement {
return this.getAttribute('title') || '';
}


get visualImpaired() {
return this.getAttribute('visualImpaired') === 'true' || false;
}

get width() {
return parseFloat(this.getAttribute('width') || '640');
}
Expand Down Expand Up @@ -221,7 +226,7 @@ export class BarChart extends HTMLElement {
return [this.marginTop, this.height - this.marginBottom];
}

get yPadding() { return 0; }
get yPadding() { return 0.1; }
// array of colors for names
get colors() {
return scaleOrdinal()
Expand Down
34 changes: 23 additions & 11 deletions webviews/src/chart-series-backgrounds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,57 @@ function pathPattern(defs: Selection<SVGDefsElement, undefined, null, undefined>
.attr('style', 'fill:#fff;fill-opacity:0.25;');
return pattern;
}
export function applySeriesBaackgrounds(svg: Selection<SVGSVGElement, undefined, null, undefined>) {
export function applySeriesBaackgrounds(svg: Selection<SVGSVGElement, undefined, null, undefined>, visualImpaired: boolean = false) {
const size = 10;
const halfSize = 0.5 * size;
const defs = svg.append("defs");

const french_blue = '#007accff';
const light_cyan = '#c9f9ffff';
const thulian_pink = '#e56399ff';
const sandy_brown = '#ee964bff';
const apple_green = '#a5be00ff';

const colors = [french_blue,
light_cyan,
thulian_pink,
sandy_brown,
apple_green]

pathPattern(defs, [
`M${halfSize},0l${halfSize},${halfSize}l-${halfSize},${halfSize}l-${halfSize},-${halfSize}l${halfSize},-${halfSize}Z`,
], size, '#00888d')
], size, colors[0])
.attr('id', 'chart-series-colour-0');

pathPattern(defs, [
`M0,${size}l${size},-${size}l0,${halfSize}l-${halfSize},${halfSize}l-${halfSize},0Z`,
`M0,${halfSize}l${halfSize},-${halfSize}l-${halfSize},0l0,${halfSize}Z`
], size, '#740099')
], size, colors[1])
.attr('id', 'chart-series-colour-1');


pathPattern(defs, [
`M0,0l${halfSize},0l0,${halfSize}l-${halfSize},0Z`,
`M${halfSize},${halfSize}l${halfSize},0l0,${halfSize}l-${halfSize},0Z`,
], size, '#007acc')
], size, colors[2])
.attr('id', 'chart-series-colour-2');


pathPattern(defs, [
`M0,0l${halfSize},0l0,${size}l-${halfSize},0Z`,
], size, '#13066b')
], size, colors[3])
.attr('id', 'chart-series-colour-3');

pathPattern(defs, [
`M0,0l0,${halfSize}l${size},0l0,-${halfSize}Z`,
], size, '#ff1b00')
], size, colors[4])
.attr('id', 'chart-series-colour-4');

svg.append("style")
.html(`
.chart-series-colour-0 { fill: url(#chart-series-colour-0); }
.chart-series-colour-1 { fill: url(#chart-series-colour-1); }
.chart-series-colour-2 { fill: url(#chart-series-colour-2); }
.chart-series-colour-3 { fill: url(#chart-series-colour-3); }
.chart-series-colour-3 { fill: url(#chart-series-colour-4); }`);
.chart-series-colour-0 { fill: ${visualImpaired ? 'url(#chart-series-colour-0);' : colors[0]} }
.chart-series-colour-1 { fill: ${visualImpaired ? 'url(#chart-series-colour-1);' : colors[1]} }
.chart-series-colour-2 { fill: ${visualImpaired ? 'url(#chart-series-colour-2);' : colors[2]} }
.chart-series-colour-3 { fill: ${visualImpaired ? 'url(#chart-series-colour-3);' : colors[3]} }
.chart-series-colour-3 { fill: ${visualImpaired ? 'url(#chart-series-colour-4);' : colors[4]} }`);
}
14 changes: 7 additions & 7 deletions webviews/src/donut-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ export class DonutChart extends HTMLElement {
.attr("viewBox", [-this.width / 2, -this.height / 2, this.width, this.height])
.attr("style", this.style.cssText + "; max-width: 100%; height: auto; height: intrinsic;");

applySeriesBaackgrounds(svg);
applySeriesBaackgrounds(svg, this.visualImpaired);

if(this.title) {
svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("style", "font-size: var(--type-ramp-base-font-size); font-family: sans-serif;")
.attr("text-anchor", "middle")
.append("text")
.selectAll("tspan")
Expand All @@ -82,14 +81,13 @@ export class DonutChart extends HTMLElement {


svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("style", "font-size: var(--type-ramp-minus1-font-size); font-family: sans-serif;")
.attr("text-anchor", "middle")
.selectAll("text")
.data(arcs)
.join("text")
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.attr("transform", d => `translate(${labelArc.centroid(d as any)})`)
.attr("transform", d => `translate(${labelArc.centroid(d as any).map(it => it * 1.6)})`)
.selectAll("tspan")
.data(d => {
const lines = `${titleFn(d.index)}`.split(/\n/);
Expand Down Expand Up @@ -118,7 +116,9 @@ export class DonutChart extends HTMLElement {
// this.handleRemoveItemListeners(removeElementButtons);
// addElementButton.addEventListener('click', this.addListItem, false);
}

get visualImpaired() {
return this.getAttribute('visualImpaired') === 'true' || false;
}

get entries(): { [key: string]: number } {
return JSON.parse(this.getAttribute('entries') || '{}') || {};
Expand Down
17 changes: 15 additions & 2 deletions webviews/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function updateCharacterTable(stats: CharacterStats[]) {
updateTable('grid-characters', stats.map((row) => ({
"Name": row.Name,
"Gender": row.Gender?.toUpperCase(),
"Length & Duration": [
"Duration": [
`${row?.Duration ? formatTime(row.Duration) : ''}`,
`${row.Lines}\u00a0lines`,
`${row.Words}\u00a0words`,
Expand Down Expand Up @@ -139,9 +139,21 @@ function onMessage(ev: MessageEvent) {
}
}

function handleHrefButton(e: Event) {
const href = (e.target as HTMLElement).getAttribute('data-href')
console.log("open file in vscode " + href)
vscode.postMessage({
command: "open",
link: href
});
}


function main() {
console.log("main");


document.querySelectorAll('vscode-button[data-href]').forEach((it) => it.addEventListener('click', handleHrefButton))

if (state.statistics) {
updateCharacterTable(state.statistics.characters);
updateLocationsTable(state.statistics.locations);
Expand All @@ -151,6 +163,7 @@ function main() {
vscode.postMessage({ type: 'ready' });
}


window.addEventListener('DOMContentLoaded', main);
window.addEventListener("load", main);
window.addEventListener("message", onMessage);
58 changes: 39 additions & 19 deletions webviews/stats.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<head>
<base href="${baseUri}">
<meta charset="utf-8">


<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
Expand Down Expand Up @@ -41,44 +41,64 @@
<h4>Characters</h4>
<section>
<h5>Representation by Racial Identity</h5>
<div style="display: flex; flex-direction: row; justify-content: space-evenly;" class="hide-if-no-racial-identity">
<div style="display: flex; flex-direction: row; justify-content: space-evenly;"
class="hide-if-no-racial-identity">
<bar-chart id="characters-speaking-roles-by-racial-identity" width="200" height="100"
style="overflow: visible;" title="Speaking Roles"></bar-chart>
<bar-chart id="characters-sentiment-by-racial-identity" width="200" height="100"
style="overflow: visible;" title="Sentiment"></bar-chart>
</div>
<div style="display: flex; flex-direction: row; justify-content: space-evenly;" class="hide-if-no-racial-identity">
<donut-chart id="characters-racial-identity-dialogue" width="100" height="100" style="overflow: visible;"
title="Dialogue&#10;Duration"></donut-chart>
<bar-chart id="characters-racial-identity-readingAge" width="200" height="100" style="overflow: visible;"
title="Reading Age"></bar-chart>
<div style="display: flex; flex-direction: row; justify-content: space-evenly;"
class="hide-if-no-racial-identity">
<donut-chart id="characters-racial-identity-dialogue" width="100" height="100"
style="overflow: visible;" title="Dialogue&#10;Duration"></donut-chart>
<bar-chart id="characters-racial-identity-readingAge" width="200" height="100"
style="overflow: visible;" title="Reading Age"></bar-chart>
</div>
<aside id="characters-racial-identity-fountainrc">
<p>
There's no data to display here because the Racial Identity of your characters havent been
specified.
You can set the Racial Identiy of characters in the .fountainrc file.
</p>
<vscode-button>Open .fountainrc</vscode-button>
<vscode-button data-href=".fountainrc?create" style="float:right; clear:right;">Open
.fountainrc</vscode-button>
</aside>
</section>
<section>
<h5>Gender Representation</h5>
<div style="display: flex; flex-direction: row; justify-content: space-evenly;">
<bar-chart id="characters-speaking-roles-by-gender" width="200" height="100"
style="overflow: visible;" title="Speaking Roles"></bar-chart>
<bar-chart id="characters-sentiment-by-gender" width="200" height="100"
style="overflow: visible;" title="Sentiment"></bar-chart>
<div style="max-width: 45%;">
<span style="display: block; text-align: center; font-weight: bold;">Speaking Roles</span>
<bar-chart id="characters-speaking-roles-by-gender" width="400" height="200"
style="overflow: visible;"></bar-chart>
</div>
<div style="max-width: 45%;">
<span style="display: block; text-align: center; font-weight: bold;">Sentiment</span>
<bar-chart id="characters-sentiment-by-gender" width="400" height="200"
style="overflow: visible;"></bar-chart>
</div>

</div>
<br />
<div style="display: flex; flex-direction: row; justify-content: space-evenly;">
<donut-chart id="characters-gender-dialogue" width="100" height="100" style="overflow: visible;"
title="Dialogue&#10;Duration"></donut-chart>
<bar-chart id="characters-gender-readingAge" width="200" height="100" style="overflow: visible;"
title="Reading Age"></bar-chart>
<div style="max-width: 45%;">
<donut-chart id="characters-gender-dialogue" width="200" height="200" style="overflow: visible;"
title="Dialogue&#10;Duration"></donut-chart>
</div>
<div style="max-width: 45%;">
<span style="display: block; text-align: center; font-weight: bold;">Reading Age</span>
<bar-chart id="characters-gender-readingAge" width="400" height="200"
style="overflow: visible;"></bar-chart>
</div>
</div>
<aside>
<aside id="characters-gender-identity-fountainrc">
<p>
Please note: Gender is a guess based on character name. For more accurate gender representation statistics, set characters' genders explicitly.
Please note: Gender is a guess based on character name. For more accurate gender
representation statistics, set characters' genders explicitly.
</p>
<vscode-button>Open .fountainrc</vscode-button>
<vscode-button data-href=".fountainrc?create" style="float:right; clear:right;">Open
.fountainrc</vscode-button>
</aside>
</section>
<section>
Expand Down
34 changes: 34 additions & 0 deletions webviews/styles/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
vscode-data-grid {
min-height: 3rem;
margin-top: 1rem;
}

vscode-data-grid vscode-data-grid-row:nth-child(even) {
background: var(--vscode-list-dropBackground);
}

vscode-data-grid vscode-data-grid-row:hover {
background: var(--vscode-list-hoverBackground);
}

vscode-data-grid-cell.column-header {
line-height: 3rem;
color: white;
font-size: calc(var(--type-ramp-base-font-size) + 2px);
}

vscode-data-grid-row {
min-height: 3rem;
}

vscode-data-grid-row.header,
vscode-data-grid-row.header:hover {
background: #47B6FF;
color: white;
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
}

vscode-button {
border-radius: 2px;
}

0 comments on commit b65cf5e

Please sign in to comment.