Use images instead of svg circle (react-d3-tree) - reactjs

I recently updated to version 2.0.1 and I am struggling to set images instead of svg circles to individual nodes. In the older versions I used nodeSvgShape property:
nodeSvgShape: {
shape: 'image',
shapeProps: {
href: AppState.config.api.img + mainTile.image,
width: 100,
height: 100,
x: -50,
y: -17,
},
},
However in the current version this does nothing. Is there any way how can I achieve this in the current version?
Thank you in advance

If you are still having this issue after a year, here is how I did this.
I was able to do this with other SVG images by using the renderCustomNodeElement properties of the Tree component. By passing a render function that you create, you are able to apply the render function to each node (found on the docs here: https://www.npmjs.com/package/react-d3-tree#styling-nodes ).
Below is an example of how to implement it, say using an object that maps the name of the node to an SVG string and then passing that to the Tree component:
import SVG from 'react-inlinesvg';
const renderMol = ({ nodeDatum, toggleNode }) => (
<g>
<SVG src={svgMapping[nodeDatum.name]}/>
</g>
);
return (
<Tree data={mydata}
renderCustomNodeElement={nameOrMol} />
)

Related

React.js. How to pass local images dynamicly according to id property?

I have a little problem. I don't know how to pass this local images dynamicly.
Lets say I have API which returns static 6 store schema like that.
stores: [{id:1, name: "Wallmart"}, {id: 2, name: "Amazon"}];
and I have some images called store1.jpg, store2.jpg ...etc.
So I import images like that.
import store1 from "./store1.jpg"
So I need to loop these images dynamicly according to id.
{
stores.map((store) => (
<img src={`store${store.id}`} />
)
}
So, My question is what is best way to do that. maybe I can create some object which contains all images or import all images like that. I didn't check this version maybe it's not working at all. It doesn't looks like proper way. Can someone just advice me something who have experinced with that ?
Forget about importing the images, and just downright use the path to the images in the stores.map function.
<img src={"store" + store.id + ".jpg"} />
I found this type of solution because I figure out that I also have colors. I add all my images into public/images folder
export const stores : any = {
store1:{
id: 1,
src: "/images/store1.png",
tertiary: "#000",
primary: "#FFF",
},
store2:{
id: 2,
src: "/images/store2.png",
tertiary: "#999",
primary: "#aaa",
}
...
}
so I import stores and loop like that.
import {stores} from "./constants"
{
store.map((item:any) => (
<StoreCatalogCard
title={item.name}
img={stores[`store${item.id}`].src}
primaryColor={stores[`store${item.id}`].primary}
tertiaryColor={stores[`store${item.id}`].tertiary}
light={true}
/>
))
}

Mapbox react - Display route with adjustments to nearest road using list of location points

I'm using mapbox with the wrapper react-map-gl.
I'm trying to draw a route with my array of lat lang points,
I found a partial solution from:
https://github.com/visgl/react-map-gl/issues/591#issuecomment-454307294
The issue is that the presented route doesn't match the nearest road.
The current route is the green line and I'm trying to change it to be like the orange line
The best solution I have found is to use the react-map-gl with the deck.gl libraries.
decl.gl,
react-map-gl
install the libraries
Create a function using the Matching API from Mapbox:
https://docs.mapbox.com/help/tutorials/get-started-map-matching-api/#add-the-map-matching-api
Use the geometries=geojson option param (inside the URL of the matching call)
return the geometry object from Matching API response (data.matchings[0].geometry)
Create GeoJsonLayer with the new geometry object:
const layerRoute = new GeoJsonLayer({
id: "geojson-layer",
data: getMatchingGeometry(),
filled: true,
stroked: false,
extruded: true,
pickable: true,
lineJointRounded: true,
getRadius: 50,
getElevation: 30,
lineWidthScale: 20,})
Add the new layer to your map:
return (
<DeckGL layers={[layerRoute]} initialViewState={{ ...initialView }} controller={true}>
<StaticMap
height={height}
width={width}
mapStyle={mapboxstyle}
mapboxApiAccessToken={API_TOKEN}
/>
</DeckGL>)

How to animate dynamic updates in CanvasJS using React functional components?

Using React functional components, I have not been able to find a way to animate my chart with dynamic data received asynchronously. The sandbox below illustrates the problem with a timer simulating the asynchronous read.
https://codesandbox.io/s/basic-column-chart-in-react-canvasjs-0gfv6?fontsize=14&hidenavigation=1&theme=dark
When running the example code, you should see 5 vertical bars of increasing heights animate. Then, after 5 seconds, it switches immediately to 4 bars of descending heights. I am looking to have that update animate.
Here is some reference information I've reviewed:
CanvasJS React Demos: many of which animate on initial draw, but I couldn't find one that animates with dynamic data loaded after the initial render.
Chart using JSON Data is an demo that has dynamic data, but doesn't animate.
Reviewing the CanvasJS forum, I found a couple links, but none that address React functional components
Vishwas from Team Canvas said:
To update dataPoints dynamically and to animate chart, you can instantiate the chart, update dataPoints via chart-options and then call chart.render as shown in this updated JSFiddle.
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Animation test"
},
animationEnabled: true,
data: [{
type: "column",
dataPoints: []
}]
});
chart.options.data[0].dataPoints = [{ label: "Apple", y: 658 },
{ label: "Orange", y: 200 },
{ label: "Banana", y: 900 }];
chart.render();
This sample is pure JS, but I tried to adapt the principle to my React functional component. To better comport with React best practices, I incorporated the useState hook for storing the data and the useEffect hook to handle the fetch. But, alas, I couldn't get my sandbox to animate with the dynamic data.
I think the problem is that CanvasJS expects to animate only on the first render, as stated by Sanjoy in the CanvasJS forum on 7/19/2016.
I found this SO question from Jan 2015 that suggests:
My current ugly workaround is to reinstantiate the chart every time I
update just to achieve that animation effect.
I'm hopeful that the situation has improved in the last four years, but if this hack is still the best/only way to go, I need some guidance on how to reinstantiate the chart every time using a React functional component.
To force a remount of a component pass a different key when you want to remount the component
<CanvasJSChart
key={dataPoints.toString()} // force a remount when `dataPoints` change
containerProps={containerProps}
options={options}
onRef={ref => (chart.current = ref)}
/>
Working example
I found a partial answer. Full executing code is in this code sandbox, but the critical bit is to delay the initial render of the chart until a state variable indicates that the data is available:
return (
<div className="App">
{!initialized ? (
<h1> Loading...</h1>
) : (
<CanvasJSChart containerProps={containerProps} options={options} />
)}
</div>
);
This is only a partial solution because subsequent data updates still do not animate.
Both examples works fine.
You can always animate chars with some kind of calling. I use in this case setInterval.
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script>
var chart;
window.onload = function () {
chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Animation test"
},
animationEnabled: true,
data: [{
type: "column",
dataPoints: []
}]
});
chart.options.data[0].dataPoints = [{ label: "Apple", y: 0 },
{ label: "Orange", y: 0 },
{ label: "Banana", y: 0 }];
chart.render();
}
var max = 0;
var s = {c: 0, i: 0};
function ANIMATE() {
if (typeof chart === 'undefined') return;
chart.options.data[0].dataPoints.forEach(function(item, index, array) {
if (index == s.i) {
array[index].y += 3;
s.c++;
}
if (s.c > 12) {
s.i++;
s.c = 0;
if (s.i == 15) { s.i = 0}
}
});
if (max < 12) {
chart.options.data[0].dataPoints.push({label: "apple" + Math.random(), y: 1 + Math.random() * 10});
max++;
}
chart.render()
}
setInterval(function(){
ANIMATE()
}, 1)
</script>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>

