I am trying to add the polyline using the following code in the viewer
const polylineOptions = {
mtype: 1,
polyline: {
clampToGround: false,
material: {
red: 0.9686274509803922,
green: 0.8784313725490196,
blue: 0.12549019607843137,
alpha: 1
},
positions:[
{
x: 4587184.226708501,
y: 263034.9288440118,
z: 4408875.3130637
},
{
x: 4587020.391536608,
y: 263038.279352096,
z: 4409044.42829542
},
{
x: 4587020.391536608,
y: 263038.279352096,
z: 4409044.42829542
}
]
width: 3,
zIndex: 1000
},
}
this.viewer.entities.add(this.polylineOptions);
but the behaviour is unexpected as follows
open this gif to see my result
and it is giving the following log in console
Entity polylines must have clampToGround: true when using zIndex. zIndex will be ignored.
What I actually want is to draw a space line but with clampToGround:false options, it creates the polyline that id attached to the terrain but when I use clampToGround:false then it hides under the tilelayer as shown in the gif
Related
I'm trying to switch from a ResponsiveLine to a ResponsiveLineCanvas using Javascript library Nivo version 0.80.0 and React 18.2.0, but markers are just not shown.
Not sure what I am missing, so I created an example to reproduce the issue
https://codesandbox.io/embed/fast-leftpad-q6ypqr?fontsize=14&hidenavigation=1&theme=dark
It is sufficient to switch from ResponsiveLineCanvas to ResponsiveLine and the marker get shown.
From the docs I cannot guess if the feature is unsupported in ResponsiveLineCanvas. So, am I missing any configuration?
import React, { useEffect, useState } from "react";
import { ResponsiveLineCanvas } from "#nivo/line";
import { ResponsiveLine } from "#nivo/line";
const commonProperties = {
width: 900,
height: 400,
margin: { top: 20, right: 20, bottom: 60, left: 80 },
animate: true,
enableSlices: "x"
};
const App = () => (
<div style={{ height: 600 }}>
<ResponsiveLineCanvas
{...commonProperties}
data={[
{
id: "Id of serie",
data: [
{ x: 0, y: 0.2 },
{ x: 1, y: 0.3 },
{ x: 2, y: 0.5 },
{ x: 3, y: 0.4 },
{ x: 4, y: 0.3 },
{ x: 5, y: 0.5 },
{ x: 6, y: 0.3 },
{ x: 7, y: 0.1 }
]
}
]}
markers={[
{
axis: "x",
value: 2,
lineStyle: { stroke: "#6aa84f", strokeWidth: 3, opacity: 0.95 },
legend: "Budget line"
}
]}
layers={[
"grid",
"axes",
"areas",
"lines",
"points",
"slices",
"mesh",
"legends",
"markers"
]}
enableGridX={false}
colors={["rgb(97, 205, 187)", "rgb(244, 117, 96)"]}
xScale={{
type: "linear"
}}
yScale={{
type: "linear",
stacked: false,
min: 0,
max: 1
}}
enableArea={true}
areaOpacity={1}
enableSlices={false}
useMesh={true}
crosshairType="cross"
/>
</div>
);
export default App;
Looking at the source code, it's clear that support for markers has not been implemented in the LineCanvas and ResponsiveLineCanvas components. There is no mention of markers anywhere in the component source. The markers prop is not included in the destructuring assignment so that prop will be ignored and have no effect.
As for the layers prop, this Canvas version goes through a bunch of if statements to check for known layer types. "marker" is not one of these types. There is no else statement that lets you know if a provided layer was invalid, it just doesn't do anything.
The supported values of the layers prop, per the source code, are:
"grid"
"axes"
"areas"
"lines"
"points"
"mesh"
"legends"
custom functions
On the other hand, the SVG-based Line and ResponsiveLine components do use the markers prop and support layers=["markers"]. You can see here how the markers prop is passed off to a CartesianMarkers component from the #nivo/core package and the resulting element is stored in the layerById dictionary.
I am new to using the Plotly library and this time I find myself with the need to show in Vuejs 2 a circular progress graph like the following one.
I know that plotly is very complete but I have not seen an example with a similar aspect and that is also with javascript.
Thanks in advance for any information or help you can provide.
Greetings!
With plotly Derek Example, the graph looks like this
My English is not very good, but note that the line of the circle does not have a smooth curvature.
You can use plotly.js traces and text to recreate the components of this chart. If you use a scatter to place down an array of markers, you can create the grey arc, then place the red arc over it. To calculate the coordinates of each these markers, you can center your axes at (0,0) then use x=r*cos(theta) and y=r*sin(theta) where theta is your angle in radians. You can get an array of x and y values to trace out the desired portions of the red and grey arcs.
To get the circular chart to look like yours, I set the range of the x-axes and y-axes both to [-2,2], made the radius of the circular arcs 0.9 with [0,0] as the center, set the markers for these arcs to be size 10, and made the grey arc go from 210 to 85 degrees and red arc go from 90 to -200 degrees (using the function makeArr written by mhodges in his answer here),. Then to get the green marker to display in the legend, I created a trace with a green marker but with null values so it doesn't plot anything on the chart. Text traces can be used to add text around the center of the circular arcs.
Here is an example (codepen is here):
// credit goes to mhodges: https://stackoverflow.com/a/40475362/5327068
function makeArr(startValue, stopValue, cardinality) {
var arr = [];
var step = (stopValue - startValue) / (cardinality - 1);
for (var i = 0; i < cardinality; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
// The function returns two arrays of circle coordinates
// for the outer points of a circle centered at some (x,y)
// and with a radius r with an arc of theta values
function getCircleCoords(r, center, degree_values) {
var center_x=center[0]
var center_y=center[1]
var x_coords = []
var y_coords = []
for (var i = 0; i < degree_values.length; i++) {
x_coords.push(center_x + (r * Math.cos(degree_values[i]*Math.PI/180)));
y_coords.push(center_y + (r * Math.sin(degree_values[i]*Math.PI/180)));
}
return [x_coords,y_coords]
}
var trace1 = {
x: [0],
y: [0.15],
text: ['1000'],
mode: 'text',
textfont: {
family: 'arial',
size: 28,
color: 'black'
},
showlegend: false
};
var trace2 = {
x: [0],
y: [-0.15],
text: ['kW/kg'],
mode: 'text',
textfont: {
family: 'arial',
size: 22,
color: 'grey'
},
showlegend: false
};
circleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(90,-200,1000))
backgroundCircleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(210,85,1000))
// display a marker in the legend without plotting it
var trace3 = {
x: [null],
y: [null],
mode: 'markers',
marker: {color: 'green', size: 10},
name: 'Correcto funcionamiento'
};
// grey background circle
var trace4 = {
x: backgroundCircleCoords[0],
y: backgroundCircleCoords[1],
mode: 'markers',
marker: {color: '#eeeeee', size: 10},
name: null,
showlegend: false
};
// red foreground circle
var trace5 = {
x: circleCoords[0],
y: circleCoords[1],
mode: 'markers',
marker: {color: 'red', size: 10},
name: 'Funcionamiento erroneo'
};
var layout = {
title:'RelacĂon potencia peso',
xaxis: {
range: [-2, 2],
zeroline: false,
showgrid: false,
zeroline: false,
showline: false,
showticklabels: false
},
yaxis: {
range: [-2, 2],
showgrid: false,
zeroline: false,
showline: false,
showticklabels: false
},
width: 600,
height: 600,
legend: {
x: 0,
y: 0,
"orientation": "h"
}
};
var data = [trace1, trace2, trace3, trace4, trace5];
Plotly.newPlot('myDiv', data, layout);
EDIT: for a smoother circle, you can increase the number of markers used to draw the circle.
circleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(90,-200,5000))
backgroundCircleCoords = getCircleCoords(r=0.9, center=[0,0], radian_values=makeArr(210,85,5000))
I am trying to integrate it into an existing Paper.js application to replace the original .tweenTo function (http://paperjs.org/reference/tween/). The only issue I am facing so far is the "chaining" of the position or point property animations:
https://codepen.io/yevsim/pen/GRmPBZB
paper.install(window)
paper.setup(canvas);
const text = new PointText({
point: new Point(100, 100),
fontFamily: "sans-serif",
fontWeight: "bold",
fontSize: 48,
fillColor: 'black'
});
text.content = 'Move me';
const timeline = gsap.timeline();
timeline.to(text.point, { duration: 1, x: '+=100' });
timeline.to(text.point, { delay: 1, duration: 1, x: '+=100' });
For the reason unknown to me, it moves the text back to its original position before doing the second animation (i.e. instead of going from 100 -> 200 -> 300, it goes 100 -> 200 -> 100 -> 200). Chaining other properties animation e.g. width, height, color, opacity works as expected. I tried to play with replacing point with position, combining them together, but nothing worked for me.
I'm not really sure why but this will work if you store text.point into a variable and use this variable instead of a reference to the actual object when creating your timeline.
Based on your code, here a corrected version:
const text = new PointText({
point: new Point(100, 100),
fontFamily: 'sans-serif',
fontWeight: 'bold',
fontSize: 48,
fillColor: 'black',
content: 'Move me'
});
// Use a variable to reference the property to animate.
const point = text.point;
const timeline = gsap.timeline();
timeline.to(point, { duration: 1, x: '+=100' });
timeline.to(point, { delay: 1, duration: 1, x: '+=100' });
Currently I have a request to have a Bullet Chart with two targets (min and max).
To do it I am simply using a normal Bullet Chart with a Scatter series to draw the other target. I would like to wrap this behavior inside the bullet chart, so it would have something like the following options:
series: [{
data: [{
y: 275,
target: 250,
minTarget: 100
}]
},
And then, on the wrap, I would get this minTarget and make a scatter plot automatically. How can I do it?
Here's the fiddle I have so far: http://jsfiddle.net/gwkxd02p/
I do not think that render is a good method to add another series - anyway, you can try to do it like this:
Highcharts.wrap(Highcharts.seriesTypes.bullet.prototype, 'render', function(p) {
if (!this.hasRendered) {
const scatterData = this.points
.map(({ x, y, options }) => ({
x,
y: options.minTarget !== undefined ? options.minTarget : null
}))
if (scatterData.length) {
const scatter = this.chart.addSeries({
type: 'scatter',
data: scatterData,
marker: {
symbol: 'line',
lineWidth: 3,
radius: 8,
lineColor: '#000'
}
}, false)
scatter.translate()
scatter.render()
}
}
p.call(this)
})
And data for bullet:
series: [{
data: [{
y: 275,
target: 250,
minTarget: 100
}, {
y: 100,
target: 50
}, {
y: 500,
target: 600,
minTarget: 20
}]
live example: http://jsfiddle.net/n4p0ezzw/
I think that the better place is bullet's init method but in that method the points do not exist yet - so you would have to match the x values (if it is needed) on your own.
My suggestion is - do not wrap Highcharts if you don't have to. A better (simpler, safer, cleaner, easier to debug, it does not change Highcharts internal code) practice would be to wrap the Highcharts constructor in a function and parse the options inside it and then call the chart constructor with new options, like this:
function customBullet(container, options) {
const newOptions = {} // parse options, check for minTarget, etc. and create new options
return Highcharts.chart(container, newOptions)
}
I am trying to add a custom 3d object in awe.js, I have tried with the cubes and sphere geometries, but haven't found any documentation that facilitates adding a 3d object. Any ideas?
awe.projections.add({
id:'n',
geometry:{ path:'cube.obj'},
rotation:{ x:30, y:30, z:0 },
material:{
type: 'phong',
color:0x000000,
},
}, { poi_id: 'north' });
using new libraries you can do it as shown below, I've copied that from my answer in another question (awe.js Augmented Reality adding text).
awe.pois.add({ id:'jsartoolkit_marker_64', position: { x:0, y:0, z:0 }, scale: { x: 1, y: 1, z: 1 } });
awe.projections.add({
id:'marker_projection',
geometry: { path: 'models/obj/example.obj' }, // path to your model
position: { x: 0, y: 0, z: 0 },
rotation: { x: 0, y: 180, z: 0 },
material:{ path: 'models/obj/example.mtl' }, // path to material if you're using one
visible: false,
}, { poi_id: 'jsartoolkit_marker_64' }); // common point of interest, in this case the marker