what does interpolation really do - react-spring

beginner here, i'm having trouble understanding interpolation with usespring in React spring library , im trying to make an element go back and forth with the translate css property, now what i do understand is that passing in a range emulates css key frames and the output is the values the element should have at that point of the animation
so i did something like,
const {xyz} = useSpring({
from: {xyz: [0, 0, 0]},
to: {xyz: [0, 200, 0]},
})
<animated.div className={classes.down} style={{
transform: xyz
.interpolate(([y]) => (
{range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [180, 220, 180, 220, 180, 220, 180, 200]}
))
.interpolate((x, y, z)=> translate(${x}px, ${y}px, ${z}px))
}}>
<Typography variant="body2" className={classes.downText}>
Scroll Down
</Typography>
<DownArrow className={classes.downIcon}/>
</animated.div>
which dosen't work

There is a lot of problem here.
First of all in the useSpring if you want to change only the y then you can eliminate the x and z.
Secondly the range not worked for me with arrow function parameter.
Finally you must use translate3d instead of translate and the backtick is missing for the template string.
Something like this:
const { y } = useSpring({
from: { y: 0 },
to: { y: 1 }
});
return (
<div className="App">
<animated.div
style={{
transform: y
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [180, 220, 180, 220, 180, 220, 180, 200]
})
.interpolate(y => `translate3d(0px, ${y}px, 0px)`)
}}
>
Scroll Down
</animated.div>
</div>
);
https://codesandbox.io/s/gracious-diffie-rgz06?file=/src/App.js:135-613

Related

In LightningChartJS, is there a way to do a drag zoom where the zoom for X and Y is always equal?

My problem is when I drag rectangle zoom for example (gyazo gif), the X axis is wider than the Y. In effect, the X axis is zoomed in more details than the Y and the visual of the graph looks different from the original graph.
https://gyazo.com/749db917465a8037b7c5f21792f572ce
I am looking for a way where if i zoom rectangle drag, the function is similar to zooming via mousewheel where x and y zoom feels equal.
here you will find an example how you can perform custom zoom rect instead of default and keep the ratio of the axes.
// Extract required parts from LightningChartJS.
const {
ColorRGBA,
ColorHEX,
emptyFill,
SolidFill,
SolidLine,
translatePoint,
_point,
lightningChart
} = lcjs;
// Import data-generator from 'xydata'-library.
const {
createProgressiveTraceGenerator
} = xydata
const chart = lightningChart()
.ChartXY()
// Disable default chart interactions with left mouse button.
// .setMouseInteractionRectangleFit(false)
.setMouseInteractionRectangleZoom(false)
.setTitleFillStyle(emptyFill)
// generate data and creating the series
const series = chart.addLineSeries().setStrokeStyle(
new SolidLine({
fillStyle: new SolidFill({ color: ColorHEX('#fff') }),
thickness: 2,
}),
)
// generate data and create series
createProgressiveTraceGenerator()
.setNumberOfPoints(200)
.generate()
.toPromise()
.then((data) => {
return series.add(data)
})
// create zooming rect and dispose it
const rect = chart
.addRectangleSeries()
.add({
x: 0,
y: 0,
width: 0,
height: 0,
})
.setFillStyle(new SolidFill({ color: ColorRGBA(255, 255, 255, 30) }))
.setStrokeStyle(
new SolidLine({
thickness: 2,
fillStyle: new SolidFill({ color: ColorRGBA(255, 255, 255, 255) }),
}),
)
.dispose()
// om Mouse drag restor rectange and set position and coordinates
chart.onSeriesBackgroundMouseDrag((obj, event, button, startLocation, delta) => {
if (button !== 0) return
const startLocationOnScale = translatePoint(
chart.engine.clientLocation2Engine(startLocation.x, startLocation.y),
chart.engine.scale,
series.scale,
)
const curLocationOnScale = translatePoint(chart.engine.clientLocation2Engine(event.x, event.y), chart.engine.scale, series.scale)
const x = Math.abs(series.getBoundaries().min.x) + Math.abs(series.getBoundaries().max.x)
const y = Math.abs(series.getBoundaries().min.y) + Math.abs(series.getBoundaries().max.y)
const ratio = x / y
const width = Math.abs(curLocationOnScale.x - startLocationOnScale.x)
const height = Math.abs(curLocationOnScale.y - startLocationOnScale.y)
const heightDirection = curLocationOnScale.y - startLocationOnScale.y // check direction of rect
// check for mouse direction to prevet fit and zoom conflict
if (curLocationOnScale.x > startLocationOnScale.x) {
rect.setDimensions({
x: startLocationOnScale.x,
y: startLocationOnScale.y,
width: width > height * ratio ? width : height * ratio,
height: width > height * ratio ? (heightDirection > 0 ? width : -width) / ratio : heightDirection,
}).restore()
} else {
// prevent phantom rectangle if you change zoom to fit during the dragging
rect.setDimensions({
x: 0,
y: 0,
width: 0,
height: 0,
}).dispose()
}
})
// on mouse drag stop dispose rect and zoom relative to its dimensions
chart.onSeriesBackgroundMouseDragStop((_, event, button, startLocation) => {
if (button !== 0) return
const rectZooom = rect.getDimensionsPositionAndSize()
if (rectZooom.width !== 0) {
chart.getDefaultAxisX().setInterval(rectZooom.x, (rectZooom.x + rectZooom.width), true, true)
if(rectZooom.height > 0){
chart.getDefaultAxisY().setInterval(rectZooom.y, (rectZooom.y + Math.abs(rectZooom.height)), true, true)
}else{
chart.getDefaultAxisY().setInterval((rectZooom.y - Math.abs(rectZooom.height)),rectZooom.y, true, true)
}
}
rect.setDimensions({
x: 0,
y: 0,
width: 0,
height: 0,
}).dispose()
})
<script src="https://unpkg.com/#arction/xydata#1.4.0/dist/xydata.iife.js"></script>
<script src="https://unpkg.com/#arction/lcjs#3.0.0/dist/lcjs.iife.js"></script>

