'vertexColors' parameter is undefined? - three.js

const material = new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors,
transparent: true,
side: THREE.DoubleSide,
})
why?

.vertexColors can either be true or false, nothing else. THREE.VertexColors does not exist, so it comes out as undefined.
https://threejs.org/docs/index.html#api/en/materials/Material.vertexColors

Parameters in Material vertexColors are boolean, true or false.
so if you have specified point color in float array then it can define boolean value (true or false), I will give a little example like this, and this is what I did it worked.
const myGeo = new THREE.BufferGeometry();
let vertices = new Float32Array([
-1.0, -1.0, 1.0, // 0
1.0, 1.0, 1.0, // 1
-1.0, 1.0, 1.0, // 2
1.0, -1.0, 1.0, // 3
-1.0, -1.0, -1.0, // 4
1.0, 1.0, -1.0, // 5
-1.0, 1.0, -1.0, // 6
1.0, -1.0, -1.0, // 7
]);
let colors = new Float32Array([
1.0, 0.0, 0.0, // Vertex 0 (Red)
1.0, 0.0, 0.0, // Vertex 1 (Red)
1.0, 1.0, 0.0, // Vertex 2 (Yellow)
1.0, 1.0, 0.0, // Vertex 3 (Yellow)
0.0, 1.0, 0.0, // Vertex 4 (Green)
0.0, 1.0, 0.0, // Vertex 5 (Green)
0.0, 0.0, 1.0, // Vertex 6 (Blue)
0.0, 0.0, 1.0, // Vertex 7 (Blue)
]);
myGeo.setAttribute('position', new THREE.BufferAttribute( vertices, 3 ));
myGeo.setAttribute('color', new THREE.BufferAttribute( colors, 3 ));
myGeo.setIndex([.....]);
const material= new THREE.MeshBasicMaterial({ vertexColors:true, side: THREE.DoubleSide, });
let mesh = new THREE.Mesh(myGeo, material)
scene.add(mesh);

Related

Gradient Stop Locations at Variable Values SwiftUI

