How can I change react-map-gl icons? - user-interface

I'm trying to customize my web application's map, I'm using react-map-gl (Uber opensource code) I try to change the map's icon pins but I could not figure out, what does the string code ICON mean?
import React, { PureComponent } from 'react';
const ICON = M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3
c0,0,0.1,0.1,0.1,0.2c0.2,0.3,0.4,0.6,0.7,0.9c2.6,3.1,7.4,7.6,7.4,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9
C20.1,15.8,20.2,15.8,20.2,15.7z;
const pinStyle = {
cursor: 'pointer',
fill: '#d00',
stroke: 'none'
};
export default class CityPin extends PureComponent {
render() {
const { size = 20, onClick } = this.props;
return (
<svg
height={size}
viewBox="0 0 24 24"
style={{ ...pinStyle, transform: `translate(${-size / 2}px,${-size}px)` }}
onClick={onClick}
>
<path d={ICON} />
</svg>
);
}
}
What does it mean all those numbers in ICON const? How can I change the style based on this code? Please help, thanks :)

All of the gibberish that is the ICON constant is SVG Path notation and is actually drawing your current symbol. If you want to learn more about it, here is another resource. There are even websites that can help you build your own SVG path string, Option 1 Option 2, and searching the web will pull up many more.
Note that you likely need to update the viewbox numbers to fit your new thing once you have the symbol you want. It otherwise chops off the symbol at those dimensions.
In trying to figure this out, my example update was:
const ICON = 'm 10 35 l 15 30 l 15 -30 A 20 20 180 1 0 10 35 z'
with a viewbox in the svg tag of:
viewBox="-8 0 55 65"
EDIT:: you can also use any image as explained in the other answers. There is an article on using custom images at Medium with a good explanation and more details.

You mentioned you're using react-map-gl, so you could use the Marker component to change your icon pins.
Is there a specific image you'd like to use for your icons, say a .png file? If so, add that image to the directory called "public." Then, in your map where you create the markers, you can display this specific image.
For example, if you have an image called mapicon.png, you'd add that to your public folder. Then, when you're creating your markers, you could do something like this.
import ReactMapGL, {Marker} from 'react-map-gl';
<Marker key={} latitude={} longitude={}>
<img
src="mapicon.png"
alt="map icon"
/>
</Marker>
From what I understand, the string is just a reference to where the icon image is stored. Hope this helps!

You can create a custom map marker with an SVG file. If you are using create-react-app, you can import your svg icon as a component like this:
import { ReactComponent as Pin } from '../../images/map-marker-icon.svg';
Then, in your example code above you can replace the
<path d={ICON} />
with this component. Here is an example:
export default class MapPin extends PureComponent {
render() {
<Marker longitude={this.props.longitude} latitude=this.props.latitude}>
<svg
onClick={() => onClick()}
viewBox="0 0 60 100"
enable-background="new 0 0 60 100">
<Pin/>
</svg>
</Marker>
));
}
}

Related

In Storybook theming for brandImage how to change logo height or width?

Within Storybook's manager.js when changing the theme I've found the documentation where you can add a custom logo with:
import { create } from '#storybook/theming'
import logo from '../src/images/logo.png'
export default create({
brandImage: logo,
})
However I've been unable to find a way to adjust the logo size of a PNG. From my research it seems the only way to adjust the size is to implement a width or height in the SVG:
logo.svg:
<svg width="100" height="40" viewBox="0 0 290.72 112.41" [...]
maanger.js:
import { create } from "#storybook/theming"
import logo from "../src/logo.svg"
export default create({
brandImage: logo,
})
I'm unable to find a way in the docs (params or themeing) if there is a way to set the width or height of a PNG.
Research
Storybook change logo
Link to brandImage not working
Custom theme brand image not being displayed in the Sidebar
Storybook's styling overrides all
In Storybook is there a way when using a PNG for brandImage I can adjust the width or height without having to implement it as a SVG?

How to change the height of d3 observable notebook embed

