mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
feat(charts): remove on dialog close
This commit is contained in:
parent
eded296b47
commit
6cd2419f10
8 changed files with 90 additions and 56 deletions
|
|
@ -7822,8 +7822,8 @@
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></script>
|
<script defer src="modules/relief-icons.js"></script>
|
||||||
<script defer src="modules/ui/style.js"></script>
|
<script defer src="modules/ui/style.js"></script>
|
||||||
<script defer src="modules/ui/editors.js?v=1.87.00"></script>
|
<script defer src="modules/ui/editors.js?v=1.87.01"></script>
|
||||||
<script defer src="modules/ui/tools.js?v=1.87.00"></script>
|
<script defer src="modules/ui/tools.js?v=1.87.01"></script>
|
||||||
<script defer src="modules/ui/world-configurator.js"></script>
|
<script defer src="modules/ui/world-configurator.js"></script>
|
||||||
<script defer src="modules/ui/heightmap-editor.js"></script>
|
<script defer src="modules/ui/heightmap-editor.js"></script>
|
||||||
<script defer src="modules/ui/provinces-editor.js"></script>
|
<script defer src="modules/ui/provinces-editor.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -630,7 +630,7 @@ function togglePercentageMode() {
|
||||||
|
|
||||||
async function showHierarchy() {
|
async function showHierarchy() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const HeirarchyTree = await import("../hierarchy-tree.js?v=1.87.00");
|
const HeirarchyTree = await import("../hierarchy-tree.js?v=1.87.01");
|
||||||
|
|
||||||
const getDescription = culture => {
|
const getDescription = culture => {
|
||||||
const {name, type, rural, urban} = culture;
|
const {name, type, rural, urban} = culture;
|
||||||
|
|
|
||||||
|
|
@ -533,7 +533,7 @@ function togglePercentageMode() {
|
||||||
|
|
||||||
async function showHierarchy() {
|
async function showHierarchy() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const HeirarchyTree = await import("../hierarchy-tree.js?v=1.87.00");
|
const HeirarchyTree = await import("../hierarchy-tree.js?v=1.87.01");
|
||||||
|
|
||||||
const getDescription = religion => {
|
const getDescription = religion => {
|
||||||
const {name, type, form, rural, urban} = religion;
|
const {name, type, form, rural, urban} = religion;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ let getDescription; // dataElement => string
|
||||||
let getShape; // dataElement => string;
|
let getShape; // dataElement => string;
|
||||||
|
|
||||||
export function open(props) {
|
export function open(props) {
|
||||||
closeDialogs(".stable");
|
closeDialogs("#hierarchyTree, .stable");
|
||||||
|
|
||||||
dataElements = props.data;
|
dataElements = props.data;
|
||||||
dataElements[0].origins = [null];
|
dataElements[0].origins = [null];
|
||||||
|
|
@ -145,7 +145,7 @@ function appendStyleSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertHtml() {
|
function insertHtml() {
|
||||||
const html = /* html */ `<div id="hierarchyTree" style="overflow: hidden;">
|
const html = /* html */ `<div id="hierarchyTree" class="dialog" style="overflow: hidden;">
|
||||||
<svg>
|
<svg>
|
||||||
<g id="hierarchyTree_viewbox" style="text-anchor: middle; dominant-baseline: central">
|
<g id="hierarchyTree_viewbox" style="text-anchor: middle; dominant-baseline: central">
|
||||||
<g transform="translate(10, -45)">
|
<g transform="translate(10, -45)">
|
||||||
|
|
|
||||||
|
|
@ -3,35 +3,35 @@ import {rollups} from "../../../utils/functionUtils.js";
|
||||||
const entitiesMap = {
|
const entitiesMap = {
|
||||||
states: {
|
states: {
|
||||||
label: "State",
|
label: "State",
|
||||||
cellsData: pack.cells.state,
|
getCellsData: () => pack.cells.state,
|
||||||
getName: nameGetter("states"),
|
getName: nameGetter("states"),
|
||||||
getColors: colorsGetter("states"),
|
getColors: colorsGetter("states"),
|
||||||
landOnly: true
|
landOnly: true
|
||||||
},
|
},
|
||||||
cultures: {
|
cultures: {
|
||||||
label: "Culture",
|
label: "Culture",
|
||||||
cellsData: pack.cells.culture,
|
getCellsData: () => pack.cells.culture,
|
||||||
getName: nameGetter("cultures"),
|
getName: nameGetter("cultures"),
|
||||||
getColors: colorsGetter("cultures"),
|
getColors: colorsGetter("cultures"),
|
||||||
landOnly: true
|
landOnly: true
|
||||||
},
|
},
|
||||||
religions: {
|
religions: {
|
||||||
label: "Religion",
|
label: "Religion",
|
||||||
cellsData: pack.cells.religion,
|
getCellsData: () => pack.cells.religion,
|
||||||
getName: nameGetter("religions"),
|
getName: nameGetter("religions"),
|
||||||
getColors: colorsGetter("religions"),
|
getColors: colorsGetter("religions"),
|
||||||
landOnly: true
|
landOnly: true
|
||||||
},
|
},
|
||||||
provinces: {
|
provinces: {
|
||||||
label: "Province",
|
label: "Province",
|
||||||
cellsData: pack.cells.province,
|
getCellsData: () => pack.cells.province,
|
||||||
getName: nameGetter("provinces"),
|
getName: nameGetter("provinces"),
|
||||||
getColors: colorsGetter("provinces"),
|
getColors: colorsGetter("provinces"),
|
||||||
landOnly: true
|
landOnly: true
|
||||||
},
|
},
|
||||||
biomes: {
|
biomes: {
|
||||||
label: "Biome",
|
label: "Biome",
|
||||||
cellsData: pack.cells.biome,
|
getCellsData: () => pack.cells.biome,
|
||||||
getName: biomeNameGetter,
|
getName: biomeNameGetter,
|
||||||
getColors: biomeColorsGetter,
|
getColors: biomeColorsGetter,
|
||||||
landOnly: false
|
landOnly: false
|
||||||
|
|
@ -199,15 +199,30 @@ const plotTypeMap = {
|
||||||
normalizedStackedBar: {offset: d3.stackOffsetExpand, formatX: value => rn(value * 100) + "%"}
|
normalizedStackedBar: {offset: d3.stackOffsetExpand, formatX: value => rn(value * 100) + "%"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let charts = []; // store charts data
|
||||||
|
let prevMapId = mapId;
|
||||||
|
|
||||||
appendStyleSheet();
|
appendStyleSheet();
|
||||||
insertHtml();
|
insertHtml();
|
||||||
addListeners();
|
addListeners();
|
||||||
changeViewColumns();
|
changeViewColumns();
|
||||||
|
|
||||||
export function open() {
|
export function open() {
|
||||||
const charts = byId("chartsOverview__charts").childElementCount;
|
closeDialogs("#chartsOverview, .stable");
|
||||||
if (!charts) renderChart();
|
|
||||||
$("#chartsOverview").dialog({title: "Data Charts"});
|
if (prevMapId !== mapId) {
|
||||||
|
charts = [];
|
||||||
|
prevMapId = mapId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!charts.length) addChart();
|
||||||
|
else charts.forEach(chart => renderChart(chart));
|
||||||
|
|
||||||
|
$("#chartsOverview").dialog({
|
||||||
|
title: "Data Charts",
|
||||||
|
position: {my: "center", at: "center", of: "svg"},
|
||||||
|
close: handleClose
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendStyleSheet() {
|
function appendStyleSheet() {
|
||||||
|
|
@ -267,25 +282,25 @@ function insertHtml() {
|
||||||
const createOption = ([value, label]) => `<option value="${value}">${label}</option>`;
|
const createOption = ([value, label]) => `<option value="${value}">${label}</option>`;
|
||||||
const createOptions = values => values.map(createOption).join("");
|
const createOptions = values => values.map(createOption).join("");
|
||||||
|
|
||||||
const html = /* html */ `<div id="chartsOverview">
|
const html = /* html */ `<div id="chartsOverview" class="dialog">
|
||||||
<form id="chartsOverview__form">
|
<form id="chartsOverview__form">
|
||||||
<div>
|
<div>
|
||||||
<button data-tip="Add a chart" type="submit">Plot</button>
|
<button data-tip="Add a chart" type="submit">Plot</button>
|
||||||
|
|
||||||
<select data-tip="Select entity (y axis)" id="chartsOverview__entitiesSelect">${createOptions(
|
<select data-tip="Select entity (y axis)" id="chartsOverview__entitiesSelect">
|
||||||
entities
|
${createOptions(entities)}
|
||||||
)}</select>
|
</select>
|
||||||
|
|
||||||
<label>by
|
<label>by
|
||||||
<select data-tip="Select value to plot by (x axis)" id="chartsOverview__plotBySelect">${createOptions(
|
<select data-tip="Select value to plot by (x axis)" id="chartsOverview__plotBySelect">
|
||||||
plotBy
|
${createOptions(plotBy)}
|
||||||
)}</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>grouped by
|
<label>grouped by
|
||||||
<select data-tip="Select entoty to group by. If you don't need grouping, set it the same as the entity" id="chartsOverview__groupBySelect">${createOptions(
|
<select data-tip="Select entoty to group by. If you don't need grouping, set it the same as the entity" id="chartsOverview__groupBySelect">
|
||||||
entities
|
${createOptions(entities)}
|
||||||
)}</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label data-tip="Sorting type">sorted
|
<label data-tip="Sorting type">sorted
|
||||||
|
|
@ -325,11 +340,11 @@ function insertHtml() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addListeners() {
|
function addListeners() {
|
||||||
byId("chartsOverview__form").on("submit", renderChart);
|
byId("chartsOverview__form").on("submit", addChart);
|
||||||
byId("chartsOverview__viewColumns").on("change", changeViewColumns);
|
byId("chartsOverview__viewColumns").on("change", changeViewColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderChart(event) {
|
function addChart(event) {
|
||||||
if (event) event.preventDefault();
|
if (event) event.preventDefault();
|
||||||
|
|
||||||
const entity = byId("chartsOverview__entitiesSelect").value;
|
const entity = byId("chartsOverview__entitiesSelect").value;
|
||||||
|
|
@ -338,30 +353,41 @@ function renderChart(event) {
|
||||||
const sorting = byId("chartsOverview__sortingSelect").value;
|
const sorting = byId("chartsOverview__sortingSelect").value;
|
||||||
const type = byId("chartsOverview__chartType").value;
|
const type = byId("chartsOverview__chartType").value;
|
||||||
|
|
||||||
const {
|
const {stackable} = quantizationMap[plotBy];
|
||||||
label: plotByLabel,
|
|
||||||
stringify,
|
|
||||||
quantize,
|
|
||||||
aggregate,
|
|
||||||
formatTicks,
|
|
||||||
stackable,
|
|
||||||
landOnly: plotByLandOnly
|
|
||||||
} = quantizationMap[plotBy];
|
|
||||||
|
|
||||||
if (!stackable && groupBy !== entity) {
|
if (!stackable && groupBy !== entity) {
|
||||||
tip(`Grouping is not supported for ${plotByLabel}`, false, "warn", 4000);
|
tip(`Grouping is not supported for ${plotByLabel}`, false, "warn", 4000);
|
||||||
groupBy = entity;
|
groupBy = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chartOptions = {id: Date.now(), entity, plotBy, groupBy, sorting, type};
|
||||||
|
charts.push(chartOptions);
|
||||||
|
renderChart(chartOptions);
|
||||||
|
updateDialogPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChart({id, entity, plotBy, groupBy, sorting, type}) {
|
||||||
|
const {
|
||||||
|
label: plotByLabel,
|
||||||
|
stringify,
|
||||||
|
quantize,
|
||||||
|
aggregate,
|
||||||
|
formatTicks,
|
||||||
|
landOnly: plotByLandOnly
|
||||||
|
} = quantizationMap[plotBy];
|
||||||
|
|
||||||
const noGrouping = groupBy === entity;
|
const noGrouping = groupBy === entity;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
label: entityLabel,
|
label: entityLabel,
|
||||||
getName: getEntityName,
|
getName: getEntityName,
|
||||||
cellsData: entityCells,
|
getCellsData: getEntityCellsData,
|
||||||
landOnly: entityLandOnly
|
landOnly: entityLandOnly
|
||||||
} = entitiesMap[entity];
|
} = entitiesMap[entity];
|
||||||
const {label: groupLabel, getName: getGroupName, cellsData: groupCells, getColors} = entitiesMap[groupBy];
|
const {label: groupLabel, getName: getGroupName, getCellsData: getGroupCellsData, getColors} = entitiesMap[groupBy];
|
||||||
|
|
||||||
|
const entityCells = getEntityCellsData();
|
||||||
|
const groupCells = getGroupCellsData();
|
||||||
|
|
||||||
const title = `${capitalize(entity)} by ${plotByLabel}${noGrouping ? "" : " grouped by " + groupLabel}`;
|
const title = `${capitalize(entity)} by ${plotByLabel}${noGrouping ? "" : " grouped by " + groupLabel}`;
|
||||||
|
|
||||||
|
|
@ -403,11 +429,10 @@ function renderChart(event) {
|
||||||
const colors = getColors();
|
const colors = getColors();
|
||||||
const {offset, formatX = formatTicks} = plotTypeMap[type];
|
const {offset, formatX = formatTicks} = plotTypeMap[type];
|
||||||
|
|
||||||
const chart = createStackedBarChart(chartData, {sorting, colors, tooltip, offset, formatX});
|
const $chart = createStackedBarChart(chartData, {sorting, colors, tooltip, offset, formatX});
|
||||||
insertChart(chart, title);
|
insertChart(id, $chart, title);
|
||||||
|
|
||||||
byId("chartsOverview__charts").lastChild.scrollIntoView();
|
byId("chartsOverview__charts").lastChild.scrollIntoView();
|
||||||
updateDialog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// based on observablehq.com/@d3/stacked-horizontal-bar-chart
|
// based on observablehq.com/@d3/stacked-horizontal-bar-chart
|
||||||
|
|
@ -543,7 +568,7 @@ function createStackedBarChart(data, {sorting, colors, tooltip, offset, formatX}
|
||||||
return svg.node();
|
return svg.node();
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertChart(chart, title) {
|
function insertChart(id, $chart, title) {
|
||||||
const $chartContainer = byId("chartsOverview__charts");
|
const $chartContainer = byId("chartsOverview__charts");
|
||||||
|
|
||||||
const $figure = document.createElement("figure");
|
const $figure = document.createElement("figure");
|
||||||
|
|
@ -560,18 +585,19 @@ function insertChart(chart, title) {
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
$figure.appendChild(chart);
|
$figure.appendChild($chart);
|
||||||
$figure.appendChild($caption);
|
$figure.appendChild($caption);
|
||||||
$chartContainer.appendChild($figure);
|
$chartContainer.appendChild($figure);
|
||||||
|
|
||||||
const downloadChart = () => {
|
const downloadChart = () => {
|
||||||
const name = `${getFileName(title)}.svg`;
|
const name = `${getFileName(title)}.svg`;
|
||||||
downloadFile(chart.outerHTML, name);
|
downloadFile($chart.outerHTML, name);
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeChart = () => {
|
const removeChart = () => {
|
||||||
$figure.remove();
|
$figure.remove();
|
||||||
updateDialog();
|
charts = charts.filter(chart => chart.id !== id);
|
||||||
|
updateDialogPosition();
|
||||||
};
|
};
|
||||||
|
|
||||||
$figure.querySelector("button.icon-download").on("click", downloadChart);
|
$figure.querySelector("button.icon-download").on("click", downloadChart);
|
||||||
|
|
@ -582,13 +608,19 @@ function changeViewColumns() {
|
||||||
const columns = byId("chartsOverview__viewColumns").value;
|
const columns = byId("chartsOverview__viewColumns").value;
|
||||||
const $charts = byId("chartsOverview__charts");
|
const $charts = byId("chartsOverview__charts");
|
||||||
$charts.style.gridTemplateColumns = `repeat(${columns}, 1fr)`;
|
$charts.style.gridTemplateColumns = `repeat(${columns}, 1fr)`;
|
||||||
updateDialog();
|
updateDialogPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDialog() {
|
function updateDialogPosition() {
|
||||||
$("#chartsOverview").dialog({position: {my: "center", at: "center", of: "svg"}});
|
$("#chartsOverview").dialog({position: {my: "center", at: "center", of: "svg"}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
const $chartContainer = byId("chartsOverview__charts");
|
||||||
|
$chartContainer.innerHTML = "";
|
||||||
|
$("#chartsOverview").dialog("destroy");
|
||||||
|
}
|
||||||
|
|
||||||
// config
|
// config
|
||||||
const NEUTRAL_COLOR = "#ccc";
|
const NEUTRAL_COLOR = "#ccc";
|
||||||
const EMPTY_NAME = "no";
|
const EMPTY_NAME = "no";
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,13 @@ function unselect() {
|
||||||
|
|
||||||
// close all dialogs except stated
|
// close all dialogs except stated
|
||||||
function closeDialogs(except = "#except") {
|
function closeDialogs(except = "#except") {
|
||||||
$(".dialog:visible")
|
try {
|
||||||
.not(except)
|
$(".dialog:visible")
|
||||||
.each(function () {
|
.not(except)
|
||||||
$(this).dialog("close");
|
.each(function () {
|
||||||
});
|
$(this).dialog("close");
|
||||||
|
});
|
||||||
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move brush radius circle
|
// move brush radius circle
|
||||||
|
|
@ -1155,7 +1157,7 @@ function confirmationDialog(options) {
|
||||||
// add and register event listeners to clean up on editor closure
|
// add and register event listeners to clean up on editor closure
|
||||||
function listen(element, event, handler) {
|
function listen(element, event, handler) {
|
||||||
element.on(event, handler);
|
element.on(event, handler);
|
||||||
return () => element.removeEventListener(event, handler);
|
return () => element.off(event, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls the refresh functionality on all editors currently open.
|
// Calls the refresh functionality on all editors currently open.
|
||||||
|
|
@ -1180,12 +1182,12 @@ async function editStates() {
|
||||||
|
|
||||||
async function editCultures() {
|
async function editCultures() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const Editor = await import("../dynamic/editors/cultures-editor.js?v=1.87.00");
|
const Editor = await import("../dynamic/editors/cultures-editor.js?v=1.87.01");
|
||||||
Editor.open();
|
Editor.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editReligions() {
|
async function editReligions() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
const Editor = await import("../dynamic/editors/religions-editor.js?v=1.87.00");
|
const Editor = await import("../dynamic/editors/religions-editor.js?v=1.87.01");
|
||||||
Editor.open();
|
Editor.open();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -858,6 +858,6 @@ function viewCellDetails() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function overviewCharts() {
|
async function overviewCharts() {
|
||||||
const Overview = await import("../dynamic/overview/charts-overview.js");
|
const Overview = await import("../dynamic/overview/charts-overview.js?v=1.87.01");
|
||||||
Overview.open();
|
Overview.open();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
// version and caching control
|
// version and caching control
|
||||||
|
|
||||||
const version = "1.87.00"; // generator version, update each time
|
const version = "1.87.01"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue