Skip to content

Commit

Permalink
Restore visualizer direction setting.
Browse files Browse the repository at this point in the history
  • Loading branch information
KirkMcDonald committed Oct 22, 2024
1 parent 3174c45 commit 0051f63
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 26 deletions.
11 changes: 8 additions & 3 deletions boxline2.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ function edgeName(link) {
return `link-${link.index}`
}

export function renderBoxGraph({nodes, links}, ignore, callback) {
export function renderBoxGraph({nodes, links}, direction, ignore, callback) {
let [itemColors, recipeColors] = getColorMaps(nodes, links)
if (direction === "down") {
direction = "TB"
} else {
direction = "LR"
}
let g = new dagre.graphlib.Graph({multigraph: true})
g.setGraph({rankdir: "TB"})
g.setGraph({rankdir: direction})
g.setDefaultEdgeLabel(() => {})

let testSVG = d3.select("body").append("svg").classed("test", true)
Expand Down Expand Up @@ -181,7 +186,7 @@ export function renderBoxGraph({nodes, links}, ignore, callback) {
.data(nodes)
.join("g")
.classed("node", true)
renderNode(rects, boxlineNodeMargin, recipeColors, ignore)
renderNode(rects, boxlineNodeMargin, "left", recipeColors, ignore)

svg.append("g")
.classed("overlay", true)
Expand Down
13 changes: 12 additions & 1 deletion calc.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
var handlers = {}
</script>
<script type="module">
import { plusHandler, clickTab, clickVisualize, changeTitle, changeRatePrecision, changeCountPrecision, changeFormat, changeMprod, changeVisType, changeVisRender, toggleDebug } from "./events.js"
import { plusHandler, clickTab, clickVisualize, changeTitle, changeRatePrecision, changeCountPrecision, changeFormat, changeMprod, changeVisType, changeVisRender, changeVisDir, toggleDebug } from "./events.js"
import { init } from "./init.js"
handlers.plusHandler = plusHandler
handlers.clickTab = clickTab
Expand All @@ -38,6 +38,7 @@
handlers.changeMprod = changeMprod
handlers.changeVisType = changeVisType
handlers.changeVisRender = changeVisRender
handlers.changeVisDir = changeVisDir
handlers.toggleDebug = toggleDebug
handlers.init = init
</script>
Expand Down Expand Up @@ -115,6 +116,16 @@
<label for="fix_render">Fixed</label>
</form>
</div>
<div class="graph_setting">
Graph direction:<br>
<form id="graph_direction">
<input id="right_direction" type="radio" name="direction" value="right" autocomplete="off" onchange="handlers.changeVisDir(event)">
<label for="right_direction">Left to right</label>

<input id="down_direction" type="radio" name="direction" value="down" autocomplete="off" onchange="handlers.changeVisDir(event)">
<label for="down_direction">Top to bottom</label>
</form>
</div>
<div id="graph_container">
<svg id="graph"><g /></svg>
</div>
Expand Down
25 changes: 25 additions & 0 deletions events.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export function setVisualizerType(vt) {

export function changeVisType(event) {
visualizerType = event.target.value
visualizerDirection = getDefaultVisDirection()
d3.select(`#${visualizerDirection}_direction`).property("checked", true)
spec.display()
}

Expand All @@ -109,6 +111,29 @@ export function changeVisRender(event) {
spec.display()
}

export let visualizerDirection

export function getDefaultVisDirection() {
if (visualizerType === "sankey") {
return "right"
} else {
return "down"
}
}

export function isDefaultVisDirection() {
return visualizerDirection === getDefaultVisDirection()
}

export function setVisualizerDirection(vd) {
visualizerDirection = vd
}

export function changeVisDir(event) {
visualizerDirection = event.target.value
spec.display()
}

// Number of SVG coordinate points per zoom level.
const ZOOM_SCALE = 100
// Number of distinct zoom "steps."
Expand Down
5 changes: 4 additions & 1 deletion fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/
import { DEFAULT_RATE, DEFAULT_RATE_PRECISION, DEFAULT_COUNT_PRECISION, DEFAULT_FORMAT } from "./align.js"
import { DEFAULT_TAB, currentTab, DEFAULT_VISUALIZER, visualizerType, DEFAULT_RENDER, visualizerRender } from "./events.js"
import { DEFAULT_TAB, currentTab, DEFAULT_VISUALIZER, visualizerType, DEFAULT_RENDER, visualizerRender, isDefaultVisDirection, visualizerDirection } from "./events.js"
import { spec, DEFAULT_BELT, DEFAULT_FUEL } from "./factory.js"
import { Rational } from "./rational.js"
import { currentMod, DEFAULT_TITLE, DEFAULT_COLOR_SCHEME, colorScheme } from "./settings.js"
Expand Down Expand Up @@ -102,6 +102,9 @@ export function formatSettings(excludeTitle, overrideTab, targets) {
if (visualizerRender !== DEFAULT_RENDER) {
settings += "vr=" + visualizerRender + "&"
}
if (!isDefaultVisDirection()) {
settings += "vd=" + visualizerDirection + "&"
}

settings += "items="
let targetStrings = []
Expand Down
19 changes: 13 additions & 6 deletions graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,14 @@ export function imageViewBox(obj) {
return `${x1} ${y1} ${PX_WIDTH-1} ${PX_HEIGHT-1}`
}

export function renderNode(rects, nodeMargin, recipeColors, ignore) {
export function renderNode(rects, nodeMargin, justification, recipeColors, ignore) {
rects.each(d => {
if (justification === "left") {
d.labelX = d.x0
} else {
d.labelX = (d.x0 + d.x1)/2 - d.width/2
}
})
// main rect
rects.append("rect")
.attr("x", d => d.x0)
Expand All @@ -125,7 +132,7 @@ export function renderNode(rects, nodeMargin, recipeColors, ignore) {
// recipe icon
labeledNode.append("svg")
.attr("viewBox", d => imageViewBox(d.recipe))
.attr("x", d => d.x0 + nodeMargin + 0.5)
.attr("x", d => d.labelX + nodeMargin + 0.5)
.attr("y", d => (d.y0 + d.y1) / 2 - iconSize/2 + 0.5)
.attr("width", iconSize)
.attr("height", iconSize)
Expand All @@ -136,26 +143,26 @@ export function renderNode(rects, nodeMargin, recipeColors, ignore) {
.attr("height", sheetHeight)
// node text (building count, or plain rate if no building)
labeledNode.append("text")
.attr("x", d => d.x0 + nodeMargin + iconSize + (d.building === null ? 0 : colonWidth + iconSize) /*+ 5*/)
.attr("x", d => d.labelX + nodeMargin + iconSize + (d.building === null ? 0 : colonWidth + iconSize) /*+ 5*/)
.attr("y", d => (d.y0 + d.y1) / 2)
.attr("dy", "0.35em")
.text(d => d.text())
let buildingNode = rects.filter(d => d.building !== null)
// colon
buildingNode.append("circle")
.classed("colon", true)
.attr("cx", d => d.x0 + nodeMargin + iconSize + colonWidth/2)
.attr("cx", d => d.labelX + nodeMargin + iconSize + colonWidth/2)
.attr("cy", d => (d.y0 + d.y1) / 2 - 4)
.attr("r", 1)
buildingNode.append("circle")
.classed("colon", true)
.attr("cx", d => d.x0 + nodeMargin + iconSize + colonWidth/2)
.attr("cx", d => d.labelX + nodeMargin + iconSize + colonWidth/2)
.attr("cy", d => (d.y0 + d.y1) / 2 + 4)
.attr("r", 1)
// building icon
buildingNode.append("svg")
.attr("viewBox", d => imageViewBox(d.building))
.attr("x", d => d.x0 + iconSize + colonWidth + nodeMargin + 0.5)
.attr("x", d => d.labelX + iconSize + colonWidth + nodeMargin + 0.5)
.attr("y", d => (d.y0 + d.y1) / 2 - iconSize/2 + 0.5)
.attr("width", iconSize)
.attr("height", iconSize)
Expand Down
57 changes: 47 additions & 10 deletions sankey.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function linkPath(d) {
return makeCurve(1, 0, x0, y0, x1, y1, d.width)
}

export function renderSankey(data, ignore) {
export function renderSankey(data, direction, ignore) {
let maxNodeWidth = 0
let testSVG = d3.select("body").append("svg")
.classed("sankey test", true)
Expand All @@ -110,9 +110,17 @@ export function renderSankey(data, ignore) {
text.remove()
testSVG.remove()

let nw, np
if (direction === "down") {
nw = nodePadding
np = maxNodeWidth
} else if (direction === "right") {
nw = maxNodeWidth
np = nodePadding
}
let sankey = d3sankey.sankey()
.nodeWidth(maxNodeWidth)
.nodePadding(nodePadding)
.nodeWidth(nw)
.nodePadding(np)
.nodeAlign(d3sankey.sankeyRight)
.maxNodeHeight(maxNodeHeight)
.linkLength(columnWidth)
Expand All @@ -121,6 +129,9 @@ export function renderSankey(data, ignore) {

for (let link of links) {
link.curve = linkPath(link)
if (direction === "down") {
link.curve = link.curve.transpose()
}
let belts = []
if (link.beltCount !== null) {
let dy = link.width / link.beltCount.toFloat()
Expand All @@ -136,6 +147,13 @@ export function renderSankey(data, ignore) {
link.belts = belts
}

if (direction === "down") {
for (let node of nodes) {
[node.x0, node.y0] = [node.y0, node.x0];
[node.x1, node.y1] = [node.y1, node.x1];
}
}

let svg = d3.select("svg#graph")
.classed("sankey", true)
svg.selectAll("g").remove()
Expand All @@ -148,7 +166,11 @@ export function renderSankey(data, ignore) {
.join("g")
.classed("node", true)

renderNode(rects, sankeyNodeMargin, recipeColors, ignore)
let nodeJust = "left"
if (direction === "down") {
nodeJust = "center"
}
renderNode(rects, sankeyNodeMargin, nodeJust, recipeColors, ignore)

// Link paths
let link = svg.append("g")
Expand Down Expand Up @@ -190,23 +212,38 @@ export function renderSankey(data, ignore) {
.attr("stroke-width", 1)
link.append("title")
.text(d => `${d.source.name} \u2192 ${d.target.name}\n${spec.format.rate(d.rate)}`)
link.filter(d => d.extra)
let linkIcon = link.filter(d => d.extra)
.append("svg")
.attr("viewBox", d => imageViewBox(d.item))
.attr("x", d => d.source.x1 + 2.25)
.attr("y", d => d.y0 - iconSize/4 + 0.25)
.attr("width", iconSize/2)
.attr("height", iconSize/2)
.append("image")
.attr("xlink:href", "images/sprite-sheet-" + sheetHash + ".png")
.attr("width", sheetWidth)
.attr("height", sheetHeight)
link.append("text")
linkIcon.append("image")
.attr("xlink:href", "images/sprite-sheet-" + sheetHash + ".png")
.attr("width", sheetWidth)
.attr("height", sheetHeight)
if (direction === "down") {
linkIcon
.attr("x", d => d.y0 - iconSize/4 + 0.25)
.attr("y", d => d.source.y1 + 2.25)
}
let linkLabel = link.append("text")
.attr("x", d => d.source.x1 + 2 + (d.extra ? iconSize/2 : 0))
.attr("y", d => d.y0)
.attr("dy", "0.35em")
.attr("text-anchor", "start")
.text(d => (d.extra ? "\u00d7 " : "") + spec.format.rate(d.rate) + "/" + spec.format.rateName)
if (direction === "down") {
linkLabel
.attr("x", null)
.attr("y", null)
.attr("transform", d => {
let x = d.y0
let y = d.source.y1 + 2 + (d.extra ? 16 : 0)
return `translate(${x},${y}) rotate(90)`
})
}

// Overlay transparent rect on top of each node, for click events.
let rectElements = svg.selectAll("g.node rect").nodes()
Expand Down
10 changes: 8 additions & 2 deletions settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.*/
import { DEFAULT_RATE, DEFAULT_RATE_PRECISION, DEFAULT_COUNT_PRECISION, DEFAULT_FORMAT, longRateNames } from "./align.js"
import { colorSchemes } from "./color.js"
import { DEFAULT_TAB, clickTab, DEFAULT_VISUALIZER, visualizerType, setVisualizerType, DEFAULT_RENDER, visualizerRender, setVisualizerRender } from "./events.js"
import { DEFAULT_TAB, clickTab, DEFAULT_VISUALIZER, visualizerType, setVisualizerType, DEFAULT_RENDER, visualizerRender, setVisualizerRender, visualizerDirection, getDefaultVisDirection, setVisualizerDirection } from "./events.js"
import { spec, DEFAULT_BELT, DEFAULT_FUEL, buildingSort } from "./factory.js"
import { getRecipeGroups } from "./groups.js"
import { changeMod } from "./init.js"
Expand All @@ -40,7 +40,7 @@ export let MODIFICATIONS = new Map([
//["space-age", new Modification("Space Age 2.0.6", "space-age-2.0.6.json", false)],
])

let DEFAULT_MODIFICATION = "2-0-6"
let DEFAULT_MODIFICATION = "2-0-7"

// Ideally we'd write this as a generalized function, but for now we can hard-
// code these version upgrades.
Expand Down Expand Up @@ -525,6 +525,12 @@ function renderVisualizer(settings) {
setVisualizerRender(DEFAULT_RENDER)
}
d3.select(`#${visualizerRender}_render`).property("checked", true)
if (settings.has("vd")) {
setVisualizerDirection(settings.get("vd"))
} else {
setVisualizerDirection(getDefaultVisDirection())
}
d3.select(`#${visualizerDirection}_direction`).property("checked", true)
}

// default module
Expand Down
6 changes: 3 additions & 3 deletions visualize.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/
import { renderBoxGraph } from "./boxline2.js"
import { visualizerType, visualizerRender, installSVGEvents } from "./events.js"
import { visualizerType, visualizerRender, visualizerDirection, installSVGEvents } from "./events.js"
import { spec } from "./factory.js"
import { iconSize, colonWidth } from "./graph.js"
import { zero, one } from "./rational.js"
Expand Down Expand Up @@ -247,9 +247,9 @@ export function renderTotals(totals, ignore) {
}

if (visualizerType === "sankey") {
renderSankey(data, ignore)
renderSankey(data, visualizerDirection, ignore)
callback()
} else {
renderBoxGraph(data, ignore, callback)
renderBoxGraph(data, visualizerDirection, ignore, callback)
}
}

0 comments on commit 0051f63

Please sign in to comment.