How to attach multiple react-spring springs on a single component?

I'm trying to learn how to use react-spring. Let's say that I have three divs to animate.
<a.div style={trans1}>
<a.div style={trans2}>
<a.div style={trans3}>
and trans1 has the following configuration…
const [clicked, toggle] = useState(null)
const { x } = useSpring({
from: { x: 0 },
x: clicked ? 1 : 0,
config: { duration: 500 },
})
const trans1 = {
transform: x
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [1, 0.97, 0.9, 1.1, 0.9, 1.1, 1.03, 1],
})
.interpolate((x) => `scale(${x})`),
}
What's the best way to implement the same type of animation on the second and third divs without duplicating all that code? How do I make multiple instances of the same spring for use on multiple Dom objects without triggering them all at the same time? I certainly don't want to duplicate a full set of code for each item, right?
Do I need to create a function that accepts a parameter that can switch the arguments in the config on the fly? 🤷🏽‍♂️
Any help is appreciated.
Here's a live example: https://codesandbox.io/s/optimistic-bassi-brnle
How do I make the left & right sides animate one at a time without creating duplicate code?
The first possibility would be to separate the style and give it to more than one div. Its drawback is, that they would behave exactly the same at the same time.
const style = {
opacity: x.interpolate({ range: [0, 1], output: [0.3, 1] }),
transform: x
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [1, 0.97, 0.9, 1.1, 0.9, 1.1, 1.03, 1]
})
.interpolate(x => `scale(${x})`)
};
return (
<div onClick={() => toggle(!state)}>
<animated.div
style={style}>
click
</animated.div>
<animated.div
style={style}>
click
</animated.div>
</div>
)
The second option is, that you create a new component with the click and spring logic. This way you write the logic once and you can use it multiple time. I introduced a text attribute also to make different text for the component.
const AnimText = ({text}) => {
const [state, toggle] = useState(true)
const { x } = useSpring({ from: { x: 0 }, x: state ? 1 : 0, config: { duration: 1000 } })
return (
<div onClick={() => toggle(!state)}>
<animated.div
style={{
opacity: x.interpolate({ range: [0, 1], output: [0.3, 1] }),
transform: x
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [1, 0.97, 0.9, 1.1, 0.9, 1.1, 1.03, 1]
})
.interpolate(x => `scale(${x})`)
}}>
{text}
</animated.div>
</div>
)
}
function Demo() {
return (
<div>
<AnimText text={'click1'}/>
<AnimText text={'click2'}/>
<AnimText text={'click3'}/>
</div>
)
}
here is the example: https://codesandbox.io/s/divine-water-n1b6x

