feat: support resize cell height and width (#55)

This commit is contained in:
vran 2024-02-02 23:06:48 +08:00 committed by GitHub
parent 6d6f582593
commit a985b8a99d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 198 additions and 26 deletions

View file

@ -1,6 +1,9 @@
import { Local } from "./types";
export class En implements Local {
default = "default";
click_to_reset = "click to reset";
/**
* context menu
*/
@ -13,8 +16,8 @@ export class En implements Local {
form_style_settings = "Style Settings";
form_about = "About";
form_contact_me = "Contact me";
form_project_url = "Project";
form_sponsor = "Sponsor";
form_project_url = "Project";
form_sponsor = "Sponsor";
form_title = "Title";
form_title_placeholder = "Input title";
form_graph_type = "Graph Type";
@ -24,7 +27,7 @@ export class En implements Local {
form_date_range = "Date Range";
form_date_range_latest_days = "Latest Days";
form_date_range_latest_month = "Latest Whole Month";
form_date_range_latest_year = "Latest Whole Year";
form_date_range_latest_year = "Latest Whole Year";
form_date_range_latest_days_placeholder = "Input days";
form_date_range_fixed_date = "Fixed Date";
form_date_range_start_date = "Start Date";
@ -78,15 +81,17 @@ export class En implements Local {
form_count_field_count_field_type_task_prop = "Task Property";
form_title_font_size_label = "Title font Size";
form_number_input_min_warning = "allow min value is {value}";
form_number_input_max_warning = "allow max value is {value}";
form_number_input_max_warning = "allow max value is {value}";
form_fill_the_screen_label = "Fill The Screen";
form_main_container_bg_color = "Background Color";
form_enable_main_container_shadow = "Enable Shadow";
form_enable_main_container_shadow = "Enable Shadow";
form_show_cell_indicators = "Show Cell Indicators";
form_cell_shape = "Cell Shape";
form_cell_shape_circle = "Circle";
form_cell_shape_square = "Square";
form_cell_shape_rounded = "Rounded";
form_cell_min_height = "Min Height";
form_cell_min_width = "Min Width";
form_datasource_type_page = "Page";
form_datasource_type_all_task = "All Task";

View file

@ -1,5 +1,8 @@
export interface Local {
default: string;
click_to_reset: string;
/**
* context menu
*/
@ -84,6 +87,8 @@ export interface Local {
form_cell_shape_circle: string;
form_cell_shape_square: string;
form_cell_shape_rounded: string;
form_cell_min_height: string;
form_cell_min_width: string;
form_datasource_type_page: string;
form_datasource_type_all_task: string;

View file

@ -1,6 +1,8 @@
import { Local } from "./types";
export class Zh implements Local {
default = "默认";
click_to_reset = "点击重置";
/**
* context menu
*/
@ -86,6 +88,8 @@ export class Zh implements Local {
form_cell_shape_circle = "圆形";
form_cell_shape_square = "方块";
form_cell_shape_rounded = "圆角";
form_cell_min_height = "单元格最小高度";
form_cell_min_width = "单元格最小宽度";
form_datasource_type_page = "文档";
form_datasource_type_all_task = "所有任务";

View file

@ -41,7 +41,7 @@ export class CalendarGraphRender extends BaseGraphRender {
this.renderCellRuleIndicator(graphConfig, main);
const activityContainer= this.renderActivityContainer(graphConfig, main);
const activityContainer = this.renderActivityContainer(graphConfig, main);
const contributionData = this.generateContributionData(
graphConfig
@ -130,6 +130,7 @@ export class CalendarGraphRender extends BaseGraphRender {
for (let i = 0; i < 7; i++) {
const dateIndicatorCell = document.createElement("div");
dateIndicatorCell.className = "cell week-indicator";
this.applyCellGlobalStylePartial(dateIndicatorCell, graphConfig, ['minWidth', 'minHeight']);
const weekText = localizedWeekDayMapping(
((graphConfig.startOfWeek || 0) + 7 + i) % 7,
2
@ -150,6 +151,7 @@ export class CalendarGraphRender extends BaseGraphRender {
for (let j = 0; j < distance; j++) {
const cellEl = document.createElement("div");
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
rowContainer?.appendChild(cellEl);
}
}
@ -170,6 +172,7 @@ export class CalendarGraphRender extends BaseGraphRender {
if (item.date == "$HOLE$") {
cellEl.innerText = "···";
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
} else if (item.value == 0) {
cellEl.className = "cell empty";
this.applyCellGlobalStyle(cellEl, graphConfig);
@ -194,6 +197,7 @@ export class CalendarGraphRender extends BaseGraphRender {
for (let j = 0; j < distance; j++) {
const cellEl = document.createElement("div");
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
rowContainer?.appendChild(cellEl);
}
}
@ -205,6 +209,7 @@ export class CalendarGraphRender extends BaseGraphRender {
for (let j = 0; j < distance; j++) {
const cellEl = document.createElement("div");
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
rowContainer?.appendChild(cellEl);
}
}

View file

@ -115,6 +115,7 @@ export class GitStyleTrackGraphRender extends BaseGraphRender {
this.bindCellAttribute(cellEl, contributionItem);
} else {
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
}
} else {
cellEl.className = "cell";

View file

@ -22,7 +22,7 @@ export interface GraphRender {
}
export abstract class BaseGraphRender implements GraphRender {
constructor() {}
constructor() { }
render(container: HTMLElement, graphConfig: ContributionGraphConfig): void {
throw new Error("Method not implemented.");
@ -221,9 +221,8 @@ export abstract class BaseGraphRender implements GraphRender {
contributionItem: ContributionCellData,
contributionMapByYearMonth: Map<string, number>
) {
const yearMonth = `${contributionItem.year}-${
contributionItem.month + 1
}`;
const yearMonth = `${contributionItem.year}-${contributionItem.month + 1
}`;
const yearMonthValue = contributionMapByYearMonth.get(yearMonth) || 0;
// tips event
setTooltip(
@ -241,6 +240,21 @@ export abstract class BaseGraphRender implements GraphRender {
}
}
applyCellGlobalStylePartial(
cellEl: HTMLElement,
graphConfig: ContributionGraphConfig,
props: string[]
) {
if (graphConfig.cellStyle) {
const partialStyle = props.reduce((acc, cur) => {
// @ts-ignore
acc[cur] = graphConfig.cellStyle[cur];
return acc;
}, {});
Object.assign(cellEl.style, partialStyle);
}
}
applyCellStyleRule(
cellEl: HTMLElement,
contributionItem: ContributionCellData,

View file

@ -46,10 +46,10 @@ export class MonthTrackGraphRender extends BaseGraphRender {
text: "",
})
);
this.renderMonthDateIndicator(dateIndicatorRow);
this.renderMonthDateIndicator(dateIndicatorRow, graphConfig);
const activityContainer = this.renderActivityContainer(graphConfig, main);
const activityContainer= this.renderActivityContainer(graphConfig, main);
const contributionData = this.generateContributionData(
graphConfig
).filter((item) => item.date != "$HOLE$");
@ -75,6 +75,7 @@ export class MonthTrackGraphRender extends BaseGraphRender {
for (let j = 0; j < fillMax; j++) {
const cellEl = document.createElement("div");
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
monthDataRowEl?.appendChild(cellEl);
}
}
@ -91,9 +92,9 @@ export class MonthTrackGraphRender extends BaseGraphRender {
monthIndicator.innerText =
contributionItem.month == 0
? localizedYearMonthMapping(
contributionItem.year,
contributionItem.month
)
contributionItem.year,
contributionItem.month
)
: localizedMonthMapping(contributionItem.month);
this.bindMonthTips(
@ -112,6 +113,7 @@ export class MonthTrackGraphRender extends BaseGraphRender {
const cellEl = document.createElement("div");
cellEl.className = "cell";
cellEl.innerText = "···";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
monthDataRowEl?.appendChild(cellEl);
}
}
@ -141,15 +143,17 @@ export class MonthTrackGraphRender extends BaseGraphRender {
for (let j = 0; j < fillMax; j++) {
const cellEl = document.createElement("div");
cellEl.className = "cell";
this.applyCellGlobalStylePartial(cellEl, graphConfig, ['minWidth', 'minHeight']);
monthDataRowEl?.appendChild(cellEl);
}
}
}
renderMonthDateIndicator(dateIndicatorRow: HTMLDivElement) {
renderMonthDateIndicator(dateIndicatorRow: HTMLDivElement, graphConfig: ContributionGraphConfig) {
for (let i = 0; i < 31; i++) {
const dateIndicatorCell = document.createElement("div");
dateIndicatorCell.className = "cell date-indicator";
this.applyCellGlobalStylePartial(dateIndicatorCell, graphConfig, ['minWidth', 'minHeight']);
dateIndicatorCell.innerText = `${i + 1}`;
dateIndicatorRow.appendChild(dateIndicatorCell);
}

View file

@ -21,7 +21,7 @@ import NumberInput from "../number-input";
import { ColorPicker } from "./ColorPicker";
import { About } from "../about";
export function CreateContributionGraphForm(props: {
export function GraphForm(props: {
yamlConfig: YamlGraphConfig;
onSubmit: (yamlGraphConfig: YamlGraphConfig) => void;
app: App;
@ -113,6 +113,17 @@ export function CreateContributionGraphForm(props: {
return 16;
};
const parseNumberFromPrefix = (
str: string | undefined,
defaultValue: number
): number => {
if (!str) {
return 0;
}
const numberStr = str.replace(/[^0-9]/, "") || "0";
return parseInt(numberStr);
};
return (
<>
<Tab
@ -515,6 +526,97 @@ export function CreateContributionGraphForm(props: {
</select>
</div>
</div>
<div className="form-item">
<span className="label">
{local.form_cell_min_width}
</span>
<div className="form-content">
<input
type="range"
min={4}
max={64}
defaultValue={parseNumberFromPrefix(
formData.cellStyle
?.minWidth,
8
)}
onChange={(e) => {
changeFormData(
"cellStyle",
{
...formData.cellStyle,
minWidth:
e.target.value +
"px",
}
);
}}
/>
<span
className="input-range-value-label"
onClick={(e) => {
changeFormData(
"cellStyle",
{
...formData.cellStyle,
minWidth: undefined,
}
);
}}
>
{formData.cellStyle?.minWidth
? formData.cellStyle
?.minWidth
: local.default}
</span>
</div>
</div>
<div className="form-item">
<span className="label">
{local.form_cell_min_height}
</span>
<div className="form-content">
<input
type="range"
min={4}
max={64}
defaultValue={parseNumberFromPrefix(
formData.cellStyle
?.minHeight,
8
)}
onChange={(e) => {
changeFormData(
"cellStyle",
{
...formData.cellStyle,
minHeight:
e.target.value +
"px",
}
);
}}
/>
<span
className="input-range-value-label"
onClick={(e) => {
changeFormData(
"cellStyle",
{
...formData.cellStyle,
minHeight:
undefined,
}
);
}}
>
{formData.cellStyle?.minHeight
? formData.cellStyle
?.minHeight
: local.default}
</span>
</div>
</div>
<div className="form-item">
<span className="label">
{local.form_theme}

View file

@ -1,7 +1,7 @@
import { Modal, App, MarkdownView, parseYaml, stringifyYaml } from "obsidian";
import { StrictMode } from "react";
import { Root, createRoot } from "react-dom/client";
import { CreateContributionGraphForm } from "./GraphForm";
import { GraphForm } from "./GraphForm";
import { YamlGraphConfig } from "src/processor/types";
import { YamlConfigReconciler } from "src/processor/yamlConfigReconciler";
@ -76,7 +76,7 @@ export class ContributionGraphCreateModal extends Modal {
this.root = createRoot(rootContainer);
this.root.render(
<StrictMode>
<CreateContributionGraphForm
<GraphForm
yamlConfig={yamlConfig}
onSubmit={onSubmit}
app={this.app}

View file

@ -64,7 +64,6 @@
align-items: flex-start;
flex-wrap: nowrap;
justify-content: flex-start;
}
.contribution-graph .main .charts.default .column {
@ -215,7 +214,11 @@
justify-content: center;
}
.contribution-graph .calendar .month-container .week-indicator-container .cell.week-indicator {
.contribution-graph
.calendar
.month-container
.week-indicator-container
.cell.week-indicator {
font-size: 0.6rem;
line-height: 1.5;
text-align: center;
@ -402,7 +405,10 @@
gap: 8px;
}
.contribution-graph-modal-form .form-item .form-vertical-content>input[type="text"] {
.contribution-graph-modal-form
.form-item
.form-vertical-content
> input[type="text"] {
flex-grow: 1;
border-width: 0px 0px 1px 0px;
padding: 3px;
@ -839,13 +845,22 @@
color: var(--text-muted);
}
.contribution-graph .activity-container .activity-content .activity-list .activity-item {
.contribution-graph
.activity-container
.activity-content
.activity-list
.activity-item {
display: flex;
flex-direction: row;
align-items: center;
}
.contribution-graph .activity-container .activity-content .activity-list .activity-item .label {
.contribution-graph
.activity-container
.activity-content
.activity-list
.activity-item
.label {
color: var(--text-muted);
padding: 0.4rem 0.6rem;
}
@ -858,7 +873,11 @@
width: 100%;
}
.contribution-graph .activity-container .activity-content .activity-navigation a {
.contribution-graph
.activity-container
.activity-content
.activity-navigation
a {
color: var(--text-muted);
text-decoration: none;
padding: 0.4rem 0.6rem;
@ -905,4 +924,17 @@
.about-container .about-item img {
max-width: 200px;
width: 200px;
}
.input-range-value-label {
font-size: 0.8rem;
color: var(--text-muted);
cursor: pointer;
padding: 4px;
border-radius: 4px;
}
.input-range-value-label:hover {
background: var(--interactive-accent);
color: var(--text-on-accent);
}