Skip to content

Commit

Permalink
fix: type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
Kati-dev-hu committed Mar 21, 2021
1 parent 05e9cc1 commit 0cda284
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 44 deletions.
60 changes: 57 additions & 3 deletions src/chart_types/wordcloud/layout/types/viewmodel_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,51 @@ export interface WordModel {
color: Color;
}

/** @public */
export type WeightFun = 'log' | 'linear' | 'exponential' | 'squareRoot';

/** @internal */
export interface Word {
color: string;
font: string;
fontFamily: string;
fontWeight: number;
hasText: boolean;
height: number;
padding: number;
rotate: number;
size: number;
style: string;
text: string;
weight: number;
x: number;
x0: number;
x1: number;
xoff: number;
y: number;
y0: number;
y1: number;
yoff: number;
}

/** @internal */
export interface Configs {
count: number;
endAngle: number;
exponent: number;
fontFamily: string;
fontStyle: string;
fontWeight: number;
height: number;
maxFontSize: number;
minFontSize: number;
padding: number;
spiral: string;
startAngle: number;
weightFun: WeightFun;
width: number;
}

/** @internal */
export interface WordcloudViewModel {
startAngle: number;
Expand All @@ -44,7 +89,16 @@ export interface WordcloudViewModel {
spiral: string;
exponent: number;
data: WordModel[];
weightFun: string;
weightFun: WeightFun;
// specType: string;
}

/** @internal */
export interface Datum {
text: string;
weight: number;
color: string;
fontFamily: string;
}

/** @internal */
Expand All @@ -58,7 +112,7 @@ export type ShapeViewModel = {
pickQuads: PickFunction;
};

const commonDefaults = {
const commonDefaults: WordcloudViewModel = {
specType: SpecTypes.Series,
startAngle: -20,
endAngle: 20,
Expand All @@ -81,7 +135,7 @@ export const defaultWordcloudSpec = {
};

/** @internal */
export const nullWordcloudViewModel = {
export const nullWordcloudViewModel: WordcloudViewModel = {
...commonDefaults,
data: [],
};
Expand Down
2 changes: 1 addition & 1 deletion src/chart_types/wordcloud/layout/viewmodel/viewmodel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function shapeViewModel(textMeasure: TextMeasure, spec: WordcloudSpec, co
return {
config,
chartCenter,
wordcloudViewModel: wordcloudViewModel,
wordcloudViewModel,
pickQuads,
};
}
55 changes: 27 additions & 28 deletions src/chart_types/wordcloud/renderer/svg/connected_component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,38 @@ import { GlobalChartState } from '../../../../state/chart_state';
import { getInternalIsInitializedSelector, InitStatus } from '../../../../state/selectors/get_internal_is_intialized';
import { Dimensions } from '../../../../utils/dimensions';
import { Logger } from '../../../../utils/logger';
import { nullShapeViewModel, ShapeViewModel } from '../../layout/types/viewmodel_types';
import { Configs, Datum, nullShapeViewModel, ShapeViewModel, Word } from '../../layout/types/viewmodel_types';
import { geometries } from '../../state/selectors/geometries';

function seed() {
return 0.5;
}

function getFont(d) {
function getFont(d: Word) {
return d.fontFamily;
}

function getFontStyle(d) {
function getFontStyle(d: Word) {
return d.style;
}

function getFontWeight(d) {
function getFontWeight(d: Word) {
return d.fontWeight;
}

function getWidth(conf) {
function getWidth(conf: Configs) {
return conf.width ?? 500;
}

function getHeight(conf) {
function getHeight(conf: Configs) {
return conf.height ?? 500;
}

function getFontSize(d) {
function getFontSize(d: Word) {
return d.size;
}

function hashWithinRange(str, max) {
function hashWithinRange(str: string, max: number) {
str = JSON.stringify(str);
let hash = 0;
for (const ch of str) {
Expand All @@ -68,7 +68,7 @@ function hashWithinRange(str, max) {
return Math.abs(hash) % max;
}

function getRotation(startAngle, endAngle, count, text) {
function getRotation(startAngle: number, endAngle: number, count: number, text: string) {
const angleRange = endAngle - startAngle;
const angleCount = count ?? 360;
const interval = count - 1;
Expand All @@ -77,56 +77,56 @@ function getRotation(startAngle, endAngle, count, text) {
return index * angleStep + startAngle;
}

function exponential(minFontSize, maxFontSize, exponent, weight) {
function exponential(minFontSize: number, maxFontSize: number, exponent: number, weight: number) {
return minFontSize + (maxFontSize - minFontSize) * weight ** exponent;
}

function linear(minFontSize, maxFontSize, _exponent, weight) {
function linear(minFontSize: number, maxFontSize: number, _exponent: number, weight: number) {
return minFontSize + (maxFontSize - minFontSize) * weight;
}

function squareRoot(minFontSize, maxFontSize, _exponent, weight) {
function squareRoot(minFontSize: number, maxFontSize: number, _exponent: number, weight: number) {
return minFontSize + (maxFontSize - minFontSize) * Math.sqrt(weight);
}

function log(minFontSize, maxFontSize, _exponent, weight) {
function log(minFontSize: number, maxFontSize: number, _exponent: number, weight: number) {
return minFontSize + (maxFontSize - minFontSize) * Math.log2(weight + 1);
}

const weightFunLookup = { linear, exponential, log, squareRoot };

function layoutMaker(config, data) {
function layoutMaker(config: Configs, data: Datum[]) {
const words = data.map((d) => {
const weightFun = weightFunLookup[config.weightFun];
return {
text: d.text,
color: d.color,
fontFamily: config.fontFamily ?? 'Impact',
style: config.fontStyle ?? 'normal',
fontWeight: config.fontWeight ?? 'normal',
fontFamily: config.fontFamily,
style: config.fontStyle,
fontWeight: config.fontWeight,
size: weightFun(config.minFontSize, config.maxFontSize, config.exponent, d.weight),
};
});

return d3TagCloud()
.random(seed)
.size([getWidth(config), getHeight(config)])
.words(words)
.spiral(config.spiral ?? 'archimedean')
.padding(config.padding ?? 5)
.rotate((d) => getRotation(config.startAngle, config.endAngle, config.count, d.text))
.rotate((d: Word) => getRotation(config.startAngle, config.endAngle, config.count, d.text))
.font(getFont)
.fontStyle(getFontStyle)
.fontWeight(getFontWeight)
.fontSize((d) => getFontSize(d));
.fontSize((d: Word) => getFontSize(d));
}

const View = ({ words, conf }) => (
const View = ({ words, conf }: { words: Word[]; conf: Configs }) => (
<svg width={getWidth(conf)} height={getHeight(conf)}>
<g transform={`translate(${getWidth(conf) / 2}, ${getHeight(conf) / 2})`}>
{words.map((d) => {
{words.map((d, i) => {
return (
<text
key={String(i)}
style={{
transform: `translate(${d.x}, ${d.y}) rotate(${d.rotate})`,
fontSize: getFontSize(d),
Expand All @@ -135,7 +135,7 @@ const View = ({ words, conf }) => (
fontWeight: getFontWeight(d),
fill: d.color,
}}
textAnchor={'middle'}
textAnchor="middle"
transform={`translate(${d.x}, ${d.y}) rotate(${d.rotate})`}
>
{d.text}
Expand Down Expand Up @@ -227,7 +227,7 @@ class Component extends React.Component<Props> {
if (!initialized || width === 0 || height === 0) {
return null;
}
const conf1 = {
const conf1: Configs = {
width,
height,
startAngle: wordcloudViewModel.startAngle,
Expand All @@ -247,15 +247,14 @@ class Component extends React.Component<Props> {
const layout = layoutMaker(conf1, wordcloudViewModel.data);

let ww;
layout.on('end', (w) => (ww = w)).start();
layout.on('end', (w: Word[]) => (ww = w)).start();

const wordCount = wordcloudViewModel.data.length;
const renderedWordCount = ww.length;
const renderedWordCount: number = ((ww as unknown) as Word[]).length;
const notAllWordsFit = wordCount !== renderedWordCount;
if (notAllWordsFit) {
Logger.warn(`Not all words have been placed: ${renderedWordCount} words rendered out of ${wordCount}`);
}

return (
<>
<canvas
Expand All @@ -269,7 +268,7 @@ class Component extends React.Component<Props> {
height,
}}
/>
<View words={ww} conf={conf1} />
<View words={(ww as unknown) as Word[]} conf={conf1} />
</>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/chart_types/wordcloud/specs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { Spec } from '../../../specs';
import { SpecTypes } from '../../../specs/constants';
import { getConnect, specComponentFactory } from '../../../state/spec_factory';
import { config } from '../layout/config/config';
import { WordModel, defaultWordcloudSpec } from '../layout/types/viewmodel_types';
import { WordModel, defaultWordcloudSpec, WeightFun } from '../layout/types/viewmodel_types';

const defaultProps = {
chartType: ChartTypes.Wordcloud,
Expand All @@ -48,7 +48,7 @@ export interface WordcloudSpec extends Spec {
spiral: string;
exponent: number;
data: WordModel[];
weightFun: string;
weightFun: WeightFun;
}

type SpecRequiredProps = Pick<WordcloudSpec, 'id'>;
Expand Down
32 changes: 22 additions & 10 deletions stories/wordcloud/1_wordcloud.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,29 @@ const text =
const getRandomNumber = getRandomNumberGenerator();

const palettes = {
turquoise: (d, i) => ['#5bc0be', '#6fffe9'][i % 2],
vivid: (d, i) => ['#2ec4b6', '#e71d36', '#ff9f1c'][i % 3],
warm: (d, i) => ['#edc951', '#eb6841', '#cc2a36', '#4f372d', '#00a0b0'][i % 5],
turquoise: (d: RawDatum, i: number) => ['#5bc0be', '#6fffe9'][i % 2],
vivid: (d: RawDatum, i: number) => ['#2ec4b6', '#e71d36', '#ff9f1c'][i % 3],
warm: (d: RawDatum, i: number) => ['#edc951', '#eb6841', '#cc2a36', '#4f372d', '#00a0b0'][i % 5],
greenBlues: () => `rgb(${getRandomNumber(0, 10)}, ${getRandomNumber(50, 100)}, ${getRandomNumber(50, 100)})`,
redBlue: () => `rgb(${getRandomNumber(100, 255)},${0},${getRandomNumber(100, 255)})`,
greyScale: () => {
const level = getRandomNumber(0, 200);
return `rgb(${level},${level},${level})`;
},
weight: (d) => {
weight: (d: RawDatum) => {
const level = (1 - d.weight ** 15) * 200;
return `rgb(${level},${level},${level})`;
},
colorByWordLength: (d) => {
colorByWordLength: (d: RawDatum) => {
const level = d.text.length;
return `rgb(${level < 5 ? level * 60 : level < 7 ? level * 40 : level * 25},${
level < 5 ? level * 5 : level < 7 ? level * 10 : level * 5
},${level < 5 ? level * 25 : level < 7 ? level * 40 : level * 15})`;
},
euiLight: (d, i) => {
euiLight: (d: RawDatum, i: number) => {
return euiPalettes.echPaletteForLightBackground.colors[i % euiPalettes.echPaletteForLightBackground.colors.length];
},
euiColorBlind: (d, i) => {
euiColorBlind: (d: RawDatum, i: number) => {
return euiPalettes.echPaletteColorBlind.colors[i % euiPalettes.echPaletteColorBlind.colors.length];
},
};
Expand Down Expand Up @@ -189,7 +189,12 @@ const rawData = text
};
});

function data(text: string, paletteName: string): WordModel[] {
interface RawDatum {
text: string;
weight: number;
}

function sampleData(text: string, paletteName: keyof typeof palettes): WordModel[] {
return rawData.map(function (d, i) {
return {
...d,
Expand Down Expand Up @@ -238,12 +243,19 @@ export const Example = () => {
? startConfig.fontFamily
: select(
'fontFamily',
{ Arial: 'Arial', 'Arial Narrow': 'Arial Narrow', Courier: 'Courier', Impact: 'Impact', Luminari: 'Luminari' },
{
Arial: 'Arial',
'Arial Narrow': 'Arial Narrow',
Courier: 'Courier',
Impact: 'Impact',
Luminari: 'Luminari',
},
startConfig.fontFamily,
);
const fontStyle = template
? startConfig.fontStyle
: select('fontStyle', { normal: 'normal', italic: 'italic' }, startConfig.fontStyle);

const palette = template
? startConfig.palette
: select(
Expand Down Expand Up @@ -279,7 +291,7 @@ export const Example = () => {
maxFontSize={maxFontSize}
spiral={spiral}
exponent={exponent}
data={data(text, palette)}
data={sampleData(text, palette as keyof typeof palettes)}
weightFun={weightFun}
/>
</Chart>
Expand Down

0 comments on commit 0cda284

Please sign in to comment.