How to programmatically set navigator handles in highstock? - css

Is there a way I can programmatically set the markers in highstock navigator, even though I want to keep marker to be set to { type: "day", count: 1, text: "1d" } but not display Zoom 1d.

It's possible to set extremes without rangeSelector using xAxis.setExtremes() method: http://plnkr.co/edit/bRnV1lyJHmmx7YURTggq?p=preview
chart: {
renderTo: 'container',
height: 600,
events: {
load: function() {
var max = this.xAxis[0].max,
range = 24 * 3600 * 1000; // one day
this.xAxis[0].setExtremes(max - range, max);
}
}
},

Related

Rotate/Pan Camera using left/right arrow keys instead of mouse in A-Frame

This may have been asked numerous times, but I can't get a clear "newbie" plan of action.
Building Aframe experiences to showcase some interiors for numerous client presentations—this will be show on a desktop browser only, and I need to be able to control pan/rotate/turn-around camera movement with left and right arrow keys instead of relying on the mouse, as many clients have found this cumbersome. I just need to control this like an old first-person shooter with four arrow buttons.
Is there a simple way to do this? I've seen various permutations of this question but no simple solution so far. Thanks!
A simple keyboard input look component:
AFRAME.registerComponent('kbd-look-controls', {
schema: {
speed: {type: 'number', default: 2}
},
init: function () {
this.bindFunctions();
this.addEventListeners();
this.keyPressed = {
'ArrowUp': false,
'ArrowDown': false,
'ArrowLeft': false,
'ArrowRight': false
}
},
remove: function () {
this.removeEventListeners();
},
tick: function(time, delta) {
var data = this.data;
var object3D = this.el.object3D;
const angleDelta = 0.01 * data.speed * (delta / 16);
if (this.keyPressed['ArrowUp']) {
object3D.rotation.x = object3D.rotation.x + angleDelta;
}
if (this.keyPressed['ArrowDown']) {
object3D.rotation.x = object3D.rotation.x - angleDelta;
}
if (this.keyPressed['ArrowLeft']) {
object3D.rotation.y = object3D.rotation.y + angleDelta;
}
if (this.keyPressed['ArrowRight']) {
object3D.rotation.y = object3D.rotation.y - angleDelta;
}
},
bindFunctions() {
this.onKeyUp = this.onKeyUp.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
},
addEventListeners() {
window.addEventListener('keydown', this.onKeyDown);
window.addEventListener('keyup', this.onKeyUp);
},
removeEventListeners() {
window.removeEventListener('keydown', this.onKeyDown);
window.removeEventListener('keyup', this.onKeyUp);
},
onKeyUp: function (evt) {
this.keyPressed[evt.code] = false;
},
onKeyDown: function (evt) {
this.keyPressed[evt.code] = true;
}
})
Sample usage:
<a-entity camera kbd-look-controls="speed: 2.5" position="0 1 0"></a-entity>
This is one approach to getting to achieve your functionality.
Using wasd-controls component as well can be undesirable, since the wasd-controls also listens to the arrow keys.
Doesn't work with the look-controls component since it's also adjusting the rotation.

Is there a way in Vis.js to keep nodes at the same size while zooming in/out?

