how can i change position of inputs in high charts high-stock? - javascript

This is default style of my chart in highcharts :
I want to change position of inputs, charts that I use are from https://www.highcharts.com/ site , i want to change from input from left to right and to input from right to left with from and to texts
I want to be like this image :
How can I do that?

It's impossible to change in regular Highcharts API options, but making some changes in core code does the job.
jsFiddle demo
At Highcharts.RangeSelector.prototype.render we need to switch sequence of triggering rangeSelector.drawInput functions:
if (inputEnabled !== false) {
rangeSelector.div = div = createElement('div', null, {
position: 'relative',
height: 0,
zIndex: inputsZIndex
});
container.parentNode.insertBefore(div, container);
// Create the group to keep the inputs
rangeSelector.inputGroup = inputGroup =
renderer.g('input-group').add(group);
inputGroup.offset = 0;
rangeSelector.drawInput('max');
rangeSelector.drawInput('min');
}
In Highcharts.RangeSelector.prototype.drawInput I made some styling/creating changes here:
// Create an SVG label that shows updated date ranges and and records
// click events that bring in the HTML input.
this[name + 'DateBox'] = dateBox = renderer.label('', inputGroup.offset)
.addClass('highcharts-range-input')
.attr({
padding: 2,
width: options.inputBoxWidth || 90,
height: options.inputBoxHeight || 17,
'text-align': 'center'
})
.on('click', function() {
// If it is already focused, the onfocus event doesn't fire
// (#3713)
rangeSelector.showInput(name);
rangeSelector[name + 'Input'].focus();
});
// Create the text label
this[name + 'Label'] = label = renderer.label(
lang[isMin ? 'rangeSelectorFrom' : 'rangeSelectorTo'],
this.inputGroup.offset
)
.addClass('highcharts-range-label')
.attr({
padding: 2,
paddingLeft: 100
})
.add(inputGroup);
inputGroup.offset += label.width - 85;

Related

Pop up div with absolute position next to click

