[README] Add support window diagram (#55678)

* [README] Add support window diagram

* [README] 🤖 Update support window diagram

* Eliminate translations

* [README] 🤖 Update support window diagram

* Port from ggplot2 -> D3.js

* [README] 🤖 Update support window diagram

Co-authored-by: github/workflows/support-window.yml <bot@typescriptlang.org>
This commit is contained in:
Jack Bates
2021-10-28 15:08:47 -07:00
committed by GitHub
parent efa2545b50
commit 141503320e
14 changed files with 762 additions and 690 deletions

128
scripts/support-window.ts Normal file
View File

@@ -0,0 +1,128 @@
import { max, min } from "d3-array";
import { axisLeft, axisTop } from "d3-axis";
import { scaleBand, scaleTime } from "d3-scale";
import { select } from "d3-selection";
import { utcYear } from "d3-time";
import { utcFormat } from "d3-time-format";
import { JSDOM } from "jsdom";
import serialize from "w3c-xmlserializer";
import data from "../docs/support-window.json";
const width = 640;
const height = 250;
const margin = { top: 30, right: 0, bottom: 0, left: 0 };
const formatDate = utcFormat("%Y-%m");
const now = new Date();
const supported = Object.entries(data)
.map(([version, value]) => {
const releaseDate = new Date(value);
const endDate = utcYear.offset(releaseDate, 2);
return { version, releaseDate, endDate };
})
.filter((d) => d.endDate >= now);
const x = scaleTime()
.domain([
min(
supported,
(d) =>
// Clip 1/4 of the earliest supported version. Cuts off the
// release date (unimportant?) but gives the visual impression
// of additional, unsupported versions?
new Date(
Number(d.releaseDate) +
((d.endDate as unknown as number) -
(d.releaseDate as unknown as number)) /
4
)
)!,
max(supported, (d) => d.endDate)!,
])
.nice()
.range([margin.left, width - margin.right]);
const y = scaleBand()
.domain(supported.map((d) => d.version))
.range([margin.top, height - margin.bottom])
.padding(0.2);
const dom = new JSDOM();
const svg = select(dom.window.document.body)
.append("svg")
// @ts-expect-error
.attr("viewBox", [0, 0, width, height])
.attr("font-family", "sans-serif");
const axes = svg
.append("g")
.attr("stroke-dasharray", 2)
.attr("stroke-opacity", 0.5)
.attr("stroke-width", 0.5);
const xAxis = axes.append("g").attr("transform", `translate(0,${margin.top})`);
axisTop(x)
.ticks(5)
.tickSize(margin.top - height - margin.bottom)(xAxis);
xAxis.selectAll(".domain").remove();
const yAxis = axes.append("g");
axisLeft(y).tickSize(margin.left - width - margin.right)(yAxis);
yAxis.selectAll(".domain").remove();
svg
.append("g")
.attr("shape-rendering", "crispEdges")
.selectAll("rect")
.data(supported)
.join("rect")
.attr("x", (d) => x(d.releaseDate))
.attr("y", (d) => y(d.version)!)
.attr("width", (d) => x(d.endDate) - x(d.releaseDate))
.attr("height", y.bandwidth())
.attr("fill", (d, i) => (i % 2 === 0 ? "#3178C6" : "#235A97"));
const texts = svg
.append("g")
.attr("fill", "#FFFFFF")
.attr("text-anchor", "middle")
.attr("transform", `translate(0,${y.bandwidth() / 2})`);
texts
.append("g")
.attr("font-weight", "bold")
.selectAll("a")
.data(supported)
.join("a")
.attr(
"href",
(d) =>
`https://www.typescriptlang.org/docs/handbook/release-notes/typescript-${d.version.replace(
/[^0-9]+/,
"-"
)}.html`
)
.attr("fill", "#FFFFFF")
.append("text")
.attr("x", (d) => x(d.releaseDate) + (x(d.endDate) - x(d.releaseDate)) / 2)
.attr("y", (d) => y(d.version)!)
.attr("dy", "0.35em")
.text((d) => d.version);
texts
.append("g")
.attr("font-size", "0.8em")
.selectAll("text")
.data(supported)
.join("text")
.attr("x", (d) => x(d.releaseDate) + (x(d.endDate) - x(d.releaseDate)) / 4)
.attr("y", (d) => y(d.version)!)
.attr("dy", "0.35em")
.text((d) => formatDate(d.releaseDate));
texts
.append("g")
.attr("font-size", "0.8em")
.selectAll("text")
.data(supported)
.join("text")
.attr(
"x",
(d) => x(d.releaseDate) + ((x(d.endDate) - x(d.releaseDate)) * 3) / 4
)
.attr("y", (d) => y(d.version)!)
.attr("dy", "0.35em")
.text((d) => formatDate(d.endDate));
process.stdout.write(serialize(svg.node()!));

View File

@@ -1,15 +1,16 @@
{
"exclude": ["fix-tslint.ts", "update-config"],
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"module": "commonjs",
"target": "es6",
"strict": true,
"baseUrl": "../types",
"moduleResolution": "node",
"resolveJsonModule": true,
"typeRoots": [
"../types"
],
"types": [],
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true
}
}