Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Revision 9e94b1c651a3ba27934bc790271261099fb360ad authored by Laura Garrison on 10 June 2024, 08:28:14 UTC, committed by Laura Garrison on 10 June 2024, 08:28:14 UTC
setting up bootstrap interface
1 parent 9bef561
  • Files
  • Changes
  • 0457dc7
  • /
  • exploratoryTool
  • /
  • BIOMED
  • /
  • index.html
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • revision
  • directory
  • content
revision badge
swh:1:rev:9e94b1c651a3ba27934bc790271261099fb360ad
directory badge
swh:1:dir:85d847bf1904ec3cbfd9f0d7034b688415919960
content badge
swh:1:cnt:08a1a5cccd15d72794a78d5e3723d782c4c4aa1e

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • revision
  • directory
  • content
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="biomed_reset.css">


    <!-- Load d3.js -->
    
    <script src="https://d3js.org/d3.v6.js"></script>
</head>

<body>
    <div id="main">
        <header>Visual Conceptual Metaphor Explorer</header>
        <div id="buttons-wrapper">
            <a href="/BIOMED" style="background-color: #019488">Biomedicine</a>
            <a href="/CLIMATE" style="background-color: #3fccbf">Climate</a>
            <a href="/SPACE" style="background-color: #7accc4">Space</a>
            <a href="/ANTHRO" style="background-color: #a7c7c4">Anthropology</a>
            
        </div>
        <div id="columns">
            <div style="display: flex; flex-direction:column;">
                <div class="row header">Distribution</div>
                <div class="row">
                    <span><b>Domain:</b> </span><span id="primary-domain-title"></span>
                    <span><b>Secondary Domain(s):</b> </span><span id="secondary-domain-title"></span>
                </div>
                <div id="scatterplot">
                    <svg id="scatterplot-svg">
    
                    </svg>
                </div>
            </div>
    
            <div id="preview">
                <div class="row header">General Information</div>
                <div class="row row-textual"><span><b>Name:</b> </span><span id="name-title"></span></div>
                <div class="row row-textual"><span><b>Author:</b> </span><span id="author-title"></span></div>
                <div class="row row-textual"><span><b>Link:</b> </span><a href="" id="link-title"></a></div>
                <div class="row" style="min-height: 0;"><img id="preview-img" src="" /></div>
            </div>
    
            <div id="piechart">
                <div class="row header">Conceptual metaphor analysis</div>
                <div class="row row-textual"><span><b>Supporting textual metaphor:</b> </span><span id="text-metaphor"></span></div>
                <div class="row row-textual"><span><b>Type:</b> </span><span id="type-metaphor"></span></div>   
                
            </div>
        </div>
    </div>

    <script>
        window.onload = function () {
            function PieChart(data, {
                name = ([x]) => x,  // given d in data, returns the (ordinal) label
                value = ([, y]) => y, // given d in data, returns the (quantitative) value
                title, // given d in data, returns the title text
                width = 640, // outer width, in pixels
                height = 400, // outer height, in pixels
                innerRadius = 0, // inner radius of pie, in pixels (non-zero for donut)
                outerRadius = Math.min(width, height) / 2, // outer radius of pie, in pixels
                labelRadius = (innerRadius * 0.2 + outerRadius * 0.8), // center radius of labels
                format = ",", // a format specifier for values (in the label)
                names, // array of names (the domain of the color scale)
                colors, // array of colors for names
                stroke = innerRadius > 0 ? "none" : "white", // stroke separating widths
                strokeWidth = 1, // width of stroke separating wedges
                strokeLinejoin = "round", // line join of stroke separating wedges
                padAngle = stroke === "none" ? 1 / outerRadius : 0, // angular separation between wedges, in radians
            } = {}) {
                // Compute values.
                const N = d3.map(data, name);
                const V = d3.map(data, value);
                const I = d3.range(N.length).filter(i => !isNaN(V[i]));

                // Unique the names.
                if (names === undefined) names = N;
                names = new d3.InternSet(names);

                // Chose a default color scheme based on cardinality.
                if (colors === undefined) colors = d3.schemeSpectral[names.size];
                if (colors === undefined) colors = d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), name.size);

                // Construct scales.
                const color = d3.scaleOrdinal(names, colors);

                // Compute titles.
                if (title === undefined) {
                    const formatValue = d3.format(format);
                    title = i => `${N[i]}\n${formatValue(V[i])}`;
                } else {
                    const O = d3.map(data, d => d);
                    const T = title;
                    title = i => T(O[i], i, data);
                }

                // Construct arcs.
                const arcs = d3.pie().padAngle(padAngle).sort(null).value(i => V[i])(I);
                const arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius);
                const arcLabel = d3.arc().innerRadius(labelRadius).outerRadius(labelRadius);

                const svg = d3.create("svg")
                    .attr("width", width)
                    .attr("height", height)
                    .attr("viewBox", [-width / 2, -height / 2, width, height])
                    .attr("style", "max-width: 100%; height: auto; height: intrinsic;");

                svg.append("g")
                    .attr("stroke", stroke)
                    .attr("stroke-width", strokeWidth)
                    .attr("stroke-linejoin", strokeLinejoin)
                    .selectAll("path")
                    .data(arcs)
                    .join("path")
                    .attr("fill", d => color(N[d.data]))
                    .attr("d", arc)
                    .append("title")
                    .text(d => title(d.data));

                svg.append("g")
                    .attr("font-family", "sans-serif")
                    .attr("font-size", 10)
                    .attr("text-anchor", "middle")
                    .selectAll("text")
                    .data(arcs)
                    .join("text")
                    .attr("transform", d => `translate(${arcLabel.centroid(d)})`)
                    .selectAll("tspan")
                    .data(d => {
                        const lines = `${title(d.data)}`.split(/\n/);
                        return (d.endAngle - d.startAngle) > 0.25 ? lines : lines.slice(0, 1);
                    })
                    .join("tspan")
                    .attr("x", 0)
                    .attr("y", (_, i) => `${i * 1.1}em`)
                    .attr("font-weight", (_, i) => i ? null : "bold")
                    .text(d => d);

                return Object.assign(svg.node(), { scales: { color } });
            }
            // append the svg object to the body of the page
            const svg_column = document.querySelector("#scatterplot");

            /* Globals */
            let data = undefined;
            let rectangles = undefined;
            let chosenImg = '';
            let piechartValues = undefined;

            const regenerate = () => {
                while (svg_column.firstChild) {
                    svg_column.removeChild(svg_column.lastChild);
                }

                d3.select("#scatterplot").append("svg");
                const svg = d3.select("#scatterplot > svg");

                const margin = { top: 20, right: 10, bottom: 45, left: 80 };
                const width = svg_column.clientWidth - margin.left - margin.right;
                const height = svg_column.clientHeight - margin.top - margin.bottom;

                const svg_viewport = svg
                    .attr("width", svg_column.clientWidth)
                    .attr("height", svg_column.clientHeight)
                    .append("g")
                    .attr("transform", `translate(${margin.left}, ${margin.top})`);

                // Add X axis
                const x = d3.scaleLinear()
                    .domain([0, 90])
                    .range([0, width]);

                svg_viewport.append("g")
                    .attr("transform", `translate(0, ${height})`)
                    .call(
                        d3.axisBottom(x)
                            .tickValues([10, 20, 30, 40, 50, 60, 70, 80, 90])
                            .tickFormat((v) => {
                                // you can completley override anything in this formatting
                                // for example
                                if (v <= 10) return 'nanosec';
                                if (v <= 20) return 'sec';
                                if (v <= 30) return 'min';
                                if (v <= 40) return 'hours';
                                if (v <= 50) return 'days';
                                if (v <= 60) return 'weeks';
                                if (v <= 70) return 'months';
                                if (v <= 80) return 'years';

                                //if (v <= 10) return '' + v + '⁻³ \n ns'



                                //if (v <= 20) return '' + v + '\n s';
                                //if (v <= 30) return '' + v + '\n m';

                                //return v + '\n  s';
                            })
                    );

                svg.append("text")
                    .attr("class", "y label")
                    .attr("text-anchor", "end")
                    .attr("y", 0)
                    .attr("x", -margin.top)
                    .attr("dy", ".75em")
                    .attr("transform", "rotate(-90)")
                    .text("SPATIAL COVERAGE");

                svg.append("text")
                    .attr("class", "x label")
                    .attr("text-anchor", "end")
                    .attr("x", width + margin.left + margin.right)
                    .attr("y", height + 55)
                    .text("TEMPORAL COVERAGE");

                // Add Y axis
                const y = d3.scaleLinear()
                    .domain([0, 100])
                    .range([height, 0]);

                svg_viewport.append("g")
                    .call(
                        d3.axisLeft(y)
                            .tickValues([10, 20, 30, 40, 50, 60, 70, 80, 90])
                            .tickFormat((v) => {
                                switch (v) {
                                    case 10: return 'molecules';
                                    case 20: return 'viruses';
                                    case 30: return 'cells';
                                    case 40: return 'bacteria';
                                    case 50: return 'tissues';
                                    case 60: return 'organs';
                                    case 70: return 'organ systems';
                                    case 80: return 'organism';
                                    case 90: return 'population';
                                    
                                }
                            })
                    );

                if (!data || !rectangles) return;

                const setPiechart = (values) => {
                    if (!values) return;

                    const piechart_column = document.querySelector("#piechart");

                    document.querySelectorAll('#piechart svg').forEach(e => e.remove());

                    let chart = PieChart(values, {
                        name: d => d.type,
                        value: d => d.percentage,
                        width: piechart_column.clientWidth,
                        height: piechart_column.clientHeight,
                        names: ['Structural', 'Ontological', 'Orientational', 'Imagistic']
                    });
                    
                    piechart_column.insertBefore(chart, document.querySelector('#piechart .row:nth-child(2)'));
                };

                setPiechart(piechartValues);

                let Tooltip = d3.select("#scatterplot")
                    .append("div")
                    .attr("class", "tooltip")
                    .style("background-color", "white")
                    .style("border", "solid")
                    .style("border-width", "2px")
                    .style("border-radius", "5px")
                    .style("padding", "5px")
                    .style("z-index", "999")
                    .style("position", "fixed")
                    .attr('pointer-events', 'none');

                document.querySelectorAll('rect').forEach(e => e.remove());

                for (let i = 0; i < rectangles.length; i++) {
                    const positionX = parseFloat(rectangles[i].xfrom);
                    const positionY = parseFloat(rectangles[i].yfrom);

                    const positionXTo = parseFloat(rectangles[i].xto);
                    const positionYTo = parseFloat(rectangles[i].yto);

                    console.log(positionX, positionXTo);
                    console.log(positionX < positionXTo);
                    console.log(positionY < positionYTo);
                    console.log(height - Math.abs(y(positionYTo - positionY)));

                    svg_viewport
                        .append('rect')
                        .attr('x', x(positionX))
                        .attr('y', y(positionYTo))
                        .attr('width', x(positionXTo) - x(positionX))
                        .attr('height', height - Math.abs(y(positionYTo - positionY)))
                        //.attr('stroke', 'black')
                        .attr('fill', rectangles[i].color)
                        //.attr('opacity', 0.2)
                        .attr('pointer-events', 'none');

                }

                // Points  Tooltip
                for (let i = 0; i < data.length; i++) {
                    const positionX = data[i].x.split('-')[0];
                    const positionY = data[i].y.split('-')[0];

                    const positionXTo = data[i].x.split('-')[1];
                    const positionYTo = data[i].y.split('-')[1];

                    svg_viewport
                        .append('circle')
                        .attr('cx', x(positionX))
                        .attr('cy', y(positionY))
                        .attr('r', 10.0)
                        .attr('class', 'circle-base')
                        .on("mouseover", () => {
                            Tooltip.style("opacity", 1);
                            Tooltop.style("display", "block")
                                .attr('pointer-events', 'none');
                        })
                        .on("mousemove", (event) => {
                            Tooltip
                                .html(data[i].name)
                                .style("left", (event.pageX + 10) + "px")
                                .style("top", (event.pageY - 20) + "px")
                                .style("display", "block");
                        })
                        .on("mouseleave", () => {
                            Tooltip.style("opacity", 0);
                            Tooltip.style("display", "none")
                                .attr('pointer-events', 'none');
                        })
                        .on('click', (event) => {
                            // Change state of each circled & set current to different CSS class            
                            document.querySelectorAll("svg circle").forEach((node) => {
                                node.classList = ['circle-base'];
                            });
                            document.querySelectorAll("svg circle")[i].classList = ['circle-click'];

                            // Set Image OR copyright notice and link
                            document.querySelector("#preview-img").setAttribute('src', data[i].imageURL);

                            // Set Domains, authors, etc...
                            document.querySelector("#primary-domain-title").innerHTML = data[i].primarydomain;
                            document.querySelector("#secondary-domain-title").innerHTML = data[i].secondarydomain;
                            document.querySelector("#name-title").innerHTML = data[i].name;
                            document.querySelector("#author-title").innerHTML = data[i].author;
                            document.querySelector("#link-title").innerHTML = data[i].url;
                            document.querySelector("#link-title").href = data[i].url;
                            document.querySelector("#type-metaphor").innerHTML = data[i].typeOfMetaphor;
                            document.querySelector("#text-metaphor").innerHTML = data[i].textMetaphor;
                            

                            console.log(data[i]);

                            // Configure piechart
                            const types = data[i].type.split('|');
                            const percentages = data[i].percentages.split('|');

                            let values = [];
                            for (let i = 0; i < types.length; i++) {
                                if (percentages[i] > 0) {
                                    values.push({ type: types[i], percentage: percentages[i] })
                                }

                            }
                            piechartValues = values;
                            setPiechart(values);
                        });
                }
            };

            window.onresize = () => {
                regenerate();
            };

            regenerate();

            d3.csv("biomed.csv").then((d) => {
                data = d;
                regenerate();
            });

            d3.csv("biomed_rectangles.csv").then((d) => {
                rectangles = d;
                regenerate();
            });
        };
    </script>
</body>

</html>
The diff you're trying to view is too large. Only the first 1000 changed files have been loaded.
Showing with 0 additions and 0 deletions (0 / 0 diffs computed)
swh spinner

Computing file changes ...

back to top

Software Heritage — Copyright (C) 2015–2026, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API