I'm wondering whether there is or not a way to keep the size of nodes, in a Vis.js network, always at the same size while zooming in/out
I the Options
{
size: 10,
scaling: {
min: 10,
max: 10
}
}
but this setting doesn't work at all, I also tried with
customScalingFunction: function (min,max,total,value) {
return 1;
}
thinking that this function would run any time there is a re-rendering of the network.
This can be achieved by changing the nodes.size and nodes.font.size options when the network is zoomed. Details on these options can be found in the documentation here and details on the zoom event here. As per the documentation the nodes.size option is only applicable to shapes which do not have the label inside of them.
Example snippet adjusting the size on zoom:
// create an array with nodes
let nodes = new vis.DataSet([
{ id: 1, label: "Node 1" },
{ id: 2, label: "Node 2" },
{ id: 3, label: "Node 3" },
{ id: 4, label: "Node 4" },
{ id: 5, label: "Node 5" },
]);
// create an array with edges
let edges = new vis.DataSet([
{ from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 2, to: 5 },
{ from: 3, to: 3 },
]);
// create a network
const container = document.getElementById("mynetwork");
const data = {
nodes: nodes,
edges: edges,
};
let options = {
nodes: {
shape: 'dot',
size: 10,
font: {
size: 10
}
}
};
const network = new vis.Network(container, data, options);
// Set the initial node size once before network is drawn
network.once("beforeDrawing", function() {
setNodeSize(network.getScale());
});
// Adjust size on zoom
network.on("zoom", function (params) {
setNodeSize(params.scale);
});
function setNodeSize(scale){
// Update node size dependent on scale
options.nodes.size = (10 / scale);
options.nodes.font.size = (10 / scale);
network.setOptions(options);
}
#mynetwork {
width: 600px;
height: 160px;
border: 1px solid lightgray;
}
<script src="https://visjs.github.io/vis-network/standalone/umd/vis-network.min.js"></script>
<div id="mynetwork"></div>
Regarding the scaling options, I don't believe they can be used to achieve this. Scaling is relative to other nodes on the network, not the viewport / zoom. A quick example to illustrate changing the scaling value is https://jsfiddle.net/34b682qs/. Clicking on the button toggles the scaling value set for each node in sequence between 10 and 20. When all nodes have the same value the network scales them all to be the same size regardless of if that value is 10 or 20. Therefore adjusting this value on zoom would have no effect.

Full Calendar v3 extending display beyond end of calendar year in List View

