Related
https://jsfiddle.net/dcfmL4br/
series: [{
name:'İstanbul',
data: [
{ x: 1246665600000, y: 100, z: 20.8, country: 'İstanbul' },
{ x: 1246752000000, y: 95, z: 23.8, country: 'İstanbul' },
],
color:Highcharts.getOptions().colors[2]
},
{
name:'Ankara',
data: [
{ x: 1246665600000, y: 96, z: 10.8, country: 'Ankara' },
{ x: 1246752000000, y: 97, z: 13.8, country: 'Ankara' },
],
color:Highcharts.getOptions().colors[3]
}
]
I have a series like that for fourth of july and fifth of july. But between these points, hours are shown. How do I hide xaxis points when there is no corresponding y axis value for them?
In labels.formatter function you can loop through series points to find out whether the current value is used:
xAxis: {
...,
labels: {
formatter: function() {
var series = this.chart.series,
s,
p,
usedValue;
for (s of series) {
if (usedValue) {
break;
}
for (p of s.xData) {
if (p === this.pos) {
usedValue = true;
break;
}
}
}
if (usedValue) {
return Highcharts.dateFormat(this.dateTimeLabelFormat, this.pos)
}
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/db8pqLty/
API Reference:
https://api.highcharts.com/class-reference/Highcharts#.dateFormat
https://api.highcharts.com/highcharts/xAxis.labels.formatter
I have a 3d scatterplot of which i want to change its zoom level and pan around it programmatically. I have tried setting the range in the layout from the beggining but it does not change the actual zoom level, just the points in the range:
"layout":
{
margin: {
l: 0,
r: 0,
b: 0,
t: 0,
pad: 1
},
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
}
},
Also i've tried invoking it with the relayout function, but it is also not working
var update = {
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
},
};
Plotly.relayout(gd, update);
Finally i found the property to change the camera position:
var update = {
scene:{
camera: {
center: { x: 0, y: 0, z: 0 },
eye: { x: 2, y: 2, z: 0.1 },
up: { x: 0, y: 0, z: 1 }
}
},
};
Plotly.relayout(gd, update);
In my Vue.js/Vuex based application I'm using this mutation to reset part of the Vuex state:
restartGame(state) {
state.gameRunning = true
state.camera = {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
}
This way, things work out fine, but writing out the whole camera state seems pretty verbose to me. So I extracted the initial camera state into a seperate file:
initialCameraState.js
export default {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
I've refactored the resetGame() mutation like this:
import initialCameraState from './initialCameraState'
restartGame(state) {
state.gameRunning = true
state.camera = initialCameraState
}
But somehow this doesn't work, the Vuex store does not get updated but seems to just stay the same. How can this be?
I'm also using initialCameraState.js to set (part of) the initial state of the Vuex store. My first thought was that when mutating the according part of the state, initialCameraState is also being mutated. That would explain resetGame() not showing any effects. So I tried using the object spread operator in both places where initialCameraState.js gets imported/used, but this didn't solve the issue.
I don't have all your code, but here's what I think may be happening. You are initing the game with the initial state which you have imported. During the game you update the state of the object by doing something like:
state.camera['position'] = {
x: 100,
y: 100,
z: 100
}
}
What actually happens is that your initial state has been updated because you have a reference to the object, not a copy of it, so when you try to reset the state it just remains the same, because you have inadvertently changed the initial state object.
To solve this simply wrap the initial state in a function (a factory function) so that the init state always gets returned:
export default function() {
return {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
};
Here's a JSFiddle showing what happens without a function (the positions remain the same): https://jsfiddle.net/9qg8ws0x/
And here one with the function (the positions are reset): https://jsfiddle.net/27xozazf/
export default {
initializeCamera () {
return {
position: {
x: 0,
y: 10,
z: 0
},
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
velocity: {
x: 0,
z: 0
},
mouseMovement: {
x: 0,
y: 0
},
rotation: {
x: 0,
y: 0
}
}
}
}
import initial from './initial'
restartGame(state) {
state.gameRunning = true
state.camera = initial.initializeCamera()
}
I am new to nodejs and i need to divide an array which contain dates on x-axis and its points on y axis and trying to draw a graph using an array to store data for x and y axis to do that i am doing this :
while(startDate <= endDate)
{
arr.push({x:startDate.toISOString().slice(0,10),y: 0});
startDate.setDate(startDate.getDate() + 1);
}
it will store all the dates from start date to ending date now i need to divide it into weeks so i am finding weeks by :
var Weeks = Math.round((endDate - startDate) / (7 * 24 * 60 * 60 * 1000));
now to get on which date there is a point so i do :
for (var i = doc.length - 1; i >= 0; i--) {
for (var j = arr.length - 1; j >= 0; j--) {
if (arr[j].x == doc[i].deal_end_date) {
arr[j].y ++;
}
}
}
}
now this will give me an output as below :
startDate: 2017-07-10, endDate: 2017-07-31
arr :
[ { x: '2017-07-10', y: 1 },
{ x: '2017-07-11', y: 0 },
{ x: '2017-07-12', y: 0 },
{ x: '2017-07-13', y: 0 },
{ x: '2017-07-14', y: 0 },
{ x: '2017-07-15', y: 1 },
{ x: '2017-07-16', y: 0 },
{ x: '2017-07-17', y: 0 },
{ x: '2017-07-18', y: 0 },
{ x: '2017-07-19', y: 0 },
{ x: '2017-07-20', y: 0 },
{ x: '2017-07-21', y: 0 },
{ x: '2017-07-22', y: 0 },
{ x: '2017-07-23', y: 0 },
{ x: '2017-07-24', y: 0 },
{ x: '2017-07-25', y: 0 },
{ x: '2017-07-26', y: 0 },
{ x: '2017-07-27', y: 0 },
{ x: '2017-07-28', y: 0 },
{ x: '2017-07-29', y: 0 },
{ x: '2017-07-30', y: 0 },
{ x: '2017-07-31', y: 0 } ]
now i need to divide this array i.e arr into weeks and
i tried
var i,j,temparray,chunk = Weeks;
for (i=0,j=arr.length; i<j; i+=chunk) {
temparray = arr.slice(i,i+chunk);
}
but it stores in temparray as :
temparray: [ { x: '2017-07-31', y: 0 } ]
and i need my temparray as below :
startDate: 2017-07-01 endDate: 2017-07-28
Weeks: 4
/*temparray[1] should be from arr[0] to arr[6]*/
temparray[1] :
[ { x: '2017-07-01', y: 0 },
{ x: '2017-07-02', y: 0 },
{ x: '2017-07-03', y: 0 },
{ x: '2017-07-04', y: 0 },
{ x: '2017-07-05', y: 1 },
{ x: '2017-07-06', y: 0 },
{ x: '2017-07-07', y: 0 }]
/*temparray[2] should be from arr[7] to arr[13]*/
temparray[2] :
[ { x: '2017-07-08', y: 0 },
{ x: '2017-07-09', y: 0 },
{ x: '2017-07-10', y: 0 },
{ x: '2017-07-11', y: 0 },
{ x: '2017-07-12', y: 0 },
{ x: '2017-07-13', y: 0 },
{ x: '2017-07-14', y: 0 }]
/*temparray[3] should be from arr[14] to arr[20]*/
temparray[3] :
[ { x: '2017-07-15', y: 0 },
{ x: '2017-07-16', y: 0 },
{ x: '2017-07-17', y: 0 },
{ x: '2017-07-18', y: 0 },
{ x: '2017-07-19', y: 0 },
{ x: '2017-07-20', y: 0 },
{ x: '2017-07-21', y: 0 }]
/*temparray[4] should be from arr[21] to arr[27]*/
temparray[4] :
[ { x: '2017-07-22', y: 0 },
{ x: '2017-07-23', y: 0 },
{ x: '2017-07-24', y: 0 },
{ x: '2017-07-25', y: 0 },
{ x: '2017-07-26', y: 0 },
{ x: '2017-07-27', y: 0 },
{ x: '2017-07-28', y: 0 }]
A solution using fill and map:
function splitArray(array, chunkSize) {
return Array(Math.ceil(array.length/chunkSize)).fill().map(function(_,i) {
return array.slice(i * chunkSize, i * chunkSize + chunkSize);
});
}
var results = splitArray([1,2,3,4,5,6,7,8], 3);
console.log(results);
You can adapt it to use dates
With one simple line of code, you may get the solution that may work up to 3 times faster than provided above:
const src = [...'abcdefghijklmnop'];
const chunkArr = (arr, size) => arr.reduceRight((res,_,__,self) => [...res, self.splice(0, size)],[]);
console.log(chunkArr(src, 3));
.as-console-wrapper {max-height: 100% !important; top 0}
As answered by #Alberto Trindade Tavares i just do it by :
/* arr is my original array */
var ressu = splitArray(arr, 7);
function splitArray(arr, chunkSize) {
return Array(Math.ceil(arr.length/chunkSize)).fill().map(function(_,i) {
return arr.slice(i * chunkSize, i * chunkSize + chunkSize);
});
}
You can also do this by using for loop. This is easy to understand.
function splitToChunks(array, parts) {
const result = [];
for (let i = parts; i > 0; i--) {
result.push(array.splice(0, Math.ceil(array.length / i)));
}
return result;
}
var results = splitToChunks([1,2,3,4,5,6,7,8], 3);
console.log(results);
So I'm using the Rickshaw graphing library and I was wondering how to dynamically add points to a graph.
I have a graph instantiated like this:
#seriesData = [ [], [], [] ]
random = new Rickshaw.Fixtures.RandomData(150)
for (var i = 0; i < 50; i++) {
random.addData(self.seriesData)
}
#graph = new Rickshaw.Graph(
element: document.getElementById("chart")
width: 550
height: 300
renderer: 'area'
series: [
{
color: "#c05020"
data: self.seriesData[0]
name: 'One'
}, {
color: "#30c020"
data: self.seriesData[1]
name: 'Two'
}, {
color: "#2791d7"
data: self.seriesData[2]
name: 'Three'
}
]
)
#graph.render()
hoverDetail = new Rickshaw.Graph.HoverDetail(
graph: self.graph
)
legend = new Rickshaw.Graph.Legend(
graph: self.graph
element: document.getElementById('legend')
)
shelving = new Rickshaw.Graph.Behavior.Series.Toggle(
graph: self.graph
legend: legend
)
axes = new Rickshaw.Graph.Axis.Time(
graph: self.graph
)
axes.render()
And I have data coming in through socket.io like this:
app.on('data',
(one, two, three) =>
// Dynamically add data points to graph
)
And I was wondering how to append these three points to the graph. I can't find any good documentation for this library. I know it's built on top of d3.js, but I'm not sure how to incorporate these methods into my graph.
Any help would be appreciated.
I envision two scenario that could solve your question:
Using the fixed Window Series for Streaming Data
leveraging the fact that arrays in javascript are passed by reference. A demo is available here
.
var data = [
{
data: [ { x: 0, y: 120 }, { x: 1, y: 890 }, { x: 2, y: 38 }, { x: 3, y: 70 }, { x: 4, y: 32 } ],
color: "#c05020"
}, {
data: [ { x: 0, y: 80 }, { x: 1, y: 200 }, { x: 2, y: 100 }, { x: 3, y: 520 }, { x: 4, y: 133 } ],
color: "#30c020"
}
];
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
height: 300,
width: 800,
series: data
} );
var y_ticks = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
graph.render();
$('button#add').click(function() {
data.push({
data: [ { x: 0, y: 200 }, { x: 1, y: 390 }, { x: 2, y: 1000 }, { x: 3, y: 200 }, { x: 4, y: 230 } ],
color: "#6060c0"
});
graph.update();
});