I'm trying to make a gradient composed of 4 stops in SwiftUI. I'd like the middle two to be anchored to the bottom of a specific stack. Something like this:
Imgur Link of what I'm trying to do
Here's the gradient code I currently have:
LinearGradient(gradient: Gradient(stops: [
//top Gradient.Stop(color: Color(hue: 0.0, saturation: 0.0, brightness: 0.0, opacity: 0.0), location: 0.0),
//variable1 Gradient.Stop(color: Color(hue: 0.0, saturation: 0.0, brightness: 0.0, opacity: 0.3), location: 0.30 //<-Variable),
//variable2 Gradient.Stop(color: Color(hue: 0.0, saturation: 0.0, brightness: 0.0, opacity: 1.0), location: 0.35 //<-Variable),
//bottom Gradient.Stop(color: Color(hue: 0.1, saturation: 1.0, brightness: 0.0, opacity: 1.0), location: 1.0)),
startPoint: UnitPoint.top, endPoint: UnitPoint.bottom)
You can simply use the frame size of the "Content Box" to determine at what position to place the gradient stop. I did this by just having a variable called frameHeight.
import SwiftUI
struct ContentView: View {
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
var frameHeight = 200
var body: some View {
let gradient = Gradient(stops: [Gradient.Stop(color: .blue, location: 0.0),
Gradient.Stop(color: .white, location: CGFloat(frameHeight)/screenHeight),
Gradient.Stop(color: .black, location: CGFloat(frameHeight)/screenHeight + 0.05),
Gradient.Stop(color: .black, location: 1.0)])
VStack{
//Content Box view of frameHeight
VStack {
Text("Content Box")
}.frame(width: screenWidth, height: CGFloat(frameHeight))
Spacer()
}.frame(width: screenWidth, height: screenHeight)
.background(LinearGradient(gradient: gradient, startPoint: UnitPoint.top, endPoint: UnitPoint.bottom))
.edgesIgnoringSafeArea(.all)
}
}

UIButton animation title position changed unexpected

UIButton animation title position changed suddenly (jumped to the left), I want to keep the title in the button center nearby always.
You can see the button title ("Login In") jumped to the left unexpected, which should be optimized.
Here is the code:
UIView.animate(withDuration: 1.5, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 0.0, options: [], animations: {
self.loginButton.bounds.size.width -= 80.0
}){ (yes) in }
UIView.animate(withDuration: 0.33, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: [], animations: {
self.loginButton.center.y -= 60.0
self.loginButton.backgroundColor = UIColor(red: 0.63, green: 0.84, blue: 0.35, alpha: 1.0)
self.spinner.center = CGPoint(x: -20, y: -16)
self.spinner.alpha = 0.0
}){ (yes) in }
Here is the code I tried , which does not work too.
UIView.animate(withDuration: 0.3, delay: 0.2, options: [], animations: {
self.loginButton.backgroundColor = UIColor(red: 0.63, green: 0.84, blue: 0.35, alpha: 1.0)
self.loginButton.bounds.size.width -= 80.0
self.loginButton.center.y -= 60.0
self.spinner.frame.origin = CGPoint(x: -20, y: 16)
self.spinner.alpha = 0.0
}) { (isOK) in }
PS:
I add the login button through storyboard , as the following image
And the code relevant is here
Add line in animation function
UIView.animate(withDuration: 1, delay: 0.2, options: [], animations: {
//Your code for animation
.
.
.
//Add this line
self.view.layoutIfNeeded()
}) { (isOK) in }
Note
Use Auto Layout for all device support and easy to animation

how do i customise the c3.js chart to get like this

Trying to create the above using c3.js.
We are using the same charting library across the application so would like to keep it consistent. Didn't find a way in c3.js to either customize donut or pie chart to get this. i need it to be hour, instead of percentage . and also the target value should be 12 instead of 100%. Any help or pointers are greatly appreciated.
normal jsfiddle link to customise.
var chart = c3.generate({
bindto: '#pie-chart',
data: {
columns: [
['data1', 30],
['data2', 120],
],
type : 'donut',
onclick: function (d, i) { console.log("onclick", d, i); },
onmouseover: function (d, i) { console.log("onmouseover", d, i); },
onmouseout: function (d, i) { console.log("onmouseout", d, i); }
},
donut: {
title: "Iris Petal Width"
}
});
setTimeout(function () {
chart.load({
columns: [
["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
["versicolor", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],
]
});
}, 1500);
setTimeout(function () {
chart.unload({
ids: 'data1'
});
chart.unload({
ids: 'data2'
});
}, 2500);
I think I'm pretty close to what you were wanting. The onrendered callback code is to append a circle in the middle of that; you may want to handle that another way, my implementation is pretty basic.
The key things to pay attention to are the config options under gauge:
gauge: {
fullCircle: true, // This makes it go all the way around
max: 12, // This is your max unit -- 12h
min: 0, // Min. is 0
startingAngle: 90, // This sets the opening to the other side
width: 25, // This is how thick the outer arc is.
label: {
format: function(value, ratio) {
return value + 'HR';
}
}
var chart = c3.generate({
data: {
columns: [
['data1', 10],
],
type: 'gauge',
colors: {
data1: '#9873FF'
}
},
gauge: {
fullCircle: true, // This makes it go all the way around
max: 12, // This is your max unit -- 12h
min: 0, // Min. is 0
startingAngle: 90, // This sets the opening to the other side
width: 25, // This is how thick the outer arc is
label: {
format: function(value, ratio) {
return value + 'HR';
}
}
},
onrendered: function() {
setTimeout(function(){ // timeout is needed for initial render.
var centerBBox = d3.select('.c3-arc-data1').node().getBBox();
d3.select('.c3-arcs-data1')
.insert('circle', '.c3-arc-data1')
.classed('c3-arc-data1-background', true)
.attr('cx', centerBBox.x + centerBBox.width/2)
.attr('cy', centerBBox.y + centerBBox.height/2)
.attr('fill', '#6C40E8')
.attr('r', (centerBBox.height / 2 - 25)) // "25" is an arbitrary number
}, 0);
}
});
.c3-chart-arcs-gauge-max,
.c3-chart-arcs-gauge-min,
.c3-chart-arcs-background{
display: none;
}
.c3-gauge-value {
fill: white !important;
font-family: "Lucida Console", Helvetica, sans-serif;
font-size: 40px !important;
transform: translateY(10px);
}
.c3-arc-data1 {
stroke: transparent !important;
}
<link href="https://cdn.rawgit.com/c3js/c3/0.4.11/c3.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/c3js/c3/0.4.11/c3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>

Not able to create scatter and line chart together in c3.js

Please guide me what i am doing wrong.I am using c3.js for showing chart in my webpage.Now i have requirement where i need to show spline and scatter chart together.I have searched in c3.js and came across combinational chart (http://c3js.org/samples/chart_combination.html). But when i used it for scatter and spline chart is not coming at all
Below is my code
<!-- Load c3.css -->
<link href="c3.css" rel="stylesheet" type="text/css">
<!-- Load d3.js and c3.js -->
<script src="d3.js" charset="utf-8"></script>
<script src="c3.js"></script>
<div class="chart" id="chart" ></div>
<script>
var chart = c3.generate({
data: {
xs: {
setosa: 'setosa_x',
},
// iris data from R
columns: [
["setosa", 3.0, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],
["setosa_x", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],
['data3', 300, 200, 160, 400, 250, 250],
],
type: 'scatter',
types: {
data3: 'spline',
},
},
axis: {
x: {
label: 'Sepal.Width',
tick: {
fit: false
}
},
y: {
label: 'Petal.Width'
}
}
});
</script>
Thanks
I have also wondered.
To plot the line chart on the same x axis as the scatter chart, you will need an x axis and set it to the same axis as scatter chart. The setosa_x data does not have to be in order, but it should be so you can make a useful line chart on the shared x axis. This affects how setosa can be defined also.
Because the x axis will have several numbers the same, you will need to giver your line data some nulls.
You need to give the scatter and line charts different axes{} to work from (y and y2). Also need to set limits with min and max for each.
You can cut and paste the data in the arrays into M Excel and order the chronoligically
var chart = c3.generate({
data: {
x:'setosa_x',
xs: {
setosa: 'setosa_x',
},
// iris data from R
columns: [
//['x',2.3,2.9,3.0,3.0,3.0,3.0,3.0,3.0,3.1,3.1,3.1,3.1,3.2,3.2,3.2,3.2,3.2,3.3,3.3,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.5,3.5,3.5,3.5,3.5,3.6,3.6,3.6,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.9,3.9,4.0,4.1,4.2,4.4],
['data3', 100, 200, 300, null, null, 200, null, 160, 400, 250, 250,100, 200, 300, 200, 160, 400, 250, 250,100, 200, 300, 200 ],
["setosa_x",2.3,2.9,3.0,3.0,3.0,3.0,3.0,3.0,3.1,3.1,3.1,3.1,3.2,3.2,3.2,3.2,3.2,3.3,3.3,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.5,3.5,3.5,3.5,3.5,3.6,3.6,3.6,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.9,3.9,4.0,4.1,4.2,4.4],
["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
],
axes: {
// setosa_x: 'x',
setosa: 'y2',
data3: 'y'
},
type: 'scatter',
types: {
data3 : 'spline'
}
},
axis: {
y: {
min: 35,
show: true
},
y2: {
max: 0.5,
show: true
}
}
});
The above answer was a useful start for me but it's ultimately off point. The C3 system allows one to specify multiple chart types, without having to resort to creating multiple y axes, which should almost always be avoided because it's too easy to manipulate inferences in this manner (think of truncating one axis to increase the appearance of variability or vise versa).
Simply add in the x and y values respectively for each series you'd like to plot and refer to the type of chart that needs to be plotted in the types argument in the data object. See below:
var setosa_x = [2.3,2.9,3.0,3.0,3.0,3.0,3.0,3.0,3.1,3.1,3.1,3.1,3.2,3.2,3.2,3.2,3.2,3.3,3.3,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.5,3.5,3.5,3.5,3.5,3.6,3.6,3.6,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.9,3.9,4.0,4.1,4.2,4.4];
var setosa = [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2];
var new_setosa = setosa.map(function(x){
return 0.75 * x + .25;
});
var new_setosa_x = setosa_x.map(function(x){
return x + .10;
})
var other_chart = c3.generate({
bindto: '#other_chart',
data: {
xs: {
setosa: 'setosa_x',
other: 'other_x'
},
// iris data from R
columns: [
["setosa_x"].concat(setosa_x),
["setosa"].concat(setosa),
["other_x"].concat(new_setosa_x),
["other"].concat(new_setosa)
],
types: {
setosa: 'scatter',
other : 'spline'
}
}
});

WebGL/GLSL vertex shader collapses 9 points into single point when I set x coord of gl_Position to zero

I do not understand why the following two shaders produce different results when I render a vertex buffer with x coordinates equal to zero:
First:
attribute vec3 position;
void main() {
gl_Position = vec4(position.x, position.y, 0.0, 1.0);
}
Second:
attribute vec3 position;
void main() {
gl_Position = vec4(0.0, position.y, 0.0, 1.0);
}
The result of the first is a line of nine dots. The result of the second is a single dot.
I'm drawing the following vertex array as GL_POINTS:
0.0, -1.00, 0.0,
0.0, -0.75, 0.0,
0.0, -0.50, 0.0,
0.0, -0.25, 0.0,
0.0, 0.00, 0.0,
0.0, 0.25, 0.0,
0.0, 0.50, 0.0,
0.0, 0.75, 0.0,
0.0, 1.00, 0.0
Here's the VBO preparation calls:
var a = new Float32Array([
0.0, -1.00, 0.0,
0.0, -0.75, 0.0,
0.0, -0.50, 0.0,
0.0, -0.25, 0.0,
0.0, 0.00, 0.0,
0.0, 0.25, 0.0,
0.0, 0.50, 0.0,
0.0, 0.75, 0.0,
0.0, 1.00, 0.0
]);
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.bufferData(gl.ARRAY_BUFFER, a.byteLength, gl.STATIC_DRAW);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, a);
Here's the draw calls:
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.vertexAttribPointer(p.position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(p.position);
gl.drawArrays(gl.POINTS, 0, 9);
That is a known problem (sorry, no link for now).
Basically, GLSL compiler thinks that attribute 'position' is not used, because the first component of it is not used. To check this try the following test:
gl_Position = vec4(0.0, position.y, 0.0, 1.0) + position.x*0.001;
Once you confirm the bug, you can either update you video driver or use an obvious workaround.

Resources