How to align solid gauge using Highcharts to the size of parent div

I have created a Solid Gauge chart using Highcharts. Now, I want to fit the chart inside a grid div which takes size of 300px or auto. When I try to put the code inside the div, it takes a lot of white space up and down of the chart.I tried to inspect it and it is showing that the SVG image is taking most of the space. I don't understand how to make the chart fit in the div.I am new to HighCharts, any help would be appreciated.
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<div id="container" style="height: 300px;">
</div>
$(function() {
var rawData = 100,
data = getData(rawData);
function getData(rawData) {
var data = [],
start = Math.round(Math.floor(rawData / 10) * 10);
data.push(rawData);
for (i = start; i > 0; i -= 1) {
data.push({
y: i
});
}
return data;
}
Highcharts.chart('container', {
chart: {
type: 'solidgauge',
marginTop: 0
},
title: {
text: ''
},
subtitle: {
text: rawData,
style: {
'font-size': '60px'
},
y: 200,
},
tooltip: {
enabled: false
},
pane: [{
startAngle: -90,
endAngle: 90,
background: [{ // Track for Move
outerRadius: '100%',
innerRadius: '70%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0.1).get(),
borderWidth: 0,
shape: 'arc'
}],
size: '100%',
center: ['50%', '65%']
}, {
startAngle: -180,
endAngle: 180,
size: '95%',
center: ['50%', '65%'],
background: []
}],
yAxis: [{
min: 0,
max: 100,
lineWidth: 0,
lineColor: 'white',
tickInterval: 0,
labels: {
enabled: true
},
minorTickWidth: 0,
tickLength: 0,
tickWidth: 0,
tickColor: 'white',
zIndex: 0,
stops: [
[0, '#fff'],
[0.1, '#0f0'],
[0.2, '#2d0'],
[0.3, '#4b0'],
[0.4, '#690'],
[0.5, '#870'],
[0.6, '#a50'],
[0.7, '#c30'],
[0.8, '#e10'],
[0.9, '#f03'],
[1, '#f06']
]
}, {
linkedTo: 0,
pane: 0,
lineWidth: 10,
lineColor: 'white',
tickPositions: [],
zIndex: 6
}],
series: [{
animation: false,
dataLabels: {
enabled: false
},
borderWidth: 0,
color: Highcharts.getOptions().colors[0],
radius: '100%',
innerRadius: '70%',
data: data
}]
});
});
Currently the image is coming this way.
http://jsfiddle.net/dt4wu39e/1/

How to add gradient css to Nivo Rocks Line chart area?