Good morning!
I have a list view set up in full calendar and have noticed that it will not display events beyond the end of the year. With it being now mid-December, this is a bit of a problem for me. We have several event that should be displaying in this list. When I change the view to month I have to click the next month button to get next years events, but at least with that I do sucessfully see the events in question.
Is there a way for my list view calendars to roll-over and include next year entries as I approach the end of the current year?
Here is an excerpt of what I have that effects the display of my calendar:
{url:'https://calendar.mydomain.com/services/id/38djsuw3hr-au8reh39dq/organization/1/department/13/',event_properties:{color:'#6a9b49'}},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: '',
center: '',
right: '' //view options on top-right (supported by v2.9.1 currently)
},
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
// opens events in a new window or tab
window.open(event.url,);
return false;
},
// eventDataTransform: function(rawEventData){
// return {title: rawEventData.Title
// };
// },
defaultView: $(window).width() < 765 ? 'listYear':'listYear', //carryover code from full sized calendar
nowIndicator: false, //show a marker for current time
eventLimit: 4, // allow "more" link when too many events
fixedWeekCount: false, // have blank rows on a 6 or 7 row month
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
allDayDefault: false,
noEventsMessage: "No Currently Scheduled Events"
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
All I see is my "NoEventsMessage" text when in list view. If I create a test event the occurs prior to the end of the year it shows up in list view.
Any ideas on spanning calendar end?
thanks
[Edit: I should say that the link at the top is a JSON feed, so I am not using a prefilled list of events from within my script or from within an external file]
Here is how I solved it.
I created a custom view entry for the specific default view called "list" and gave it a one year duration:
views: {
list: {
duration: { days:365 }
}
},
I reset my default view from the dynamic version I carried over from my full-sized calendar (since I am using this in a column anyway and the window width call is not needed):
From:
defaultView: $(window).width() < 765 ? 'listYear':'listYear',
To:
defaultView: 'list',
After doing those things my January entries for next year began to display in list view.
Here is what my display calls look like (If someone wants to edit this to make it look prettier and more efficient, I don't mind :).
ics_sources = [
{url:'https://calendar.mydomain.com/services/id/38djsuw3hr-au8reh39dq/organization/1/department/13/',event_properties:{color:'#6a9b49'}},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: false,
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
// opens events in a new window or tab
window.open(event.url,);
return false;
},
defaultView: 'list',
nowIndicator: false, //show a marker for current time
eventLimit: 4, // allow "more" link when too many events
fixedWeekCount: false, // have blank rows on a 6 or 7 row month
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
noEventsMessage: "No Currently Scheduled Events",
views: {
list: {
duration: { days: 365 },
}
}
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
Thanks.
[edit: removed extraneous backticks from answer.]

Visjs timeline edit content item template

I'd like to be able to edit the content attribute of visjs timeline items in the timeline itself. However, when I use an input as part of a template, it doesn't appear to receive any mouse events; I can't click in it and type anything, and clicking buttons doesn't work, either. Buttons appear to get the mouseover event, though:
function test(item) {
alert('clicked');
}
var options = {
minHeight: '100%',
editable: true,
moveable: false,
selectable: false,
orientation: 'top',
min: new Date('2015-01-01'),
max: new Date('2015-12-31'),
zoomMin: 1000 * 4 * 60 * 24 * 7,
margin: {
item: 10,
axis: 5
},
template: function(item) {
return '<div onClick="test"><input value="click in the middle"></input><button onClick="test">test</button></div>'
}
};
/* create timeline */
timeline.on('click', function (properties) {
var target = properties.event.target;
if(properties.item) properties.event.target.focus();
});
https://codepen.io/barticula/pen/EpWJKd
Edit: Code above CodePen example have been updated to use the click event to focus on the input, but all other normal mouse behavior is missing. Keyboard events appear to function normally.
To get a reaction with a click on a timeline element, you can use the library's own events (see events on doc and this exemple on website).
On your example, you could do something like this among other possible solutions in pure javascript including...
// Configuration for the Timeline
var options = {
minHeight: '100%',
editable: true,
moveable: false,
selectable: false,
orientation: 'top',
min: new Date('2015-01-01'),
max: new Date('2015-12-31'),
zoomMin: 1000 * 4 * 60 * 24 * 7,
margin: {
item: 10,
axis: 5
},
template: function(item) {
return '<div id="test-div"><input placeholder="hey" type="text" id="inputTest" ><button id="test-button">test</button></div>'
}
};
// Create a Timeline
var timeline = new vis.Timeline(container, null, options);
timeline.setGroups(groups);
timeline.setItems(items);
timeline.on('click', function (properties) {
var target = properties.event.target;
if(properties.item) alert('click on' + target.id);
});
UPDATED
It is difficult to know exactly what you want to do because there are several possible solutions anyway.
Eventually, I propose another snippet below and a codepen updated.... but will it meet your need, not sure ?
2nd UPDATE (for another work track, see comments)
// Configuration for the Timeline
var options = {
minHeight: '100%',
editable: true,
moveable: false,
selectable: false,
orientation: 'top',
margin: {
item: 10,
axis: 5
},
template: function(item) {
return '<div><input placeholder="edit me..." type="text"></input><button>send value</button></div>'
}
};
// Create a Timeline
var timeline = new vis.Timeline(container, null, options);
timeline.setGroups(groups);
timeline.setItems(items);
timeline.on('click', function(properties) {
var target = properties.event.target;
var item = items.get(properties.item);
console.log(properties.event);
// if (properties.item && target.tagName === "DIV") focusMethod(target);
if (properties.item && target.tagName === "INPUT") target.focus();
if (properties.item && target.tagName === "BUTTON") getInputValue(item, target);
});
focusMethod = function getFocus(target) {
// target.insertAfter("BUTTON");
target.firstChild.focus();
}
getInputValue = function getValue(item, target) {
target.focus();
var inputValue = (target.parentNode.firstChild.value) ? target.parentNode.firstChild.value : "no value entered ";
alert("Input value : " + inputValue + " => send by: " + item.content)
}

Google Analytics - Stacked Column Chart - How to add more X-axis tick marks

I have a page in a web app showing new users vs. users, and I'm charting it in a column chart. The JS looks like this:
var dataChart1 = new gapi.analytics.googleCharts.DataChart({
query: {
metrics: 'ga:newUsers, ga:users',
dimensions: 'ga:date',
'start-date': beginDate,
'end-date': endDate
},
chart: {
container: 'chart1-container',
type: 'COLUMN',
options: {
width: '100%',
isStacked: true
}
}
});
The result stacked column chart looks as follows:
As you can see there no X-axis tick marks, and I would like to add them for each date in the chart. How would I do this?
You could modify the chart and redraw.
Not sure what your data looks like. But you may need to remove duplicates from chartTicks...
dataChart1.on('success', function(response) {
// response.chart : the Google Chart instance.
// response.data : the Google Chart data object.
var chartTicks = [];
for (var i = 0; i < response.data.getNumberOfRows(); i++) {
chartTicks.push(response.data.getValue(i, 0));
}
var options = {
width: '100%',
isStacked: true,
hAxis: { ticks: chartTicks }
}
response.chart.draw(response.data, options);
});

Resources