npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sloy-map

v0.1.3

Published

Set up a beautiful geoportal using config. No code.

Downloads

4

Readme

Set up a beautiful geoportal using config. No code.

Features

  1. All features from mapbox \ maplibre \ deck.gl
  2. JSON configuration (can be stored on the backend)
  3. Custom geojson & vector tiles filters
  4. Custom geojson & vector tiles visualisation
  5. License, copyright and metadata management
  6. Low level api via redux actions
  7. Custom files loader
  8. Custom projections
  9. Built-in responsive version
  10. Pmtiles support
  11. Basemap setup
  12. Themes
  13. Localisation
  14. Terrain
  15. Countours
  16. Typescript-safe

Tldr;

Main details:

  1. Library is a maplibre map wrapper.
  2. You can use any features from mapbox \ maplibre \ deck.gl
  3. Library has 5 main entities: sources, layers, visualization, filter, card
  4. Source: data source (geojson, json, vector tile), technically is a wrapper for mabplibre Source with extra params
  5. Visualization: wrapper for the mabplibre Layer with extra params.
  6. Filter: configuration for custom ui that helps to filter source data
  7. Layer: group of visualizations and filters
  8. Card: popup for selected data

Installation

npm i sloy-map
npm i react-redux @reduxjs/toolkit
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
import { SloyMap, sloyReducer } from "sloy-map";
import 'sloy-map/style.css';

const store = configureStore({
  reducer: {
    sloy: sloyReducer,
  },
});

export function App() {
  return (
    <Provider store={store}>
      <SloyMap
        mapState={{
          initialViewState: {
            zoom: 14.5,
            longitude: 44.51,
            latitude: 40.18,
          },
          mapStyle: "https://sloy.io/armenia/style.json",
        }}
        sources={[
          {
            id: "sourceId",
            path: "/file.geojson",
            type: "geojson",
            // also you can use { type: "json" }
            // with latProperty, lngProperty, coordsProperty, isCoordsReverse for custom lat\lng keys

            // you can use custom projection here
            // supports proj4 format
            projection: "EPSG:28408",
            properties: [
              {
                id: "VALUE",
                title: "kcal/cm²",
                // you can describe data colors here, this colors can be used in the visualisations and filters
                values: {
                  40: { color: "#fddede" },
                  45: { color: "#feb7b9" },
                  50: { color: "#fd9793" },
                },
              },
              {
                id: "UNIT",
                title: "Units",
              },
            ],
            // you can describe popup content using the keys from the data
            card: {
              title: "name",
              blocks: [{ type: "value", id: "VALUE" }],
            },
            copyright: [],
            mapSourceProps: {
              /* any mapbox\maplibre source props */
            },
          },
        ]}
        layers={[
          {
            id: "layerId",
            title: "Geojson example",
            description: "Description",
            filters: [],
            visualizations: [
              {
                id: "visualizationId",
                source: "sourceId",
                openable: true,
                property: "VALUE",
                type: "map",
                // any mapbox\maplibre props:
                mapLayerProps: {
                  type: "fill",
                  paint: {
                    "fill-opacity": 0.6,
                  },
                },
              },
            ],
          },
        ]}
        mapProps={
          {
            /* you can use mapbox\maplibre map props here
         for example mapboxAccessToken: xxxx */
          }
        }
      />
    </Provider>
  );
}

You can find more examples in the src/examples/ folder

API

Map props

export interface SloyMapProps extends MapContextProps {
  mapState: IMapState;
  mapProps?: IMapProps;
  sources: InputSloySource[];
  layers: InputSloyLayer[];
  theme?: typeof styled-components ThemeProvider;
  copyrights?: ICopyright[];
  children?: ReactNode;
  locale?: string;
  translations?: Record<string, Record<string, string>>;
  overrideCard?: OverrideCardFn;
  overrideLayers?: OverrideLayersFn;
  terrainSource?: string;
  layout?: {
    hasBaseMap?: boolean;
    hasPmtiles?: boolean;
    buildingLayerName?: string;
    loaderImageSrc?: string;
    canSelectMultipleLayers?: boolean;
  };
}

Source

interface ISource {
  id: string;
  mapSourceProps?: typeof maplibre.Source;
  // path to file
  path?: string;
  type: "vector-tiles" | "geojson" | "json";
  properties?: Record<string, SourceProperty>;
  card?: ICard["id"];
  isCoordsReverse?: boolean;
  coordsProperty?: string;
  latProperty?: string;
  lngProperty?: string;
  projection?: string;
  dataByIdPath?: string;
  copyright: Copyright["id"][];
}

source illustration

Layer

interface ILayer {
  id: string;
  title: string;
  description?: string;
  updatedAt?: string;
  link?: {
    label?: string;
    href?: string;
  };
  license?: string;
  filters: IFilter["id"][];
  visualizations: IVisualization["id"][];
  initialViewState?: {
    center?: number[];
  };
}

layer illustration

Visualization

interface IVisualization {
  id: string;
  type: "map" | "building-ids" | "marker-image" | "building-range" | "native";
  source: ISource["id"];
  property?: string;
  previewPath?: string;
  rootSrc?: string;
  ids?: string[];
  openable?: boolean;
  mapLayerProps?: typeof maplibre.Layer;
}

visualisation illustration

Filter

interface IFilter {
  id: string;
  source: ISource["id"];
  type: "boolean" | "range" | "string" | "string[]";
  filterVisualizations: IVisualization["id"][];
  sortType?: "config" | "count" | "alphabetical";
  totalHeader?: "count";
  title?: string;
  description?: string;
  property?: string;
  color?: string;
  subTitle?: string;
  totalType?: "percent";
  postfix?: string;
}

filter illustration

Card

interface ICard {
  id: string;
  cover?: string;
  title?: string | string[];
  description?: string | string[];
  additionalInfo?: string[];
  blocks: ICardBlock[];
  rootSrc?: string;
}

interface ICardBlock {
  type: string;
  id?: string;
  deps?: string;
  content?: string;
  dateTimeFormat?: Intl.DateTimeFormatOptions;
  title?: string | null;
  value?: ReactNode;
}

card illustration

Copyright

interface ICopyright {
  id: string;
  shortName: string;
  fullName?: string;
  url: string;
  requiredAttribution?: boolean;
}

copyright illustration

Contribution

pnpm i
pnpm start