I have a Map and a List inside the same container with 2:5 flex ratio set. I would like to be able to toggle doubleclick on the map to maximize it to fill the container or reset it back to the original size depending whether the List is hidden. I wrote the function below and bound it to the map's dblclick event. I see it go into this function but it has no effect on what I see. Any ideas why my list won't animate and hide?
google.maps.event.addListener(that.getMap(), 'dblclick', function () {
var list = Ext.ComponentQuery.query('#BuildingList')[0];
var height = list.getHeight();
if (list.isHidden()) {
list.show(Ext.Anim({
easing: 'easeInOut',
duration: 1000,
autoClear: false,
from: {
opacity: 0,
height: '0px'
},
to: {
opacity: 1,
height: list.getHeight() + 'px'
}
}));
} else {
list.hide(Ext.Anim({
easing: 'easeInOut',
duration: 1000,
autoClear: false,
from: {
opacity: 1,
height: list.getHeight() + 'px'
},
to: {
opacity: 0,
height: '0px'
}
}))
}
});
The best way to do this sort of thing I found was to set the flex to 0 of the list on the dblclick event (which I had to add as an override to the map), as follows:
that.addAfterListener('dblclick', function (view, map, zoomlevel, eOpts) {
var list = view.getParent().down('buildings');
Ext.Anim.run(list, 'fade', {
easing: 'easeInOut',
autoClear: false,
duration: 300,
after: function () {
list.setFlex(0);
}
});
});
Related
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.
Follow the vaadin guidence of web component to create a meter:
#Tag("dw-meter")
#NpmPackage(value = "echarts", version = "5.2.2")
#JsModule("../node_modules/echarts/dist/echarts.js")
#JsModule("./dwmeter.webcomponent.js")
public class DwMeter extends Div {
}
Integrate the meter into a demo application:
DwMeter meter = new DwMeter();
meter.setWidth("100px");
meter.setHeight("100px");
add(meter);
Application is executed successfully, but the meter is not displayed.
Trace the web page, Tag <dw-meter> and <canvas> are generated correctly :
Changed Tag <dw-meter> to <div>, the meter is visible:
My question is how to visualize an user-defined vaadin web component? e.g. <dw-meter>
attached dwmeter.webcomponent.js:
import * as ECharts from "echarts";
class dwMeter extends HTMLElement {
constructor() {
super();
}
init(o) {
// Shadow root
const shadowRoot = this.attachShadow({mode: 'open'});
// container
var container = document.createElement('div');
shadowRoot.appendChild(container);
// Garantee all elements are rendered
setTimeout(function() {
var myChart = ECharts.init(o); //container
myChart.setOption(o.options());
}, 0);
}
options() {
const gaugeData = [
{
value: 0.25,
name: 'pressure',
title: {
offsetCenter: ['0%', '90%']
}
}
];
var option = {
series: [
{
type: 'gauge',
min: 0,
max: 0.25,
splitNumber: 5,
progress: {
show: false,
width: 5
},
axisLine: {
lineStyle: {
width: 5,
color: [[1, 'rgba(36,177, 76)']]
}
},
axisTick: {
show: false
},
splitLine: {
length: -10,
lineStyle: {
width: 5,
color: 'rgba(36,177, 76)'
}
},
axisLabel: {
distance: -20,
color: '#999',
fontSize: 10
},
anchor: {
show: true,
showAbove: true,
size: 12,
itemStyle: {
borderWidth:0,
color: 'rgba(36,177, 76)',
}
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 5,
length: '60%',
offsetCenter: [0, '8%'],
itemStyle: {
color: 'rgba(36,177, 76)'
}
},
title: {
color: 'rgba(36,177, 76)',
fontSize: 14,
fontWeight: 800,
fontFamily: 'Arial',
offsetCenter: [0, '100%']
},
detail: {
valueAnimation: true,
fontSize: 12,
offsetCenter: [0, '55%'],
show: true
},
data:gaugeData
}
]
};
return option;
}
connectedCallback() {
this.init(this);
}
disconnectedCallback() {
}
attributeChangedCallback() {
}
clone(origin, target) {
var target = target || {};
for(var prop in origin) {
target[prop] = origin[prop];
}
}
}
window.customElements.define('dw-meter', dwMeter);
The reason that nothing is shown when you're using the <dw-meter> custom element is that it has a shadow root, while the actual content (rendered by the ECharts library) is outside that shadow root. Whenever an element has a shadow root, then the content of the shadow root will be rendered and the content outside the shadow root will be rendered in the location of a <slot> element inside the shadow root. If there is no <slot>, then it won't be shown anywhere at all.
If you want to use the shadow root to encapsulate styles, then you would at the very least need to change ECharts.init(o) to instead do ECharts.init(container). There might also be other things that you need to change to make it work properly, but that depends on exactly how ECharts is implemented. The o parameter that I assume you're passing from the server is most likely redundant since this is already a reference to the top-level element.
After adding attribute "maximizable:true" , a button will be appear on the pop up window . After I click on maximize button, window is moving towards left . It is not coming in the center of the screen .
detailsWindow = new Ext.Window( {
title :
"Details",
maximizable:true,
width:screen.width*.30,
height:screen.height*.40,
minWidth:screen.width*.30,
minHeight:screen.height*.40,
maxWidth:screen.width*.90,
maxHeight:screen.height*.85,
modal: true,
constrain: true,
layout: 'fit',
alwaysOnTop :true,
autoDestroy:true,
scrollable:true,
items : [detailsGrid],
listeners:{
afterrender:function(){
Ext.defer(function(){
if(this!=null && this.body!=null && this.body.dom!=null){
window.scrollTo(this.x,this.y);
this.body.dom.scrollTop=0;
}
},100,this);
}
}
});
See here
Normally, when you maximize a window it maximizes to the entire screen. But, in your case you have provided min/max height and width. So thats why its not taking full screen size. If you want to position the window at center even after maximizing it then you can add a maximize listener and provide a style of left as done in below code:
Ext.create(Ext.window.Window, {
title: "Details",
maximizable: true,
width: screen.width * .30,
height: screen.height * .40,
minWidth: screen.width * .30,
minHeight: screen.height * .40,
maxWidth: screen.width * .90,
maxHeight: screen.height * .85,
modal: true,
constrain: true,
layout: 'fit',
alwaysOnTop: true,
autoDestroy: true,
scrollable: true,
// items : [detailsGrid],
listeners: {
afterrender: function () {
Ext.defer(function () {
if (this != null && this.body != null && this.body.dom != null) {
window.scrollTo(this.x, this.y);
this.body.dom.scrollTop = 0;
}
}, 100, this);
},
maximize: function (win) {
var width = (screen.width - win.getWidth()) / 2;
win.setStyle('left', width + 'px');
}
}
}).show();
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)
}
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);
}
}
},