I tried adding gradient css to line chart area of nivo rocks component according to this guide Gradients. but it is not working.
Example screenshot
I need something like the above chart gradients. And here is my code,
<ResponsiveLine
data={data1}
margin={{
"top": 65,
"right": 50,
"bottom": 50,
"left": 70
}}
yScale={{ type: 'linear', min: 0, max: 10 }}
tooltip={tooltip}
stacked={true}
curve="monotoneX"
axisTop={null}
axisRight={null}
axisBottom={{
"tickSize": 5,
"tickPadding": 5,
"tickRotation": 0,
"legend": "VIDEOS",
"legendPosition": "middle",
"legendOffset": 42
}}
axisLeft={{
"tickSize": 5,
"tickPadding": 5,
"tickRotation": 0,
"legend": "MARKS",
"legendPosition": "middle",
"legendOffset": -40
}}
defs={[{
id: 'gradientC',
type: 'linearGradient',
colors: [
{ offset: 0, color: '#fff' },
{ offset: 100, color: '#000' },
],
},]}
fill={[
{ match: '*', id: 'gradientC' },
]}
animate={true}
enableGridY={false}
colors={'linear-gradient(to bottom, #fff, #000)'}
colorBy={'id'}
lineWidth={6}
dotSize={14}
enableDots={false}
dotColor="inherit:darker(0.3)"
dotBorderWidth={2}
dotBorderColor="#ffffff"
enableDotLabel={true}
dotLabel="y"
dotLabelYOffset={-12}
enableArea={true}
areaOpacity={0.1}
motionStiffness={90}
motionDamping={15}
legends={[]}
/>
This is what I got,
Thanks in advance.
Bit late to the party on this, but if you're still stuck:
Pretty hacky, but will work as a little work around for adding a gradient to Nivo line chart.
Create an SVG def for the linear gradient and then reference it by url in the color array.
// these are just an example for the chart wrapper
const height = 300;
const width = 800;
const gradProps = {
gradientUnits: 'userSpaceOnUse',
x1: '0',
y1: '0',
x2: '0',
y2: height
};
const Chart = () => (
<div style={{ height, width }}>
<svg>
<defs>
<linearGradient id="someGradientId" {...gradProps} >
<stop offset="25%" stopColor="#ff0000" />
<stop offset="100%" stopColor="rgba(255,255,255,0)" />
</linearGradient>
</defs>
</svg>
<ResponsiveLine
data={chartData}
colors={['url(#someGradientId)']}
margin={{
top: 2,
bottom: 2
}}
dotSize={0}
enableArea={true}
enableGridX={false}
enableGridY={false}
curve={curve}
axisBottom={{
tickValues: []
}}
/>
</div>
);
Will also need to then overwrite the color value for stroke of the line via css
, as the
[stroke="url(#someGradientId)"] {
stroke: #ff0000;
}
If you put
enableArea = {true}
it will show the background. Also you can put
areaOpacity={0.1}
Example
<ResponsiveLine
data={data}
margin={{ top: 50, right: 110, bottom: 50, left: 60 }}
xScale={{ type: 'point' }}
yScale={{ type: 'linear', min: 'auto', max: 'auto', stacked: true, reverse: false }}
curve="catmullRom"
axisTop={null}
axisRight={null}
enableGridX={props.enableGridX}
enableGridY={props.enableGridY}
axisBottom={{
orient: 'bottom',
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
}}
axisLeft={{
orient: 'left',
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
}}
pointSize={10}
pointColor={{ from: 'color', modifiers: [] }}
pointBorderWidth={2}
pointBorderColor={{ from: 'serieColor' }}
pointLabel="y"
pointLabelYOffset={-12}
areaOpacity={0.25}
useMesh={true}
keys={['commits']}
transportation
defs={[{
id: 'gradientC',
type: 'linearGradient',
colors: [
{ offset: 0, color: '#e65a14' },
{ offset: 100, color: '#e65a14' },
],
},]}
fill={[
{ match: '*', id: 'gradientC' },
]}
animate={true}
colorBy={'id'}
lineWidth={2}
dotSize={14}
enableDots={false}
dotColor="inherit:darker(0.3)"
dotBorderWidth={2}
dotBorderColor="#e65a14"
enableDotLabel={true}
dotLabel="y"
dotLabelYOffset={-12}
enableArea={true}
motionStiffness={90}
motionDamping={15}
legends={[
{
anchor: 'bottom-right',
direction: 'column',
justify: false,
translateX: 100,
translateY: 0,
itemsSpacing: 0,
itemDirection: 'left-to-right',
itemWidth: 80,
itemHeight: 20,
itemOpacity: 0.75,
symbolSize: 12,
symbolShape: 'circle',
symbolBorderColor: 'rgba(0, 0, 0, .5)',
effects: [
{
on: 'hover',
style: {
itemBackground: 'rgba(0, 0, 0, .03)',
itemOpacity: 1
}
}
]
}
]}
/>

How do I add a class to a Rect in bonsaijs?

I need to add a class to a Rect. I can't seem to figure out how to do it.
bar = (new Rect(x, ySegment * 10 + 30 + margin, w, 0)
.attr('opacity', 0.8)
.attr('class', data[i].segments[j].color)
.addTo(stage));
the class attr is ignored.
A DisplayObject like Rect isn't the representation of an HTMLElement. That's why custom attributes like "class" don't work. If your intention is to re-use attributes for different DisplayObjects, then try the following:
var myAttrs = {
fillColor: 'red',
opacity: 0.5
};
new Rect(20, 20, 100, 100).attr(myAttrs).addTo(stage);
new Rect(20, 130, 100, 100).attr(myAttrs).addTo(stage);
Play with it here: Orbit

Resources