so I understand that I can change the fixed width instead of a responsive width, by importing Library, then re-assigning the width value. But I also want to change the height and including ,height: 500 doesn't seem to work. What am I doing wrong and what other way is there to embed the d3 observable notebook chart with customizable width and height without using an iframe?
<div class="chart"></div>
<p>Credit: <a href="https://observablehq.com/#tripletk/mmcovid19-confirmedcases">Myanmar COVID-19 Total Lab
Confirmed Cases by Timmy Kyaw</a></p>
<script type="module">
import {
Runtime,
Inspector,
Library
} from "https://cdn.jsdelivr.net/npm/#observablehq/runtime#4/dist/runtime.js";
const runtime = new Runtime(Object.assign(new Library, {
width: 500
}));
import define from "https://api.observablehq.com/d/1adf72a9a09835c3.js?v=3";
const main = runtime.module(define, name => {
if (name === "chart") return Inspector.into(".chart")();
});
</script>
Width works differently than height in Observable notebooks. You’ve already found how to change width: it’s a reactive variable that you can override with a constant like you’re doing; by default it uses with width of the document body.
For height, or any other value you want to inject like data or zipCode, you should use main.redefine("height", 500). (I’m using 200 in the example below, just change it to 500.)
<div class="chart"></div>
<p>Credit: <a href="https://observablehq.com/#tripletk/mmcovid19-confirmedcases">
Myanmar COVID-19 Total Lab Confirmed Cases by Timmy Kyaw</a></p>
<script type="module">
import {
Runtime,
Inspector,
Library
} from "https://cdn.jsdelivr.net/npm/#observablehq/runtime#4/dist/runtime.js";
const runtime = new Runtime(Object.assign(new Library, {
width: 500
}));
import define from "https://api.observablehq.com/d/1adf72a9a09835c3.js?v=3";
const main = runtime.module(define, name => {
if (name === "chart") return Inspector.into(".chart")();
});
main.redefine("height", 200)
</script>
Often it’s useful to make the figure fill an enclosing div instead of hardcoding a width and height: see this example of that approach. Also for reference, the docs have more information about both the redefine and new Library techniques.

CKEditor 5 single instance height

I have multiple instances of CKEditor 5 and I want to add button which will change the height of texteditor. In order to do so I have to change height of a single instance, is that possible and if yes, how?
Side note:
I want to make maximize button like in CKEditor 4. Is there plugin for that or I have to make it myself?
Maximize Feature - From what I have checked it has not been implemented yet. CKEditor has a ticket ofr it: https://github.com/ckeditor/ckeditor5/issues/1235
Editor Height - This link explains How to set the height of CKEditor 5 (Classic Editor) explains how to do this permanently. If however you want to do change editor height dynamically with a button, you need to use a small trick where you assign a CSS class not directly to content area but to its container (notice .ck-small-editor .ck-content in css class and document.getElementsByClassName( 'ck-editor' )[ 0 ] in JavaScript ):
ClassicEditor
.create( document.querySelector( '#editor' ), {
} )
.then( editor => {
window.editor = editor;
// Assign small size to editor using CSS class in styles and button in HTML
const editable = editor.ui.getEditableElement();
document.getElementById( 'change-height' ).addEventListener( 'click', () => {
document.getElementsByClassName( 'ck-editor' )[ 0 ].classList.toggle( 'ck-small-editor' );
} );
} )
.catch( err => {
console.error( err.stack );
} );
.ck-small-editor .ck-content {
min-height: 50px !important;
height: 50px;
overflow: scroll !important;
}
<script src="https://cdn.ckeditor.com/ckeditor5/12.0.0/classic/ckeditor.js"></script>
<div id="editor">
<h2>The three greatest things you learn from traveling</h2>
<p>Like all the great things on earth traveling teaches us by example. Here are some of the most precious lessons I’ve learned over the years of traveling.</p>
<h3>Appreciation of diversity</h3>
<p>Getting used to an entirely different culture can be challenging. While it’s also nice to learn about cultures online or from books, nothing comes close to experiencing cultural diversity in person. You learn to appreciate each and every single one of the differences while you become more culturally fluid.</p>
<h3>Confidence</h3>
<p>Going to a new place can be quite terrifying. While change and uncertainty makes us scared, traveling teaches us how ridiculous it is to be afraid of something before it happens. The moment you face your fear and see there was nothing to be afraid of, is the moment you discover bliss.</p>
</div>
<div>
<button type="button" id="change-height">Change Height</button>
</div>