I am trying to make a right click lead to a div pop up. However, the click will be inside a cesium window, which only lets a div show if it has absolute position. Is it possible to edit the pop up position of a div with absolute position?
Right now, my code looks like this:
var editHandler = newCesium.ScreenSpaceEventHandler(scene.canvas);
editHandlersetInputAction(function(e){
var shapeEditMenu = document.getElementById("shapeEditMenu");
shapeEditMenu.style.display = "block";
shapeEditMenu.style.left = e.clientX;
shapeEditMenu.style.top = e.clientY;
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
#shapeEditMenu {
position: absolute;
display: none:
top: 80px;
height: 50px;
width: 80px;
}
<div id="shapeEditMenu">
Line thickness:
<input type="number"> pt
</div>
It doesn't work here because there isn't cesium, but what happens in my actual code is that the div pops up on right click, but always is at the same position, not at the place where you right click.
As mentioned in the comments, there is some API confusion going on here. clientX is part of browser-native API, not Cesium's API. Since you're using Cesium's event handling system, you get events from that API. In this case, you would use e.position.x and follow that up with a + 'px' to indicate CSS-pixel units for the stylesheet.
Also you have a few typos here:
newCesium. should be new Cesium.
editHandlersetInputAction should be editHandler.setInputAction
display: none: should be display: none;
Here's a live Sandcastle demo that shows a right-click "Testing" menu show up at the mouse location.
var viewer = new Cesium.Viewer('cesiumContainer');
var editHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
editHandler.setInputAction(function(e) {
var shapeEditMenu = document.getElementById("toolbar");
shapeEditMenu.textContent = 'Testing';
shapeEditMenu.style.display = "block";
shapeEditMenu.style.left = e.position.x + 'px';
shapeEditMenu.style.top = e.position.y + 'px';
shapeEditMenu.style.background = 'rgba(42, 42, 42, 0.8)';
shapeEditMenu.style.border = '1px solid #888';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
editHandler.setInputAction(function(e) {
var shapeEditMenu = document.getElementById("toolbar");
shapeEditMenu.style.display = "none";
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

Hiding an object using css

I am trying to hide a vertical bar I have created in a jQuery Flot graph when the mouse is not within the bounds of the grid. I set me horizontal bounds for the grid as such: horizontalBounds = [leftOffset, plot.width() + leftOffset];. I then used an if statement to say "if the mouse is within the vertical bounds, do this to the verticalBar.css."
if (position.pageX >= horizontalBounds[0] && position.pageX <= horizontalBounds[1]) {
if (typeof verticalBar !== "undefined" && verticalBar !== null) {
verticalBar.css({
transform: "translate(" + position.pageX + "px, 0px)"
});
}
Below is my css code (which is actually in my javascript file; don't ask...). What do I need to do to hide the verticalBar when the mouse is not within those horizontal bounds? I was thinking I could just add the attribute `visibility: hidden' to the verticalBar.css, but I can't figure out how to do that. Any hints?
verticalBar.css({
backgroundColor: "#F7E4E6",
width: "1px",
height: "100%",
position: "absolute",
padding: 0,
margin: 0,
left: 0,
transform: "translateX(" + plot.getPlotOffset().left + "px)"
});
}
try using "display:none;" in your CSS.
Depending on how you're wanting to hide the bar, you can have something as simple as display: none.
If you're wanting to add in some animations, you could use some jQuery functions to control that particular node.
You could also utilize a set of CSS class name swaps to trigger some CSS animations.
so none of those methods seemed to work for me. I ended up discovering that Flot has a crosshair plugin (flot.crosshair). The crosshair can be configured to act only on the x axis/ x coordinate as it tracks the movement of the mouse. Here is an example of the crosshair tracking in action: Flot Tracking Example.
Once the plugin was added, I was able to get the desired results; as the "vertical bar" only shows up when the cursor is on the grid. Below is really all you need to do to configure it (other than adding the plugin to the appropriate files). Hope this helps someone in the future.
plot = $.plot(
placeholder
data
grid:
clickable: true
hoverable: true
color: "white"
mouseActiveRadius: 1000
tooltip:
show: true
content: '%y'
crosshair:
mode: "x"
color: "#FFFFFF"
lineWidth: 1

jointjs: get position of label and set position to center of link-segments

I would like to add a label to a link, which I do like this:
paper.on({
'cell:pointerdblclick': function(cellView, event, x, y){
// Set label for this link
if (cellView.model.isLink()) {
var cellId = cellView.model.id,
label = cellView.model.get('labels'),
content = 'Text';
if (label) { // edit existing label
$('#canvas').prepend('<input type="text" id="overlay" data-id="' + cellId + '" style="top: 20px; left: 20px;" value="' + content + '">');
$('#overlay').focus().select();
}
else { // create new label
cellView.model.label(0, {
position: .5,
attrs: {
rect: { fill: 'white' },
text: { text: 'my label' }
}
});
}
}
}
});
If there is an existing label an overlay is beeing added for editing the text. To get this input field exactly over the label, I need to know the position of this. But the position isn't defined as a absolute position on the paper, but a value relative to the start point. Otherwise I could just use the x and y value for positioning of the input field.
I'm using links in manhattan style, that means there could be multiple segments as a link isn't a straight line. Now I would like to position a label always in the center of a segment. Also the label can be dropped from one segment to another segment. But the label attribute position uses the complete lenth of the link and not just of one segment. I don't know from where I can get this informations.

How to set the auto width for combo box in Kendo UI?

I want to set the combo box width automatically based on the lengthiest text which is bound to the Combo box, so I tried like below, but I am able to see the auto size (width) only for drop down (drop down when clicking the combo) of the combo box, still the length is greater than expected, the overall length should be reduced to hold only 3 characters, am I missing something here?
<input id="combobox" />
$("#combobox").kendoComboBox({
index: 0,
dataSource: {
data: ["One", "Two"]
}
});
var comboBox = $("#combobox").data("kendoComboBox");
comboBox.list.width("auto");
$("#combobox").width(parseInt($("#combobox").css("width")));
http://jsfiddle.net/KendoDev/Z4rwQ/
I guess you could determine the length in the datasource itself, and then resize the combobox. This works for a demo project, but i guess depending on styles and padding that you might need to to some more refining to the sizing technique.
This determines the size of the elements (again, in case you are using objects instead of strings inside the array, you might need to refine it a bit (you could pass the displayMember if you'd like)
function determineWidth(ds) {
var l = ds.length, selement = document.createElement('span'), maxwidth = 0, curwidth = 0;
selement.style = 'position: fixed; left: -500px; top: -500px;';
document.body.appendChild(selement);
for (var i = 0; i < l; i++) {
$(selement).html(ds[i]);
curwidth = $(selement).width();
if (curwidth < maxwidth) {
continue;
}
maxwidth = curwidth;
}
document.body.removeChild(selement);
return curwidth + 24;
}
inside the combobox, you can bind to the dataBound event, determine the size of the elements, and update the container and parent to match the actual size
$("#combobox").kendoComboBox({
index: 0,
dataSource: {
data: ["One", "Two", "Hundred"]
},
dataBound: function() {
var width = determineWidth(this.dataSource.data());
$('#combobox-container').find('span>.k-dropdown-wrap').width(width).parent().width(width);
}
});
var comboBox = $("#combobox").data("kendoComboBox");
fiddle you can find here: http://jsfiddle.net/Icepickle/gLbLtjhf/
I will like to add, if you want to have a fixed width of comboBox irrespective of the data item length then define the "HtmlAttributes" property while defining the combo box:
#(Html.Kendo().ComboBox().Name("myCombo")
.DataTextField("Text")
.DataValueField("Value")
.Placeholder("--- Select ---")
.DataSource(src => src.Read(read => read.Action("ActionMethod", "Controller")))
.HtmlAttributes(new { style = "width: 200px;"})
)
Or from javascript:
var combobox = $("#combobox").data("kendoComboBox");
combobox.list.width(200);
Reference Link
Try adding this css.
.k-combobox
{
display: inline !important;
}
and register open event
open: function(e) {
var width = $(".k-combobox").width();
$(".k-animation-container").width(width);
$(".k-list-container").width(width - 4);
}
DEMO
update
Perhaps you need to wrap the combobox and wrap it with div.
<div id="combobox-container">
<input id="combobox" />
</div>
then change the jquery into
open: function(e) {
var width = $("#combobox-container").width();
$("#combobox-container").parent().find(".k-animation-container").width(width);
$("#combobox-container").parent().find(".k-list-container").width(width - 4);
}
UPDATED DEMO

jQuery/JavaScript collision detection

How to detect if two <div> elements have collided?
The two divs are simple coloured boxes travelling perpendicular to each other, so no complicated shapes or angles.
var overlaps = (function () {
function getPositions( elem ) {
var pos, width, height;
pos = $( elem ).position();
width = $( elem ).width();
height = $( elem ).height();
return [ [ pos.left, pos.left + width ], [ pos.top, pos.top + height ] ];
}
function comparePositions( p1, p2 ) {
var r1, r2;
r1 = p1[0] < p2[0] ? p1 : p2;
r2 = p1[0] < p2[0] ? p2 : p1;
return r1[1] > r2[0] || r1[0] === r2[0];
}
return function ( a, b ) {
var pos1 = getPositions( a ),
pos2 = getPositions( b );
return comparePositions( pos1[0], pos2[0] ) && comparePositions( pos1[1], pos2[1] );
};
})();
$(function () {
var area = $( '#area' )[0],
box = $( '#box0' )[0],
html;
html = $( area ).children().not( box ).map( function ( i ) {
return '<p>Red box + Box ' + ( i + 1 ) + ' = ' + overlaps( box, this ) + '</p>';
}).get().join( '' );
$( 'body' ).append( html );
});
body {
padding: 30px;
color: #444;
font-family: Arial, sans-serif;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
#area {
border: 2px solid gray;
width: 500px;
height: 400px;
position: relative;
}
#area > div {
background-color: rgba(122, 122, 122, 0.3);
position: absolute;
text-align: center;
font-size: 50px;
width: 60px;
height: 60px;
}
#box0 {
background-color: rgba(255, 0, 0, 0.5) !important;
top: 150px;
left: 150px;
}
#box1 {
top: 260px;
left: 50px;
}
#box2 {
top: 110px;
left: 160px;
}
#box3 {
top: 200px;
left: 200px;
}
#box4 {
top: 50px;
left: 400px;
}
p {
margin: 5px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<h1>Detect overlapping with JavaScript</h1>
<div id="area">
<div id="box0"></div>
<div id="box1">1</div>
<div id="box2">2</div>
<div id="box3">3</div>
<div id="box4">4</div>
</div>
General idea - you get the offset and dimension of the boxes and check whether they overlap.
If you want it to update, you can use setInterval:
function detectOverlapping() {
// code that detects if the box overlaps with a moving box
setInterval(detectOverlapping, 25);
}
detectOverlapping();
Also, note that you can optimize the function for your specific example.
you don't have to read the box dimensions repeatedly (like I do in my code) since they are fixed. You can read them on page load (into a variable) and then just read the variable
the horizontal position of the little box does not change (unless the user resizes the window). The vertical positions of the car boxes does not change. Therefore, those values also do not have to be read repeatedly, but can also be stored into variables.
you don't have to test whether the little box overlaps with all car boxes at all times. You can - based on its vertical position - figure out in which lane the box is currently, and test only the specific car box from that lane.
I believe this is the easiest way:
https://plugins.jquery.com/overlaps/
Here is another one, in German:
http://www.48design.de/news/2009/11/20/kollisionsabfrage-per-jquery-plugin-update-v11-8/
I'd give those a try.
--UPDATE--
I can't really spend anytime on it right now, but i can when i get home if no one answers but you;d do something like:
setInterval(function(){
//First step would be to get the offset of item 1 and item 2
//Second would be to get the width of each
//Third would be to check if the offset+width ever overlaps
//the offset+width of the 2nd
//Fourth would be, if so, do X or set a class...
},10);
Its a little late on this but I guess you could use this approach that I tried when I was faced with the similar situation. The advantage here is that there are no additional plugin, or scripts involved and neither do you have to introduce performance hungry polling into it.
This technique uses the the built-in methods and events that Jquery's droppable has to offer.
Ok, enough said, here's the solution technique:
Say if you have two elements (images in my case) and you don't want them to overlap or detect when they do, make the two elements a droppable and make them to 'accept' each other:
$([div1, div2]).droppable(CONFIG_COLLISSION_PREVENTION_DROPPABLE);
The 'CONFIG_COLLISSION_PREVENTION_DROPPABLE' looks like this:
var originatingOffset = null;
CONFIG_COLLISSION_PREVENTION_DROPPABLE = {
tolerance: "touch",
activate : function (event, ui) {
// note the initial position/offset when drag starts
// will be usedful in drop handler to check if the move
// occurred and in cae overlap occurred, restore the original positions.
originatingOffset = ui.offset;
},
drop : function (event, ui) {
// If this callback gets invoked, the overlap has occurred.
// Use this method to either generate a custom event etc.
// Here, i used it to nullify the move and resetting the dragged element's
// position back to it's original position/offset
// (which was captured in the 'activate' handler)
$(ui.draggable).animate({
top: originatingOffset.top + "px",
left: originatingOffset.left + "px"
}, 300);
}
}
The 'activate' and 'drop' handlers refer to the 'dropactivate' and 'drop' events of "droppable" plugin
Here, the key is the 'drop' callback. Whenever any of the two elements overlap and they are dropped over each other, the 'drop' will be called. This is the place to detect and take actions, may be sending out custom events or calling other actions (I here chose to revert the overlapping element's positions to the initial position when the drag started, which was captured in 'activate' callback).
That's it. No polling, no plugins, just the built-in events.
Well, there can be other optimizations/extensions done to it, this was simply the first shot out of my head that worked :)
You can also use the 'dropover' and 'dropout' events to signal and create a visual feedback to the user that two elements are overlapping, while they may be still on the move.
var CLASS_INVALID = "invalid";
// .invalid { border: 1px solid red; }
...
$.extend(CONFIG_COLLISSION_PREVENTION_DROPPABLE, {
over : function (event, ui) {
// When an element is over another, it gets detected here;
// while it may still be moved.
// the draggable element becomes 'invalid' and so apply the class here
$(ui.draggable).addClass(CLASS_INVALID);
},
out : function(event, ui) {
// the element has exited the overlapped droppable now
// So element is valid now and so remove the invalid class from it
$(ui.draggable).removeClass(CLASS_INVALID);
}
});
Hope this helps!
You can do this using getBoundingClientRect()
function isOverlapping(div1, div2){
const div1 = div1.getBoundingClientRect();
const div2 = div2.getBoundingClientRect();
return (div1.right > div2.left &&
div1.left < div2.right &&
div1.bottom > div2.top &&
div1.top < div2.bottom)
}
EDIT: I have written a blog post on my website. Here a link to it.
http://area36.nl/2014/12/creating-your-own-collision-detection-function-in-javascript/
Well I had the same problem but thanks to the answer of Oscar Godson I got a function that works. I used Jquery for easy coding and because i'm lazy ;p. I put the function in a other function that is fired every second so keep that in mind.
function collidesWith (element1, element2) {
var Element1 = {};
var Element2 = {};
Element1.top = $(element1).offset().top;
Element1.left = $(element1).offset().left;
Element1.right = Number($(element1).offset().left) + Number($(element1).width());
Element1.bottom = Number($(element1).offset().top) + Number($(element1).height());
Element2.top = $(element2).offset().top;
Element2.left = $(element2).offset().left;
Element2.right = Number($(element2).offset().left) + Number($(element2).width());
Element2.bottom = Number($(element2).offset().top) + Number($(element2).height());
if (Element1.right > Element2.left && Element1.left < Element2.right && Element1.top < Element2.bottom && Element1.bottom > Element2.top) {
// Do your stuff here
}
}
What it does is basically it gets all the values of element1 and then get all the values of element2. Then with the help of some calculations it figures out all the values. Then in the if statement it compares the square of element1 to the square of element2. If the values of element1 are between the left, right, top and bottom values of element2. If that is true the code in the bottom is executed.
I ran into this generalized issue myself, so (full disclosure) I made a plugin for it. For simple collision queries about static objects, try this:
http://sourceforge.net/projects/jquerycollision/
Which allows you to get a list of overlapping collision boxes (or none if there's no collision):
hits = $("#collider").collision(".obstacles");
Or to get a collision event during "dragging", use this:
http://sourceforge.net/apps/mediawiki/jquidragcollide/?source=navbar#collision
Which gives you a "collision" event to connect to. (Or a "protrusion" event, to see if a div escapes another div that currently contains it.)
$(draggable).bind(
"collision",
function(event,ui) {
...
}
);
If you are checking collisions during motion other than dragging, just call the original repeatedly, it's pretty quick. Note: the dragging one doesn't play nicely with resizing.
Post is old, May be it help someone...
function CheckDiv()
{
var ediv1 = document.getElementById('DIV1');
var ediv2 = document.getElementById('DIV2');
ediv1.top = $(ediv1).offset().top;
ediv1.left = $(ediv1).offset().left;
ediv1.right = Number($(ediv1).offset().left) + Number($(ediv1).width());
ediv1.bottom = Number($(ediv1).offset().top) + Number($(ediv1).height());
ediv2.top = $(ediv2).offset().top;
ediv2.left = $(ediv2).offset().left;
ediv2.right = Number($(ediv2).offset().left) + Number($(ediv2).width());
ediv2.bottom = Number($(ediv2).offset().top) + Number($(ediv2).height());
if (ediv1.right > ediv2.left && ediv1.left < ediv2.right && ediv1.top < ediv2.bottom && ediv1.bottom > ediv2.top)
{
alert("hi");
}
if (ediv1.left > ediv2.left && ediv1.top > ediv2.top && ediv1.right < ediv2.right && ediv1.bottom < ediv2.bottom)
{
alert("hello");
}
}

Categories

Resources