gl-react-expo shader with external image texture input

I'm trying to use gl-react-expo shaders to apply some effects on some images in an Expo project. The images are from an external url (like http://i.imgur.com/rkiglmm.jpg).
I can make simple shaders that don't use a texture input, and it works perfectly. But I am not finding the correct way to pass the image to the shader. I'm trying to implement the DiamondCrop example from this site (http://greweb.me/2016/06/glreactconf/) and all the other simple examples that I found that passes an image to the shader. But none of them work.
This is my shader definition:
import React from "react";
import { Shaders, Node, GLSL } from "gl-react";
const frags = {
diamond: GLSL`
precision highp float;
varying vec2 uv;
uniform sampler2D t;
void main () {
gl_FragColor = mix(
texture2D(t, uv),
vec4(0.0),
step(0.5, abs(uv.x - 0.5) + abs(uv.y - 0.5))
);
}`
}
const shaders = Shaders.create({
DiamondCrop: {
frag: frags.image
}
});
const DiamondCrop = ({ children: t }) => (
<Node
shader={shaders.DiamondCrop}
// uniformsOptions={{
// t: { interpolation: "nearest" },
// }}
uniforms={ { t } }
>
</Node>
);
export { DiamondCrop }
I tried passing the image in the following ways:
// 1
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
{{uri:'http://i.imgur.com/rkiglmm.jpg'}}
</DiamondCrop>
</Surface>
// 2
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
{{image:{uri:'http://i.imgur.com/rkiglmm.jpg'}}}
</DiamondCrop>
</Surface>
// 3
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
http://i.imgur.com/rkiglmm.jpg
</DiamondCrop>
</Surface>
// 4
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
{'http://i.imgur.com/rkiglmm.jpg'}
</DiamondCrop>
</Surface>
And the errors I get are the following:
// 1 (on 'expo red screen of death')
undefined is not an object (evaluating '_expo2.default.FileSystem')
// 2 (Expo warning; nothing appears on the Surface region)
Node#1(DiamondCrop#2), uniform t: no loader found for value, Object {
"image": Object {
"uri": "http://i.imgur.com/rkiglmm.jpg",
},
}, Object {
"image": Object {
"uri": "http://i.imgur.com/rkiglmm.jpg",
},
}
// 3 (Expo warning; nothing appears on the Surface region)
Node#1(DiamondCrop#2), uniform t: no loader found for value, http://i.imgur.com/rkiglmm.jpg, http://i.imgur.com/rkiglmm.jpg
// 4 (Expo warning; nothing appears on the Surface region)
Node#1(DiamondCrop#2), uniform t: no loader found for value, http://i.imgur.com/rkiglmm.jpg, http://i.imgur.com/rkiglmm.jpg
Could anyone point me in the right directions to accomplish this task??
This question is quite old, but I wanted to write an answer for those who may be into the gl related stuff with react-native and Expo.
TL;DR The reason this is happening is because the library gl-react-expo is outdated, it is doing import Expo from "Expo" which is deprecated(breaks the entire thing actually) in V33 of expo SDK.
I made a github repo that hosts the corrected libraries, you may want to use that. Here is the link gl-expo-libraries Also, If you want to stick to original libraries then go to the node_modules folder, go to the gl-react-expo fodler and look for _expo2 variable in the files and change _expo2.default to _expo. It will do the trick.
Cheers :)

