1656649800
Wikimaps-D3js Atlas -- A command line utility to convert massive GIS sources into elegant administrative and topographic raster, topojson files and web friendly svg maps.
Wikimaps-D3js Atlas takes the power of GIS to the hands of web developpers, graphists, journalists and online readers. A single command let you process super heavy GIS sources such open source administrative NaturalEarth shapefiles and topographic ETOPO/SRTM tifs into light geojson, TopoJSON and SVG files optimized for screens display. XML shapes and groups of shapes keep the most relevant data-attributes (name, iso_2, hasc code, population and others) allowing rich data binding while the graphic aspect keeps up to modern expectations. We believe our topojson and svg files to be the finest available online due to the smart selection and presence of these data attributes easing data binding.
# Generate map for India
make -f master.makefile NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0 WIDTH=1280
# Generate maps for all countries. /!\ : May take half a day.
bash ./script/world_atlas_generator.bash ./script/world_atlas_commands.txt
Topographic-Administrative | Administrative |
---|---|
![]() | ![]() |
Topographic | Administrative localisator |
![]() | ![]() |
Constitutives components (raster, topojson) and derivated variations (jpg, png, svg) are gathered into /output/{Country_name}/
, as for India it represent about 70 files.
To custom the styles, edit ./js/wikiatlas.js
's "CSS MODULE", and ./01_topography/
relative color ramps.
CPU :
Disk space :
Environment :
nodejs
v6.8.2 (LTS Boron) & npm
System dependencies :
gdal
, topojson
, jsdom
, d3js
, python
, make
.On Linux Ubuntu, run the following:
git clone https://github.com/WikimapsAtlas/WikimapsAtlas-generator.git #get code
cd ./WikimapsAtlas-generator
npm install # install node dependencies and system dependencies. May need sudo.
npm run data # download ETOPO1, NaturalEarth data (default). See ./package.json & data.makefile
# npm run dataplus # download SRTM250, SRTM90, GADM2 data (precise). See ./package.json & data.makefile
On OS X use Homebrew's brew install <program>
. (Are you on Mac ? Help us to write this section.).
Per default, output files have the following characteristics:
./js/wikiatlas.js
)Custom projection is possible but not yet implemented. See issue 1.
Wikimaps Atlas is usually run via the master.makefile
, which pass variables to sub-module makefiles generating suit of cropped shp, rasters images, topojson and svgs. Modules can be ran independently as well.
Master: When run, the master.makefile
runs other layer-specialized sub-makefiles. These sub-makefiles process GIS sources, output topoJSON file(s) which nodejs
, jsdom
, and D3js
convert into stand alone SVGs stored in the ./output
folder.
Topography & reliefs: When run, the topography.makefile
download the raster GIS DEM sources, process them (unzip, crop, slice, polygonize, merge), to output an elegant topographic stack of polygons, topojson and WP styled SVG files.
Hillshade relief: When run, the hillshade.makefile
process SRTM sources via crop, hillshading relief, resize, color relief, to output elegant shaded relief png/jpg (current) and topojson/svg.
Administrative: When run, the administrative.makefile
processes the administrative L0 (countries), L1 (subunits), disputed areas and cities (places) GIS sources via unzip, crop, filter, to output elegant topojson files.
Water: When run, the water.makefile
processes the rivers and lakes GIS sources via unzip and crop, to output elegant topojson files.
D3 (svg generator): When run, the d3.makefile
queries the previously generated jpg, png, and topojson in order to create D3js svg visualisations, then printed into stand alone .svg
files.
# master
make -f master.makefile NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0 WIDTH=1280
# 1. topography raster & vector
make -f master.makefile topography NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0 SLICES=8
# 2. hillshade module
make -f master.makefile hillshade NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0 SLICES=8
# 3. administrative module
make -f master.makefile administrative NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0
# 4. water module
make -f master.makefile water NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0
# 5. d3 module (depend on 1,2,3,4)
make -f master.makefile d3 NAME=India ISO2=IN WEST=67.0 NORTH=37.5 EAST=99.0 SOUTH=05.0
This API is inspired by ogr2ogr
, topojson
, gdal
, and convert
(imageMagick) APIs. Elements are ordered by order of apparition, from master, to administrative, to shaded relief, to topography.
Commonly used:
administrative.topo.json
files, this parameter is used to filter the ones to visualize via d3js.[180.0,-180.0]
.[80.0,-80.0]
(GIS data often missing for poles)[180.0,-180.0]
.[80.0⁰,-80.0]
(GIS data often missing for poles)WNES
values and the WIDTH
.1980
(px),>0
.8
,2
(!).15
,[0-100]
.Advanced use:
.shp
& .tif
outputs.epsg:4326
(equirectangular).epsg:3857
(mercator, requires S=370400
)ADM0NAME = '$(NAME)' AND ORDER BY POP_MAX DESC LIMIT 15
together with all countries capitals.ADM0NAME = '$(NAME)' AND POP_MAX > 2000000
1e4
(10,000),[1e2,1e5]
.5
,>0
.111120
(if surface in decimal degrees and vertical in meters use S=111120
, if vertical in feets use S=370400
)315
,[0-359]
.60
,[0-90]
.Under consideration:
1
,[0-1]
0
,[0-10]
etopo
,etopo
, srtm250
, srtm90
Note:
s
scale should be edited. See man gdal
.Generated files are moved into ./output/<NAME>/
.
Files below are generated as intermediate steps before the svg maps creation.
elevations.topo.json
: n slices in vector format to represent signicative elevations of exponential altitude (ex: 0,50,200,500,2000, 5000m).color.jpg
: raster relief with two relative coloramps for landmass and sea. (default: Mercator)trans.png
: a transparent hillshade, see How to create transparent hillshade?. (default: Mercator)hillshades.topo.json
: vector version of the previous.administrative.topo.json
made by combining the following :admin_0.topo.json
: countriesadmin_1.topo.json
: subdivisions of the target countrydisputed.topo.json
: disputed area within the range of the queryplaces.topo.json
: cities with population above a given numberwaters.topo.json
: major rivers of the area.Whenever available, these elements are transmitted into the final topojson files :
name
: feature's English name (for all: countries, provinces, disputed, cities, rivers)L0
: feature's country iso2 codes (for countries, provinces, disputed, cities),L0_3
: feature's iso3 codes (for countries, provinces, disputed, cities),L1
: feature's province hasc code (for provinces, disputed), *L0_name
: feature's country name (for provinces, disputed, cities),L1_name
: feature's province name (for cities),note
: "claimed by, controlled by" (for disputed areas)status
: feature's status (for cities),pop
: population (for cities),scalerank
: river scalerank.Files below are complete web friendly maps.
{NAME}_location_map,_admin_relief_(2015)-en.svg
-- raster relief and hillshade, vector admin_0, admin_1, cities, labels, rivers.{NAME},_{Province_name}_locator_map,_admin_relief_(2015)-en.svg
-- idem previous, with provinces enlighten.{NAME},_{Province_name}_locator_map,_admin_blue_(2015)-en.svg
-- idem previous, no reliefs nor hillshades, 100% vector.{NAME}_location_map,_admin_blue_(2015).svg
-- no labels.{NAME}_location_map,_admin-topographic_relief_(2015)-en.svg
{NAME},_{Province_name}_locator_map,_admin-topographic_relief_(2015)-en.svg
{NAME}_location_map,_admin-topographic_relief_(2015).svg
{NAME}_location_map,_topographic_blue_(2015).svg
We here mirror best practices refined by Wikipedia's cartographers over the past 10 years.
Report issues or ideas on github.
Supports:
Author: WikimapsAtlas
Source Code: https://github.com/WikimapsAtlas/WikimapsAtlas-generator
License: MIT license
1656592800
Earthjs
Earthjs is a javascript library for easy building orthographic globe. Originally inspired by planetary.js (canvas) and Faux-3d Shaded Globe (svg) and both were created using D3-v3.
Earthjs is created using D3-v4, design as pluggable modules.
Awesome interactive globe can be created, drag to rotate, scroll mouse zooming. Multi layer of globe, combination between SVG, Canvas and Threejs. Multiple globe as a twin globe with same or different layer. Solid or transparent globe in SVG, Canvas or Threejs, hide/show some features balancing between smooth rendering and cpu utilization. point/mark of location, bar chart on globe & tooltips.
SVG for quickly prototyping the globe as it used standard SVG DOM element so event & css can be applied to each element. the downside will come when the need to create so much SVG element, the responsiveness or jaggering drag will show.
Canvas for more data point that need to be render and UX experience stay in good shape. Interactivity or mouse detection are available for hovering, click & double click. detect country or point of location.
WebGL/Threejs is a way to go if eye catchy of globe is needed and lots of data, or want to be better CPU utilization by moving some intensive calculation to GPU.
Interesting Data Visualization can be created by combining SVG, Canvas & Threejs(WebGL) like: choropleth globe using Canvas or Threejs, heatmap globe by rendering heatmap on canvas and use that canvas as a texture in Threejs, flightLine to connect two datapoint using Threejs and coloring target location (usually country) using Canvas. flashy bullet that travel along the way of flightLine is there including the mouse event using Threejs.
Selected plugins bundled into library:
Optional
This sample need to run on the webserver, you can use nodejs web-server or python simple http server.
<html>
<head>
<script type='text/javascript' src='http://d3js.org/d3.v4.min.js'></script>
<script type='text/javascript' src='http://d3js.org/topojson.v3.min.js'></script>
<script type='text/javascript' src='../dist/earthjs.js'></script>
<style media="screen">
.countries path {
fill: rgb(117, 87, 57);
stroke: rgb(80, 64, 39);
stroke-linejoin: round;
stroke-width: 1.5;
opacity: 1;
}
.graticule path {
fill: none;
opacity: 0.2;
stroke: black;
stroke-width: 0.5;
}
</style>
</head>
<body>
<svg id="earth"></svg>
<script>
const g = earthjs()
.register(earthjs.plugins.graticuleSvg())
.register(earthjs.plugins.autorotatePlugin(10))
.register(earthjs.plugins.worldSvg('./d/world-110m.json'));
g.ready(function(){
g.create();
})
</script>
</body>
</html>
Plugins is a function created in "earthjs.plugins" namespace, return with javascript object. Some of the keys have a special meaning, "name" property will be define plugin namespace in "earthjs", "urls" property is an ajax url and six(6) functions start with "on" are event handler. Other functions that define in the plugin will be live on the plugin namespace. Function defined in the plugin will become proxy function in which they have a context of earthjs instance.
export default (url) => {
//.... private code
return {
name: 'samplePlugin',
urls: [url], // ajax url
onReady () {}, // ajax handler
onInit () {},
onCreate () {},
onResize () {},
onRefresh () {},
onInterval() {}
}
}
If necessary when the plugin is in use, onReady() can be superseded by ready() function, created in the plugin namespace.
// example:
g.register(earthjs.plugins.worldSvg('./d/world-110m.json'));
g.worldSvg.ready = function(err, json) {
//+++collpased code
g.worldSvg.data(json);
}
Plugin example
earthjs.plugins.graticuleSimple = () => {
const grat = d3.geoGraticule(), $ = {};
function create() {
this._.svg.selectAll('.graticule').remove();
$.grat = this._.svg.append("path").datum(grat).attr("class", "graticule");
refresh.call(this);
}
function refresh() {
$.grat.attr("d", this._.path);
}
return {
name: 'graticuleSimple',
onCreate() {create .call(this);},
onRefresh() {refresh.call(this);}
}
}
//... plugin in use
const g = earthjs()
.register(earthjs.plugins.graticuleSimple())
.create();
Convention
For SVG create function:
in general, return value should be a simple object whereby body of functions are kept in the private place with same name, and use .call(this,...) to execute the private function.
For Canvas, it always recreate the whole canvas, mean that onCreate & onRefresh should be using same (logic of drawing) function.
For Threejs, the concept of refresh is different compare with SVG or Canvas, when globe rotate the internal state of projection is changed, to reflect the changes in UI, SVG or Canvas need to refresh or redraw the path, as for Threejs the D3 projection state change need to be transfer to Threejs main container object, so less need to create onRefresh function.
Building earthjs requires Node.js. Once you've installed the project's dependencies with npm install, you can build earthjs to the dist directory with npm run build.
Author: Earthjs
Source Code: https://github.com/earthjs/earthjs
License: MIT license
1656452280
Datamaps is intended to provide some data visualizations based on geographical data. It's SVG-based, can scale to any screen size, and includes everything inside of 1 script file. It heavily relies on the amazing D3.js library.
Out of the box it includes support for choropleths and bubble maps (see demos), but it's not limited to just that. Its new plugin system allows for the addition of any type of visualization over the map.
For feature requests, open an issue!
new Datamaps(options)
, passing in at least an element
optionExample:
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="/datamaps.world.min.js"></script>
<div id="container" style="position: relative; width: 500px; height: 300px;"></div>
<script>
var map = new Datamap({element: document.getElementById('container')});
</script>
This should render a new world map with a standard projection.
npm install datamaps
dist
directory, like:<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="node_modules/datamaps/dist/datamaps.world.min.js"></script>
<div id="container" style="position: relative; width: 500px; height: 300px;"></div>
<script>
var map = new Datamap({element: document.getElementById('container')});
</script>
bower install datamaps
dist
directory, like:<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="bower_components/datamaps/dist/datamaps.world.min.js"></script>
<div id="container" style="position: relative; width: 500px; height: 300px;"></div>
<script>
var map = new Datamap({element: document.getElementById('container')});
</script>
A map of the USA with an Albers based projection will be default if you only include datamaps.usa.min.js
, but in case you include datamaps.all.min.js
:
<script>
var map = new Datamap({
element: document.getElementById('container'),
scope: 'usa'
});
</script>
<script>
var map = new Datamap({
element: document.getElementById('container'),
fills: {
defaultFill: 'rgba(23,48,210,0.9)' // Any hex, color name or rgb/rgba value
}
});
</script>
<script>
var map = new Datamap({
element: document.getElementById('container'),
geographyConfig: {
highlightOnHover: false,
popupOnHover: false
}
});
</script>
<script>
var map = new Datamap({
element: document.getElementById('container'),
geographyConfig: {
dataUrl: '/custom.json'
},
scope: 'custom',
setProjection: function(element, options) {
var projection, path;
projection = d3.geo.albersUsa()
.center([long, lat])
.scale(element.offsetWidth)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
}
path = d3.geo.path()
.projection( projection );
return {path: path, projection: projection};
}
});
</script>
By specifying a dataUrl
, Datamaps will attempt to fetch that resource as TopoJSON.
If you are using a custom map, you'll probably want to specify your own setProjection
method as well.
setProjection
takes 2 arguments, element
as a DOM element, options
as the original options you passed in. It should return an object with two properties: path
as a d3.geo.path
, projection
as a d3.geo.projection
The example above will result in albersUsa projection.
Read about other D3.js projections
Follow the below steps:-
Here are the some examples of different countries maps.
var bubble_map = new Datamap({
element: document.getElementById('india'),
scope: 'india',
geographyConfig: {
popupOnHover: true,
highlightOnHover: true,
borderColor: '#444',
borderWidth: 0.5,
dataUrl: 'https://rawgit.com/Anujarya300/bubble_maps/master/data/geography-data/india.topo.json'
//dataJson: topoJsonData
},
fills: {
'MAJOR': '#306596',
'MEDIUM': '#0fa0fa',
'MINOR': '#bada55',
defaultFill: '#dddddd'
},
data: {
'JH': { fillKey: 'MINOR' },
'MH': { fillKey: 'MINOR' }
},
setProjection: function (element) {
var projection = d3.geo.mercator()
.center([78.9629, 23.5937]) // always in [East Latitude, North Longitude]
.scale(1000);
var path = d3.geo.path().projection(projection);
return { path: path, projection: projection };
}
});
Set the correct projection for India map on world map with the help of Longitude and Latitute of India (you can google it India Longitude and Latitute)
Please use india.toto.json for India geopraphy json data from https://github.com/Anujarya300/bubble_maps/blob/master/data/geography-data/india.topo.json, otherwise your map wont work. (I have truncated IND. from all state ISO code(2-digit ISO code), e.g IND.JH for Jharkhand state truncated to JH)
Please note in setProjection method, I have set [78.9629, 23.5937] to locate center point for India in the world map. That means Latitude = 78.9629 E and Longitude = 23.5937 N. Remember Latitute and Longitude are always East and North. For western countries, Latitude are in West so make it convert as Negative of East. e.g 102.3421 W ==> -102.3421 E.
var bubble_map = new Datamap({
element: document.getElementById('canada'),
scope: 'canada',
geographyConfig: {
popupOnHover: true,
highlightOnHover: true,
borderColor: '#444',
borderWidth: 0.5,
dataUrl: 'https://rawgit.com/Anujarya300/bubble_maps/master/data/geography-data/canada.topo.json'
//dataJson: topoJsonData
},
fills: {
'MAJOR': '#306596',
'MEDIUM': '#0fa0fa',
'MINOR': '#bada55',
defaultFill: '#dddddd'
},
data: {
'JH': { fillKey: 'MINOR' },
'MH': { fillKey: 'MINOR' }
},
setProjection: function (element) {
var projection = d3.geo.mercator()
.center([-106.3468, 68.1304]) // always in [East Latitude, North Longitude]
.scale(250)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return { path: path, projection: projection };
}
});
Set the correct projection for Canada map on world map with the help of Longitude and Latitute of Canada (you can google it Canada Longitude and Latitute)
Please use canada.toto.json for India geopraphy json data from https://github.com/Anujarya300/bubble_maps/blob/master/data/geography-data/canada.topo.json, otherwise your map wont work. (I have truncated CA. from all state ISO code(2-digit ISO code), e.g CA.TN to TN)
Please note in setProjection method, I have set [-106.3468, 68.1304] to locate center point for Canada in the world map. That means Latitude = 106.3468 W and Longitude = 68.1304 N. Remember Latitute and Longitude are always East and North. For western countries, Latitude are in West so make it convert as Negative of East. e.g 102.3421 W ==> -102.3421 E.
You can adjust this latitude and longitude co-ordinates by minor changing. e.g, if your map is not showing full view of North then you can change 68.1304 N to 70.3200 N or 71.3200 etc. if your map is not showing full view of East then you can change 32.1304 E to 70.3200 E or 30.3200 etc.
More about other countries maps
Probably the most common type of map visualization, where different states or countries are color coded.
You'll need to know the 2 letter state code ('NY' for New York) or the 3 letter country code ('SCT' for Scotland) to fill in areas.
<script>
var map = new Datamap({
element: document.getElementById('container'),
fills: {
HIGH: '#afafaf',
LOW: '#123456',
MEDIUM: 'blue',
UNKNOWN: 'rgb(0,0,0)',
defaultFill: 'green'
},
data: {
IRL: {
fillKey: 'LOW',
numberOfThings: 2002
},
USA: {
fillKey: 'MEDIUM',
numberOfThings: 10381
}
}
});
// Draw a legend for this map
map.legend();
</script>
This will draw a world map and fill in IRL (Ireland) with the corresponding fills.LOW
and USA with fills.MEDIUM
.
You can also use fill: color
for each state if you don't want to define a fillKey
.
Colors will be applied in this order: fillKey
, fill
, defaultFill
.
map.updateChoropleth({
USA: {fillKey: 'LOW'},
CAN: '#0fa0fa'
});
You can specify either a literal color (as a string), or an object with a fillKey property.
defaultFill
The following will reset the entire map to the defaultFill
and update CA
to be filled green.
map.updateChoropleth({CA: 'green'}, {reset: true})
The following will reset the entire map to defaultFill
map.updateChoropleth(null, {reset: true})
The following will reset the entire map to defaultFill
, but update the corresponding data of NY.
map.updateChoropleth({NY: {numberOfVoters: 55452}}, {reset: true})
You can also add a map legend with the legend
plugin (used above)
Example highmaps_world.html explains how to create colorized map based on some quantity of things, Live Demo
Example result:
Expanding on the previous example of using data
, any property passed into data
will be sent to the popupTemplate
function, which can be override to display custom messages.
<script>
var map = new Datamap({
element: document.getElementById('container'),
fills: {
HIGH: '#afafaf',
LOW: '#123456',
MEDIUM: 'blue',
UNKNOWN: 'rgb(0,0,0)',
defaultFill: 'green'
},
data: {
IRL: {
fillKey: 'LOW',
numberOfThings: 2002
},
USA: {
fillKey: 'MEDIUM',
numberOfThings: 10381
}
},
geographyConfig: {
popupTemplate: function(geo, data) {
return ['<div class="hoverinfo"><strong>',
'Number of things in ' + geo.properties.name,
': ' + data.numberOfThings,
'</strong></div>'].join('');
}
}
});
</script>
geographyConfig.popupTemplate
, bubblesConfig.popupTemplate
and arcConfig.popupTemplate
just needs to return an HTML string, so feel free to use Handlebars or Underscore templates (instead of the terrible Array.join method above).
Bubbles in a core plugin that will render circles('bubbles') on different parts of the map. Each of these bubbles can be color coded in the same way a choropleth is color coded (see above 'Choropleth' example).
var bombMap = new Datamap({
element: document.getElementById('map_bombs'),
scope: 'world',
geographyConfig: {
popupOnHover: false,
highlightOnHover: false
},
fills: {
'USA': '#1f77b4',
'RUS': '#9467bd',
'PRK': '#ff7f0e',
'PRC': '#2ca02c',
'IND': '#e377c2',
'GBR': '#8c564b',
'FRA': '#d62728',
'PAK': '#7f7f7f',
defaultFill: '#EDDC4E'
},
data: {
'RUS': {fillKey: 'RUS'},
'PRK': {fillKey: 'PRK'},
'PRC': {fillKey: 'PRC'},
'IND': {fillKey: 'IND'},
'GBR': {fillKey: 'GBR'},
'FRA': {fillKey: 'FRA'},
'PAK': {fillKey: 'PAK'},
'USA': {fillKey: 'USA'}
}
});
var bombs = [{
name: 'Joe 4',
radius: 25,
yield: 400,
country: 'USSR',
fillKey: 'RUS',
significance: 'First fusion weapon test by the USSR (not "staged")',
date: '1953-08-12',
latitude: 50.07,
longitude: 78.43
},{
name: 'RDS-37',
radius: 40,
yield: 1600,
country: 'USSR',
fillKey: 'RUS',
significance: 'First "staged" thermonuclear weapon test by the USSR (deployable)',
date: '1955-11-22',
latitude: 50.07,
longitude: 78.43
},{
name: 'Tsar Bomba',
radius: 75,
yield: 50000,
country: 'USSR',
fillKey: 'RUS',
significance: 'Largest thermonuclear weapon ever tested—scaled down from its initial 100 Mt design by 50%',
date: '1961-10-31',
latitude: 73.482,
longitude: 54.5854
}
];
//draw bubbles for bombs
bombMap.bubbles(bombs, {
popupTemplate: function (geo, data) {
return ['<div class="hoverinfo">' + data.name,
'<br/>Payload: ' + data.yield + ' kilotons',
'<br/>Country: ' + data.country + '',
'<br/>Date: ' + data.date + '',
'</div>'].join('');
}
});
The first parameter to bubbles
should be an array of objects, each with at least 3 properties:
latitude
longitude
radius
Optionally, pass in fillKey
to color code the bubble, and pass in any other data you want to render in a popup template which can be overridden in the options parameter.
For further customization, you can set these properties on each bubble to override the options parameter (or default options):
borderColor
borderWidth
borderOpacity
fillOpacity
The second parameter is the options
param, where you can override any of the default options (documented below)
You can continue to call bubbles
on the same map instance and the map will auto update itself. Any bubble previously drawn that's not included in subsequent calls will be removed from the UI.
map.bubbles([])
will erase all bubbles.
For USA maps you can add 2 letter (i.e., NY, TX) labels to each state. To add labels, after created the map:
map.labels();
The following options are allowed:
labelColor
// Font color, default: #000lineWidth
// Line width for New England states, default: 1fontSize
// Font size, default: 10fontFamily
// Font family, default: 'Verdana'customLabelText
// Replaces 2 letter labels with customAn example for using the options:
map.labels({labelColor: 'blue', fontSize: 12});
An example for using the customLabelText
This accepts an object whose keys are uppercase 2 letter state codes. Values will be substituted for default label text Any missing values default to 2 state letters
newLabels = {'AK':'Alaska', 'AL':'123',.......};
map.labels({'customLabelText': newLabels});
Example custom-labels.html for using the customLabelText
You can override the default projection by setting your own setProjection(element)
function. Example here
var map = new Datamap({
scope: 'world',
element: document.getElementById('container1'),
setProjection: function(element) {
var projection = d3.geo.equirectangular()
.center([19, -3])
.rotate([4.4, 0])
.scale(400)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path()
.projection(projection);
return {path: path, projection: projection};
},
If jQuery is present on the page when the Datamaps library loads, it'll automatically create a jQuery plugin called datamaps
that can be used like:
<script>
$("#container").datamaps(options);
</script>
All events are bubbled up to the root svg
element and to listen to events, use the done
callback.
<script>
var map = new Datamap({
element: document.getElementById('container'),
done: function(datamap) {
datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography) {
alert(geography.properties.name);
});
}
});
</script>
Set responsive
to true
and then listen for resize
events on window
, and call Datamaps.prototype.resize
.
Avoid setting the height and width of the container
with hard pixel values, instead use percent values. (use 50%
instead of 500px
.
If the aspect ratio of your custom map is not the default 16:9
(0.5625
), you should use the aspectRatio
option to set it appropriately (eg. 0.3
for a 3:1
aspect ratio).
<div id="container"></div>
<script>
var map = new Datamap({
element: document.getElementById('container'),
responsive: true
});
// Pure JavaScript
window.addEventListener('resize', function() {
map.resize();
});
// Alternatively with d3
d3.select(window).on('resize', function() {
map.resize();
});
// Alternatively with jQuery
$(window).on('resize', function() {
map.resize();
});
</script>
{
scope: 'world', // Currently supports 'usa' and 'world', however with custom map data you can specify your own
setProjection: setProjection, // Returns a d3 path and projection functions
projection: 'equirectangular', // Style of projection to be used. try "mercator"
height: null, // If not null, datamaps will grab the height of 'element'
width: null, // If not null, datamaps will grab the width of 'element',
responsive: false, // If true, call `resize()` on the map object when it should adjust it's size
done: function() {}, // Callback when the map is done drawing
fills: {
defaultFill: '#ABDDA4' // The keys in this object map to the "fillKey" of [data] or [bubbles]
},
dataType: 'json', // For use with dataUrl, currently 'json' or 'csv'. CSV should have an `id` column
dataUrl: null, // If not null, datamaps will attempt to fetch this based on dataType ( default: json )
geographyConfig: {
dataUrl: null, // If not null, datamaps will fetch the map JSON (currently only supports topojson)
hideAntarctica: true,
hideHawaiiAndAlaska : false,
borderWidth: 1,
borderOpacity: 1,
borderColor: '#FDFDFD',
popupTemplate: function(geography, data) { // This function should just return a string
return '<div class="hoverinfo"><strong>' + geography.properties.name + '</strong></div>';
},
popupOnHover: true, // True to show the popup while hovering
highlightOnHover: true,
highlightFillColor: '#FC8D59',
highlightBorderColor: 'rgba(250, 15, 160, 0.2)',
highlightBorderWidth: 2,
highlightBorderOpacity: 1
},
bubblesConfig: {
borderWidth: 2,
borderOpacity: 1,
borderColor: '#FFFFFF',
popupOnHover: true, // True to show the popup while hovering
radius: null,
popupTemplate: function(geography, data) { // This function should just return a string
return '<div class="hoverinfo"><strong>' + data.name + '</strong></div>';
},
fillOpacity: 0.75,
animate: true,
highlightOnHover: true,
highlightFillColor: '#FC8D59',
highlightBorderColor: 'rgba(250, 15, 160, 0.2)',
highlightBorderWidth: 2,
highlightBorderOpacity: 1,
highlightFillOpacity: 0.85,
exitDelay: 100, // Milliseconds
key: JSON.stringify
},
arcConfig: {
strokeColor: '#DD1C77',
strokeWidth: 1,
arcSharpness: 1,
animationSpeed: 600, // Milliseconds
popupOnHover: false, // True to show the popup while hovering
popupTemplate: function(geography, data) { // This function should just return a string
// Case with latitude and longitude
if ( ( data.origin && data.destination ) && data.origin.latitude && data.origin.longitude && data.destination.latitude && data.destination.longitude ) {
return '<div class="hoverinfo"><strong>Arc</strong><br>Origin: ' + JSON.stringify(data.origin) + '<br>Destination: ' + JSON.stringify(data.destination) + '</div>';
}
// Case with only country name
else if ( data.origin && data.destination ) {
return '<div class="hoverinfo"><strong>Arc</strong><br>' + data.origin + ' -> ' + data.destination + '</div>';
}
// Missing information
else {
return '';
}
}
}
}
Contributing Guidelines
grunt build
task or submit any built files in your PR.src/examples
if adding a new feature. Copy an existing feature .html
file to start.Downloads:
Author: Markmarkoh
Source Code: https://github.com/markmarkoh/datamaps
License: MIT license
1656394080
Declarative Charting Framework for Angular!
ngx-charts is unique because we don't merely wrap d3, nor any other chart engine for that matter. It is using Angular to render and animate the SVG elements with all of its binding and speed goodness, and uses d3 for the excellent math functions, scales, axis and shape generators. By having Angular do all of the rendering it opens us up to endless possibilities the Angular platform provides such as AoT, SSR, etc.
Data visualization is a science but that doesn't mean it has to be ugly. One of the big efforts we've made while creating this project is to make the charts aesthetically pleasing. The styles are also completely customizable through CSS, so you can override them as you please.
Also, constructing custom charts is possible by leveraging the various ngx-charts components that are exposed through the ngx-charts module.
To use ngx-charts in your project install it via npm:
npm i @swimlane/ngx-charts --save
To learn how to use the ngx-charts components to build custom charts and find examples, please refer to our Custom Charts Page.
git checkout master
)git pull
)npm ci
)npm test
)git checkout -b release/X.Y.Z
projects/swimlane/ngx-charts/package.json
.projects/docs/changelog.md
git commit -am "(release): X.Y.Z"
git tag X.Y.Z
git push origin HEAD --tags
npm run publish:lib
ngx-charts
is a Swimlane open-source project; we believe in giving back to the open-source community by sharing some of the projects we build for our application. Swimlane is an automated cyber security operations and incident response platform that enables cyber security teams to leverage threat intelligence, speed up incident response and automate security operations.
SecOps Hub is an open, product-agnostic, online community for security professionals to share ideas, use cases, best practices, and incident response strategies.
For more info, check out the documentation and the demos.
Author: Swimlane
Source Code: https://github.com/swimlane/ngx-charts
License: MIT license
1656386580
nivo provides supercharged React components to easily build dataviz apps, it's built on top of d3.
Several libraries already exist for React d3 integration, but just a few provide server side rendering ability and fully declarative charts.
In order to use nivo, you have to install the @nivo/core
package and then choose some of the scoped @nivo
packages according to the charts you wish to use:
yarn add @nivo/core @nivo/bar
Join the nivo discord community.
nivo is comprised of several packages/components, for a full list, please use the Components Explorer.
Author: Plouc
Source Code: https://github.com/plouc/nivo
License: MIT license
1656284820
Vega: A Visualization Grammar
Vega is a visualization grammar, a declarative format for creating, saving, and sharing interactive visualization designs. With Vega you can describe data visualizations in a JSON format, and generate interactive views using either HTML5 Canvas or SVG.
For documentation, tutorials, and examples, see the Vega website. For a description of changes between Vega 2 and later versions, please refer to the Vega Porting Guide.
For a basic setup allowing you to build Vega and run examples:
https://github.com/vega/vega
.yarn
to install dependencies for all packages. If you don't have yarn installed, see https://yarnpkg.com/en/docs/install. We use Yarn workspaces to manage multiple packages within this monorepo.yarn test
to run test cases, or run yarn build
to build output files for all packages.yarn test
or yarn build
, run yarn serve
to launch a local web server — your default browser will open and you can browse to the "test"
folder to view test specifications.This repository includes the Vega website and documentation in the docs
folder. To launch the website locally, first run bundle install
in the docs
folder to install the necessary Jekyll libraries. Afterwards, use yarn docs
to build the documentation and launch a local webserver. After launching, you can open http://127.0.0.1:4000/vega/
to see the website.
For backwards compatibility, Vega includes a babel-ified ES5-compatible version of the code in packages/vega/build-es5
directory. Older browser would also require several polyfill libraries:
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.4.4/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/regenerator-runtime@0.13.3/runtime.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.0.0/dist/fetch.umd.min.js"></script>
Interested in contributing to Vega? Please see our contribution and development guidelines, subject to our code of conduct.
Looking for support, or interested in sharing examples and tips? Post to the Vega discussion forum or join the Vega slack organization! We also have examples available as Observable notebooks.
If you're curious about system performance, see some in-browser benchmarks. Read about future plans in our roadmap.
Author: Vega
Source Code: https://github.com/vega/vega
License: BSD-3-Clause license
1656062110
Britecharts is a client-side reusable Charting Library based on D3.js v5 that offers easy and intuitive use of charts and components that can be composed together to create amazing visualizations.
![]() | ![]() | ![]() |
---|---|---|
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
Britecharts components have been written in ES2016 with a Test Driven methodology, so they are fully tested, and we are committed to keeping them that way.
The typical use of Britecharts involves creating a chart using its simple API, then rendering it on a container which has previously had data applied to it. The code will look like this:
barChart
.width(500)
.height(300);
barContainer.datum(dataset).call(barChart);
All the components expose some common API methods like width, height, and margin. Additionally, each chart or component can expose specific methods you can find in the documentation:
Britecharts components are distributed in UMD modules, each one exposing a D3.js component written with the Reusable API pattern. To use any of the Britecharts modules, you will need to require the chart in your JS file using AMD/CommonJS modules or adding a script tag with the src
pointing to the file. You would also need to load the d3-selection submodule to select the chart container.
npm install britecharts d3-selection
You can also load Britecharts from our CDN as we do in this demo page or play around in our JSBin and CodePen demo projects.
They also provide some minimal CSS styling, that can be loaded independently or as a bundle. Check our Styling Britecharts tutorial to see more options.
This project is in active development. You can check our plans for the next release to see what's coming, and vote for your favorite proposals on the issues page.
To give your feedback, you can open a new issue. You can also find us in the D3.js slack group, in the #britecharts channel. If you want to help, you can check the contributing guide.
If you work with Angular, check out ngx-britecharts and their demos. We are also preparing a wrapper for React, and we will be talking about it on our twitter.
Sun Dai designs Britecharts, and two books inspired the code, Developing a D3.js Edge and Mastering D3.js. It also leveraged a significant number of examples and articles from the D3.js community overall.
Read more in the license document
Author: Britecharts
Source Code: https://github.com/britecharts/britecharts
License: Apache-2.0 license
1654951392
Avataar Generator in Dart
A package to generate svg in Dart that produces awesome emojis. This package can be used with Angular Dart, Flutter etc.
Add this to your project's pubspec.yaml
dependencies:
avataar_generator: any
Anywhere you want the svg string.
getSvg(new Options())
Options can be given different parameters.
Run this command:
With Dart:
$ dart pub add avataar_generator
With Flutter:
$ flutter pub add avataar_generator
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get
):
dependencies:
avataar_generator: ^1.1.2
Alternatively, your editor might support dart pub get
or flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:avataar_generator/enums.dart';
import 'package:avataar_generator/generator.dart';
import 'package:avataar_generator/methods/accessories.dart';
import 'package:avataar_generator/methods/clothes.dart';
import 'package:avataar_generator/methods/colors.dart';
import 'package:avataar_generator/methods/face.dart';
import 'package:avataar_generator/methods/tops.dart';
example/main.dart
import 'package:avataar_generator/generator.dart';
void main() {
print(getSvg(new Options()));
}
Author: Devslane
Source Code: https://github.com/devslane/Avataar-Generator
License: BSD-2-Clause license
1654673640
yUML to SVG
This project is a fork of jaime-olivares/yuml-diagram. You might want to check it out if you are more interested in a synchronous version of the API or you want to use an older version of Node.js.
Allows the creation of offline UML diagrams based on the yUML Syntax.
--experimental-modules
and --experimental-worker
CLI flags).You can install it with yarn:
yarn global add yuml2svg # For CLI usage
yarn add yuml2svg # As local dependency
Or with npm:
npm --global install yuml2svg # For CLI usage
npm install yuml2svg # As local dependency
Please refer to the wiki page.
You can use the package to transform yUML diagrams to SVG via the Command-Line Interface.
# You can install the package globally (or use npx)
yarn global add yuml2svg
# Prints SVG document on the standard output
yuml2svg < diagram.yuml
# Note: On Windows Powershell, you may need to use cat command instead
cat diagram.yuml | yuml2svg
# Save SVG file to the disk
yuml2svg < diagram.yuml > diagram.svg
# Save SVG file to the disk using dark mode
yuml2svg --dark < diagram.yuml > diagram.svg
The API exports a function that accepts as arguments:
Readable
stream, a Buffer
or a string
containing the yUML diagram.object
containing the options for the rendering.object
containing the options for Viz.js. Check it out if you are using this package in the browser.object
containing the render options for Viz.js.The API returns a Promise
which resolves in a string containing SVG document as a string
.
The options for the rendering are:
dir
:string
The direction of the diagram "TB" (default) - topDown, "LR" - leftToRight, "RL" - rightToLefttype
:string
The type of SVG - "class" (default), "usecase", "activity", "state", "deployment", "package", "sequence".isDark
:boolean
Option to get dark or light diagramdotHeaderOverrides
:object
Option to customize output (not supported for sequence diagram)Please check out Viz.js wiki to get more the documentation of the last two parameters.
Here are some examples of a simple usage you can make of the API:
import fs from "fs";
import yuml2svg from "yuml2svg";
/**
* Renders a string or a Buffer into SVG with dark mode
* @param {string | Buffer | Readable} yuml The yUML diagram
* @returns {Promise<string>} callback The SVG document that represents the yUML diagram
*/
const renderDarkSVG = yuml => yuml2svg(yuml, { isDark: true });
/**
* Renders a given file into a SVG string asynchronously
* @param {string} filePath Path to the yUML diagram
* @returns {Promise<string>} callback The SVG document that represents the yUML diagram
*/
const renderFile = filePath => yuml2svg(fs.createReadStream(filePath));
/**
* Renders a given file into a SVG string asynchronously
* @param {string} filePath Path to the yUML diagram
* @param {{dir:string, type: string, isDark: boolean}} [options]
* @param {object} [vizOptions] @see https://github.com/mdaines/viz.js/wiki/2.0.0-API
* @returns {Promise<string>} callback The SVG document that represents the yUML diagram
*/
const renderFileWithOptions = (filePath, options, vizOptions) =>
yuml2svg(fs.createReadStream(filePath), options, vizOptions);
/**
* Generates a SVG file from a yUML file
* @param {string} inputFile Path to the .yuml document to read
* @param {string} outputFile Path to the .svg file to write
* @returns {Promise<>} Promise that resolves once the SVG file is written
*/
const generateSVG = async (inputFile, outputFile) => {
const svg = await yuml2svg(fs.createReadStream(filePath));
return await fs.promises.writeFile(outputFile, svg);
};
N.B.: yuml2svg is written using ES modules, it means it cannot be required (require('yuml2svg')
will throw); although you still can use it from a CJS script using dynamic import:
var fs = require("fs");
/**
* Renders a given file into a SVG string asynchronously
* @param {string} filePath Path to the yUML diagram
* @param {(Error, string)=>any} callback Async callback
*/
function renderFile(filePath, callback) {
import("yuml2svg")
.then(function(module) {
var yuml2svg = module.default;
return yuml2svg(fs.createReadStream(filePath));
})
.then(function(svg) {
callback(null, svg);
})
.catch(callback);
}
You can find a working example of a browser implementation using webpack here: yuml2svg-playground.
If you want to use streams, pass a ReadableStreamDefaultReader
or ReadableStreamBYOBReader
object to the API:
import yuml2svg from "https://dev.jspm.io/yuml2svg@5";
const yumlOptions = {};
const vizOptions = {
workerURL:
"data:application/javascript,importScripts('https://unpkg.com/viz.js@2.1.2/full.render.js')",
};
fetch("https://raw.githubusercontent.com/aduh95/yuml2svg/master/test/test.yuml")
.then(response =>
response.ok
? yuml2svg(response.body.getReader(), yumlOptions, vizOptions)
: Promise.reject(response.text())
)
.then(svg =>
document.body.append(
new DOMParser().parseFromString(svg, "text/xml").documentElement
)
)
.catch(console.error);
Note: Only UTF-8 is supported when using streams.
Author: aduh95
Source Code: https://github.com/aduh95/yuml2svg
License: MIT license
1654607820
gulp-svgmin
With npm do:
npm install gulp-svgmin
import { src, dest } from 'gulp';
import svgmin from 'gulp-svgmin';
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin())
.pipe(dest('./out'));
export default defaultTask;
By default, gulp-svgmin
loads options from a svgo.config.js
file in your project. See the svgo’s configuration docs for more info on how to write one.
You can control which directory svgo
searches for svgo.config.js
with the cwd
option. Or you can use a different file name with the configFile
option.
import { src, dest } from 'gulp';
import svgmin from 'gulp-svgmin';
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin({
// Specify an absolute directory path to
// search for the config file.
cwd: '/users/admin/project/assets',
// This path is relative to process.cwd()
// or the 'cwd' option.
configFile: 'images/svg/config.js',
}))
.pipe(dest('./out'));
export default defaultTask;
Instead of using a config file, you can pass an object of svgo’s options to the gulp-svgmin
plugin. You will need to provide the config in comma separated objects, like the example below.
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin({
// Ensures the best optimization.
multipass: true,
js2svg: {
// Beutifies the SVG output instead of
// stripping all white space.
pretty: true,
indent: 2,
},
// Alter the default list of plugins.
plugins: [
// You can enable a plugin with just its name.
'sortAttrs',
{
name: 'removeViewBox',
// Disable a plugin by setting active to false.
active: false,
},
{
name: 'cleanupIDs',
// Add plugin options.
params: {
minify: true,
}
},
],
}))
.pipe(dest('./out'));
You can view the full list of plugins here.
By default, the plugins list given to the gulp plugin will alter the default list of svgo plugins. Optionally, you can specify your plugins and set the full
flag to true
to indicate that your plugins list should not be merged with the default list of plugins.
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin({
multipass: true,
// The plugins list is the full list of plugins
// to use. The default list is ignored.
full: true,
plugins: [
'removeDoctype',
'removeComments',
'sortAttrs',
// ...
],
}))
.pipe(dest('./out'));
To have per-file options, pass a function, that receives file
object and returns svgo
options. For example, if you need to prefix ids with filenames to make them unique before combining svgs with gulp-svgstore:
const defaultTask = () =>
src('src/*.svg')
.pipe(svgmin(function getOptions(file) {
const prefix = path.basename(
file.relative,
path.extname(file.relative)
);
return {
plugins: [
{
name: 'cleanupIDs',
parmas: {
prefix: prefix + '-',
minify: true,
},
},
],
};
}))
.pipe(svgstore())
.pipe(dest('./dest'));
Pull requests are welcome. If you add functionality, then please add unit tests to cover it.
If you have any difficulties with the output of this plugin, please use the SVGO tracker.
Author: Ben-eb
Source Code: https://github.com/ben-eb/gulp-svgmin
License: MIT license
1654015740
websafe_svg
A Flutter compatible library to handle SVGs for Android, iOS, and Web.
Add the repo to your Flutter pubspec.yaml
file.
dependencies:
websafe_svg: <<version>>
Then run...
flutter packages get
asset
network
memory
string
import 'package:websafe_svg/websafe_svg.dart';
...
Widget build(BuildContext context) {
return WebsafeSvg.asset(...);
}
Run this command:
With Flutter:
$ flutter pub add websafe_svg
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
websafe_svg: ^2.1.1+1
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:websafe_svg/websafe_svg.dart';
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:websafe_svg_example/src/animation_page.dart';
import 'src/asset_svg_page.dart';
import 'src/memory_svg_page.dart';
import 'src/network_svg_page.dart';
import 'src/string_svg_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebsafeSvg Example'),
),
body: ListView(
children: [
ListTile(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => AnimationPage(),
),
),
title: Text('Animation'),
),
ListTile(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => AssetSvgPage(),
),
),
title: Text('Assets'),
),
ListTile(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MemorySvgPage(),
),
),
title: Text('Memory'),
),
ListTile(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => NetworkSvgPage(),
),
),
title: Text('Network'),
),
ListTile(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => StringSvgPage(),
),
),
title: Text('String'),
),
],
),
);
}
}
Author: Peiffer-innovations
Source Code: https://github.com/peiffer-innovations/websafe_svg
License: MIT license
1653730740
jest-snapshots-svg
Take a React Native component tree, and render it into an SVG.
// _tests/render.test.tsx
import * as React from "react"
import { Text } from "react-native"
import * as renderer from "react-test-renderer"
import "jest-snapshots-svg"
describe("Fixtures", () => {
it("does some simple JSX", () => {
const component = renderer.create(<Text />).toJSON()
expect(component).toMatchSnapshot()
expect(component).toMatchSVGSnapshot(480, 640)
})
})
Would make:
src/_tests/
├── __snapshots__
│ ├── render.test.tsx.snap
│ └── render.test.tsx-does-some-simple-jsx.svg
└── render.test.tsx
It does this by emulating the rendering process of React Native by calling yoga-layout directly in your tests, then converting the output of the layout-pass into SVG items that can easy be previewed in GitHub.
👍
Your code | The final SVG |
---|---|
Write your normal Jest snapshot tests, but use
| ![]() |
Then you run your tests. yarn jest . | |
Then you get SVG output in the
|
If you use <Text />
elements, you must have access to the font files so we can lay the text out. Usually, this just means having the font installed. However, if this goes wrong, this can be done manually via the loadFont
function, where you pass in the font file as a buffer. If you need a fallback, you can use addFontFallback
. If you just want to be able to specify the default fontFamily to use, you can use setDefaultFont
.
import { addFontFallback, loadFont, setDefaultFont } from "jest-snapshots-svg"
setDefaultFont("DejaVu Sans")
loadFont(fs.readFileSync("your-font-file.ttf"))
addFontFallback("Your Font", "'Helvetica', 'Arial', sans-serif")
This should be able to determine the fontFamily
, fontWeight
, and fontStyle
. However, if it's wrong, or it failed, you can pass these in as a second argument.
loadFont(fs.readFileSync("your-font-file.ttf"), {
fontFamily: "Helvetica",
fontWeight: "normal",
fontStyle: "normal"
})
If you have a .ttc
file (a collection of multiple files), and it fails to correctly guess the font style parameters, you can provide a postscriptName
in the style object to target a specific font. Do this in combination with passing in the font style arguments. See more about this over at fontkit.
An alternative way to load a font is to use the addFontToSvg
function instead of the normal loadFont
. This takes as input the path (can be a node_modules import reference) to load the font from, plus optionally the normal font style information that loadFont takes. Loading the font this way means that we can keep a reference to the file path that the font was loaded from, and then embed the path to the font into the svg in a css style definition.
addFontToSvg("@expo/vector-icons/fonts/FontAwesome.ttf")
Any fonts loaded using addFontToSvg
will be checked against the list of actual fonts used in Text styles in the component. Only those that have actually been used in the rendered component will be output into the svg.
In order for the above to work with the vector icons, you will need to create a test mock file for these packages. The default output from react-test-renderer does not include the actual character codes to display, which means that it cannot be captured from the rendered component to add to the svg. The file should be added to the __mocks__
directory next to the node_modules directory, and should have the same name/path as the module it is replacing.
For a typical project with the node_modules directory in the project root directory you should create a file <project_root>/__mocks__/@expo/vector-icons.js
(or ts if you are using typescript) for mocking @expo/vector-icons. For react-native-vector-icons the mock file should be <project_root>/__mocks__/react-native-vector-icons.js
.
In the mock file, you need to set the render function to return a Text component, with the font style details set to match the icon font and the text itself set to the unicode reference for the particular character that should be displayed for that icon.
An example mock for @expo/vector-icons could be (written in typescript):
import * as fs from "fs"
import { addFontToSvg } from "jest-snapshots-svg"
import * as React from "react"
import { StyleProp, StyleSheet, Text, TextStyle } from "react-native"
import { IconProps } from "react-native-vector-icons/Icon"
const glyphmapDir = "@expo/vector-icons/vendor/react-native-vector-icons/glyphmaps"
const fontDir = "@expo/vector-icons/fonts"
export const createIconSet = (
glyphMap: { [name: string]: string | number },
fontFamily: string,
fontFile?: string) =>
{
const filename = require.resolve(`${fontDir}/${fontFamily}.ttf`)
addFontToSvg(filename, { fontFamily, fontStyle: "normal", fontWeight: "normal" })
class Icon extends React.Component<IconProps, any> {
static loadFont() {
console.log("called Icon:loadFont()")
}
static getImageSource() {
console.log("called Icon.getImageSource()")
}
render() {
const { name, size, color, style, ...props } = this.props
let glyph = name ? glyphMap[name] : undefined
if (typeof glyph === "number") {
glyph = String.fromCodePoint(glyph);
}
const styleDefaults: TextStyle = {
fontFamily,
fontSize: size,
fontWeight: "normal",
fontStyle: "normal",
color
}
return (
<Text {...props} style={[styleDefaults, style]}>
{`&#x${glyph
.codePointAt(0)
.toString(16)
.toUpperCase()};`}
</Text>
);
}
}
return Icon
}
export const createIconSetFromFontello = jest.fn()
export const createIconSetFromIcoMoon = jest.fn()
// If you know you're only going to use a few/one of these fonts, you can safely
// remove any you won't use.
export const Entypo = createIconSet(
require(`${glyphmapDir}/Entypo.json`),
"Entypo"
)
export const EvilIcons = createIconSet(
require(`${glyphmapDir}/EvilIcons.json`),
"EvilIcons"
)
export const Feather = createIconSet(
require(`${glyphmapDir}/Feather.json`),
"Feather"
)
export const FontAwesome = createIconSet(
require(`${glyphmapDir}/FontAwesome.json`),
"FontAwesome"
)
export const Foundation = createIconSet(
require(`${glyphmapDir}/Foundation.json`),
"Foundation"
)
export const Ionicons = createIconSet(
require(`${glyphmapDir}/Ionicons.json`),
"Ionicons"
)
export const MaterialCommunityIcons = createIconSet(
require(`${glyphmapDir}/MaterialCommunityIcons.json`),
"MaterialCommunityIcons"
)
export const MaterialIcons = createIconSet(
require(`${glyphmapDir}/MaterialIcons.json`),
"MaterialIcons"
)
export const Octicons = createIconSet(
require(`${glyphmapDir}/Octicons.json`),
"Octicons"
)
export const SimpleLineIcons = createIconSet(
require(`${glyphmapDir}/SimpleLineIcons.json`),
"SimpleLineIcons"
)
export const Zocial = createIconSet(
require(`${glyphmapDir}/Zocial.json`),
"Zocial"
)
For react-native-vector-icons, change the glyphmapDir
and fontDir
paths:
const glyphmapDir = "react-native-vector-icons/glyphmaps"
const fontDir = "react-native-vector-icons/Fonts"
This is definitely pre-1.0, we only have it working on a few tests in artsy/emission. Expect alpha quality style snapshots for a while, but more people working on it will mean we all get a better chance at it working out well.
OK, you need to clone this repo:
git clone https://github.com/jest-community/jest-snapshots-svg.git
There's the usual stuff, yarn test
and yarn lint
.
If you want to work against your own projects, then you need to set it up for linking and turn on watch mode.
yarn watch # starts a server, so make a new tab for the next bits
yarn link
cd [my_project]
yarn link jest-snapshot-svg
Now your project is using the dev version of this.
Author: jest-community
Source Code: https://github.com/jest-community/jest-snapshots-svg
License: MIT license
1653280980
HeroIcons
heroicons port to Flutter. This package renders the icons as SVG pictures.
class MyExampleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return HeroIcon(
HeroIcons.calendar,
solid: false, // Outlined icons are used by default.
color: Colors.red,
size: 30,
);
}
}
Add heroicons
package into your pubspec.yaml
.
dependencies:
heroicons: # Latest version
You can also run flutter pub add heroicons
to quickly add latest version from your CLI.
Run source code generation to create heroicons.dart
file with named constructor for every icon.
dart tool/generator.dart
Run this command:
With Flutter:
$ flutter pub add heroicons
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
heroicons: ^0.5.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:heroicons/heroicons.dart';
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:heroicons/heroicons.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
iconTheme: IconThemeData(
color: Colors.red,
),
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: IconTheme(
data: IconThemeData(color: Colors.black),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
HeroIcon(HeroIcons.arrowLeft),
HeroIcon(HeroIcons.arrowRight),
HeroIcon(HeroIcons.calendar),
HeroIcon(HeroIcons.arrowLeft, solid: true),
HeroIcon(HeroIcons.arrowRight, solid: true),
HeroIcon(HeroIcons.calendar, solid: true),
],
),
),
),
);
}
}
Author: Vaetas
Source Code: https://github.com/vaetas/heroicons
License: MIT license
1653248460
React Native Vector Image
iOS/Android native vector assets generated from SVG.
react-native-svg
.yarn add react-native-vector-image @klarna/react-native-vector-drawable
Edit android/app/build.gradle
to look like this (without the +):
project.ext.react = [
enableHermes: false, // clean and rebuild if changing
]
apply from: "../../node_modules/react-native/react.gradle"
+ apply from: "../../node_modules/react-native-vector-image/strip_svgs.gradle"
Open your project in Xcode, select the Build Phases tab, and edit the Bundle React Native code and images
script to look like this (without the +):
set -e
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
+ ../node_modules/react-native-vector-image/strip_svgs.sh
Since native vector assets cannot be served over http via metro dev server, they must be generated and compiled into the app bundle.
import VectorImage from 'react-native-vector-image';
const App = () => <VectorImage source={require('./image.svg')} />;
To add dark mode to your image, create a new file with an .dark.svg
extension, ie image.svg
= light and image.dark.svg
= dark.
This takes a while as metro has to go through all the code to find the imported SVGs.
yarn react-native-vector-image generate
Argument | Description | Default |
---|---|---|
--entry-file | Path to the app entrypoint file. | index.js |
--config | Path to the metro config file. | metro.config.js |
--reset-cache | Reset metro cache before extracting SVG assets. | false |
--ios-output | Path to an iOS .xcassets folder. | ios/AppName/Images.xcassets |
--no-ios-output | Disable iOS output. | false |
--android-output | Path to an Android res folder. | android/app/src/main/res |
--no-android-output | Disable Android output. | false |
yarn react-native run-ios
# or
yarn react-native run-android
generate
command outputs "Error while parsing image.svg"Some optimizations applied by SVGO are not compatible with the SVG parser on Android. Try to re-export the SVG without optimizing it.
<VectorImage />
warns "Could not find image"It means that the native vector asset does not exist or is out of sync with the SVG. Simply generate the files and recompile the app.
Author: Oblador
Source Code: https://github.com/oblador/react-native-vector-image
License: MIT license
1653187320
react-svg-pan-zoom
react-svg-pan-zoom is a React component that adds pan and zoom features to the SVG images. It helps to display big SVG images in a small space.
This component can work in four different modes depending on the selected tool:
npm install --save react-svg-pan-zoom
yarn add react-svg-pan-zoom
<script src="https://unpkg.com/prop-types@15/prop-types.js"></script>
<script src="https://unpkg.com/react-svg-pan-zoom@3"></script>
<ReactSVGPanZoom>
.<UncontrolledReactSVGPanZoom>
.setPointOnViewerCenter
, reset
methods and className
, style
propsauto
, improves default toolbarpreventPanOutside
and scaleFactor
propsminiatureBackground
, miniatureHeight
, Minor improvements & fixdisableDoubleClickZoomWithToolAuto
scaleFactorOnWheel
, Upgrades depsscaleFactorMax
, scaleFactorMin
props (#71), Upgrades depsonPan
and onZoom
callbacks, Upgrade deps, Fixes boundaries featuretoolbarProps.SVGAlignX
and toolbarProps.SVGAlignY
props. Adds alignment configuration in fitToViewer(SVGAlignX = "left", SVGAlignY = "top")
method (#120). Upgrades deps.<UncontrolledReactSVGPanZoom />
component and makes <ReactSVGPanZoom>
a stateless component (except for some optimizations); Moves props related to miniature and toolbar, respectively into the miniatureProp
and toolbarProp
props. Migration guide is available here.fitToViewer
method #167, adds activeToolColor
property #168, upgrades depsavailable at http://chrvadala.github.io/react-svg-pan-zoom/
Author: Chrvadala
Source Code: https://github.com/chrvadala/react-svg-pan-zoom
License: MIT license