On hover effect on a SVG group

I'm working on a pretty big map with lots of different areas and text on top of them, sort of like countries. I want to add a on mouse hover effect when hovering over this area. The effect should add a shadow and change its opacity. When I hover out of the area the opacity should go back to its original and the shadow effect should go away. I managed to do this but when I add text into this area it messes things up. The on hover effect gets called again when I hover on the text that's inside area when it shouldn't be called again at all. I made a fiddle that works until i hover on the text as well. I'm using the D3.js library for the coding.
var groupAreas = "";
groupAreas = d3.selectAll(".area-group");
groupAreas.on("mouseover", fadeInArea)
.on("mouseout", fadeOutArea)
.on("click", zoomIn);
var initialOpacity = 0;
function fadeInArea() {
//Get its initial opacity
initialOpacity = d3.select(this).select("path").style("opacity");
d3.select(this).transition(500).attr("filter", "url(#shadow-filter-1)").style("cursor", "pointer");
d3.select(this).select("path").transition(500).style("opacity", 0.7);
}
function fadeOutArea() {
d3.select(this).transition(500).attr("filter", null).style("cursor", "default");
d3.select(this).select("path").transition(500).style("opacity", initialOpacity);
}
https://jsfiddle.net/qx5u9uo4/6/
the area has an original opacity of 0.4. When i hover over the area it changes to 0.7 and the shadow effect is added. When I go out, it goes back to 0.4 as it should. Yet if i go in the area and also hover over the text the OnMouseOver gets called again and it then sets 0.7 as original opacity and thus never goes back to 0.4 again when I actually go outside the area.
I think the problem may lie with my order of DOM svg elements?
<g class="area-group">
<path id="area-1" d="M502.2 581.4h-53.5v-61l167.4 70.4v34.6H502.2z" />
<text transform="translate(542.4 614)"> FOO </text>
<text transform="translate(459.4 571.2)"> BAR </text>
<text transform="translate(521.1 592.9)"> / </text>
</g>
Sounds like you just want to stop the text elements from receiving pointer events:
.area-group>text {
pointer-events: none;
}

Wrong SVGSVGElement width in Firefox

On th following document:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd">
<svg width = "100%"
height = "100%"
id="pic"
version="1.1"
style="background-color:blue"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
I'm trying to get the width value of the root SVGSVGElement:
document.getElementById ("pic").width.baseVal.value
Chromium says: 969
Firefox says: 1
Sure value maybe a little implementation dependent, but (what indeed must be independent) when i try to get a converted value:
var w = evt.target.width.baseVal;
w.convertToSpecifiedUnits (5);
alert(w.valueInSpecifiedUnits);
chrome gives again 969, but Firefox' answer is 1.
I need this value to adjust some elements in my scripts, but they don't work in Firefox.
How can i obtain the real value of width?
This is the way I got it to give consistent values cross-browser:
This was the way I fixed it:
var heightComponents = ['height', 'paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth'],
widthComponents = ['width', 'paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'];
var svgCalculateSize = function (el) {
var gCS = window.getComputedStyle(el), // using gCS because IE8- has no support for svg anyway
bounds = {
width: 0,
height: 0
};
heightComponents.forEach(function (css) {
bounds.height += parseFloat(gCS[css]);
});
widthComponents.forEach(function (css) {
bounds.width += parseFloat(gCS[css]);
});
return bounds;
};
Not very pretty, but works.
2 years later this is still an issue..
I found a temporary solution:
var style = window.getComputedStyle(svg,null);
var svgWidth = style.getPropertyValue("width").slice(0, -2); // "1240px" -> "1240"
but in my case this is very expensive and the browser gets super slow..
so, has anyone got a better solution?
I also tried to convert "the magic 1" into a pixel width following this article:
https://developer.mozilla.org/en/docs/Web/API/SVGLength
but no luck either..
From Firefox 33 onwards you will be able to use getBoundingClientRect to get the width/height you want. Firefox 33 will be released on 14th October 2014 but you could try a nightly right now if you want to.

Resources