Highcharts with React Legend placement and more

so I've recently introduced myself to Highcharts and I did create a hardcoded dummy chart on my app. However I'm having issues with mainpulating the placement specifically of the LEGEND circles. So here's the Link i drew code+inspiration from :
https://github.com/whawker/react-jsx-highcharts/blob/gh-pages/examples/Combo/App.js
And here's some of my code :)
render() {
const pieData = [
{
name: "Jane",
y: 17
},
{
name: "John",
y: 13
},
{
name: "Joe",
y: 20
},
{
name: "Ivan",
y: 50
}
];
return (
<HighchartsChart>
<Legend />
<YAxis id="number">
<PieSeries
id="total-consumption"
name="Total consumption"
data={pieData}
center={[300, 120]}
size={255}
showInLegend
/>
</YAxis>
</HighchartsChart>
);
so basically yeah I need the legend to move from the bottom to the right side etc , oh and as well as I'm not sure how to manipulate/display the values instead of the names on the chart itself .
Thanks in advance for ANY feedback and tips,
Yours truly ,
Victor (a confused Intern still)
As far as I can see from the examples of the react-jsx-highcharts library you are using the <Legend> component has some props that allow positioning.
To e.g. align it on the right try this:
<Legend layout="vertical" align="right" verticalAlign="middle" />
The documentation seems to be more than incomplete so your best chance is to look into the examples or dig into the source yourself to see which props might help you.
In most cases the components seem to be passing configuration options given as props to Highcharts as they are:
The intention of this library is to provide a very thin abstraction of Highcharts using React components. This has been achieved by passing Highcharts configuration options as component props.
In the vast majority of cases, the name of the configuration option, and the name of the component prop are the same.

Resources