UNPKG

terriajs

Version:

Geospatial data visualization platform.

114 lines (103 loc) 3.94 kB
"use strict"; import { nest as d3Nest } from "d3-collection"; import defaultValue from "terriajs-cesium/Source/Core/defaultValue"; import defined from "terriajs-cesium/Source/Core/defined"; const defaultClassName = "base-chart-title"; const defaultHeight = 30; // The additional height of the title, which may in fact be the legend. /** * Handles the drawing of the chart title, which may be a string or a legend. * * @param {String} [titleSettings.type='string'] May be 'string' or 'legend'. * @param {String} [titleSettings.title] For 'string'-type titles, the title. * @param {String} [titleSettings.className] The className to use for the title DOM element. Defaults to 'base-chart-title'. * @param {Number} [titleSettings.height=defaultTitleHeight] The height of the title bar. */ const Title = { className(titleSettings) { return titleSettings && titleSettings.className ? titleSettings.className : defaultClassName; }, getHeight(titleSettings) { return defaultValue( defined(titleSettings) ? titleSettings.height : 0, defaultHeight ); }, create(d3Element, titleSettings) { // For a nicely centered title, use css: .chart-title {left: 0, right: 0, text-align: center;} and maybe {margin: 0 auto;}. d3Element .append("div") .attr("class", Title.className(titleSettings)) .style("opacity", 1e-6) .style("position", "absolute"); }, enterUpdateAndExit( d3Element, titleSettings, margin, catalogItems, transitionDuration ) { // The title might be the legend, or a simple string. const title = d3Element .select("." + Title.className(titleSettings)) .style("top", margin.top + "px"); title .transition() .duration(transitionDuration) .style("opacity", Title.getHeight(titleSettings) > 0 ? 1 : 1e-6); if (defined(titleSettings)) { let titleData = catalogItems; if (titleSettings.type === "string") { titleData = [{ id: "_string__", name: titleSettings.title }]; } // in d3 v4, selection.data method returns new selections // rather than modifying the selection in-place. const titleComponents = title .selectAll(".title-component") .data(titleData, (d) => d.id); // Check whether there are multiple category names and/or column names. const numberOfCategories = d3Nest().key((d) => d.categoryName).length; const numberOfColumnNames = d3Nest().key((d) => d.name).length; // This is to only show the interesting parts of the name & categoryName in the title, // similar to Tooltip.js. const getName = function (d, index) { if (!d.categoryName) { return d.name; } if (numberOfColumnNames === 1) { return d.categoryName + (index === 0 ? " " + d.name : ""); } if (numberOfCategories === 1) { return (index === 0 ? d.categoryName + " " : "") + d.name; } if (d.name === d.categoryName) { return d.categoryName; } return d.categoryName + " " + d.name; }; // Enter. const addedTitleComponents = titleComponents .enter() .append("span") .attr("class", "title-component"); if (titleSettings.type === "legend") { addedTitleComponents.append("span").attr("class", "color"); } addedTitleComponents.append("span").attr("class", "name"); // Enter and update. const mergedTitleComponents = addedTitleComponents.merge(titleComponents); mergedTitleComponents .select(".color") .style("background-color", (d) => d.color) .style("border-radius", (d) => { return d.type === "momentPoints" ? "50%" : "0"; }); mergedTitleComponents.select(".name").text(getName); // Exit. titleComponents.exit().remove(); } } }; export default Title;