uiSlider - Values and image of the slider are misaligned - javascript

I'm trying to implement a Qualtrics survey, where I want to have an image of a ladder and a vertical slider next to it (where participants can set where they're on the ladder). The values on the slider run from 1 to 10, but the handle cannot be set to 10, but can be set to 0 (which is graphically under the slider itself). Furthermore, if I set 4 on the slider, it interprets it as 5 (similarly, if I set 0, it thinks it's 1, and so on). Do you know what am I doing wrong? I'm attaching the JS and the HTML scripts. I would be tremendously grateful if anyone could help! Thanks in advance
Here is the screenshot of the handle being under the slider
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
var vSlider = document.getElementById('uiSlider');
noUiSlider.create(vSlider,
{
start: 5,
step: 1,
direction: 'rtl',
orientation: 'vertical',
range: {
min: 1,
max: 10
},
format: wNumb(
{
decimals: 0
}
),
// Show a scale with the slider
pips: {
mode: 'steps',
stepped: true,
density: 10,
}
}
);
var inputNumber = document.getElementById('QR~'+this.questionId+'~1');
vSlider.noUiSlider.on('update', function (values, handle) {
inputNumber.value = values[handle];
}
);
inputNumber.addEventListener('change', function () {
vSlider.noUiSlider.set([null, this.value]);
}
);
inputNumber.setAttribute('readonly',true)
}
);
Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/
});
Qualtrics.SurveyEngine.addOnUnload(function()
{
/*Place your JavaScript here to run when the page is unloaded*/
});
<table style="width:100%">
<tbody>
<tr>
<td style="padding-right:10px; width:65%; vertical-align: top;" rowspan="3"><img style="width: 600px; height: auto;" src="https://www.researchgate.net/profile/Paul-Vaucher/publication/259879628/figure/fig3/AS:341740713201697#1458488743795/MacArthur-scale-of-subjective-social-status-It-is-used-to-assess-patient-and-doctor.png"></td>
</tr>
<tr>
<td style="padding-left:30px;">
<div style="height:375px;" id="uiSlider"> </div>
</td>
</tr>
</tbody>
</table>

Try to add this:
inputNumber.addEventListener('change', function () {
vSlider.noUiSlider.set(values[handle]);
}
Instead of this:
inputNumber.addEventListener('change', function () {
vSlider.noUiSlider.set([softSlider.noUiSlider.set]);
}
It will help you to reach number "10".
And about the number "0", actually it not "0" it is "1" in your scale. If you will take a look closer, so when you are setting "7", actually your handle is under the 7th mark, same if you are setting 10, handle is under 10th mark. So position of the handle, which you consider as "0" is actually a "1" in the design you have chosen.
Hovewer, you can override this behaviour, by adding those lines:
var override = document.getElementsByClassName('noUi-base')[0];
override.style.position = "initial"
Below the code where the slider is created.
noUiSlider.create(vSlider,
{
start: 5,
step: 1,
direction: 'rtl',
orientation: 'vertical',
range: {
min: 1,
max: 10
},
format: wNumb(
{
decimals: 0
}
),
// Show a scale with the slider
pips: {
mode: 'steps',
stepped: true,
density: 10,
}
}
);

Related

Is there a stable way to set echarts axis limits from html id value

I'm writing an electron.js app where I'm using echart.js to display a heatmap.
Two html input tags are used to let the user set the axis limits for the heatmap.
<span>
<input type="number" id="min_limit" value= 1>
<input type="number" id="max_limit" value= 2>
</span>
In the javascript code I'm simply using the following to get this content:
data_min = document.getElementById('min_limit').value;
data_max = document.getElementById('max_limit').value;
The problem occurs when I try to use these two variables within the echart option:
option = {
...
visualMap: {
min: data_min,
max: data_max,
...
}
}
I get the following error:
"Uncaught DOMException: Failed to execute 'addColorStop' on 'CanvasGradient': The value provided ('undefined') could not be parsed as a color."
The interesting thing is that the program works when I try any of the following (only one of the input values respectively but not both at the same time):
option = {
...
visualMap: {
min: 0,
max: data_max,
... // No errors
}
}
option = {
...
visualMap: {
min: data_min,
max: 1,
... // No errors
}
}
option = {
...
visualMap: {
min: 0,
max: 1,
... // No errors
}
}
And calling*:
myChart.setOption(option);
To display the chart.
Any suggestions? I'm new to html and JavaScript so there may be an obvious error that I'm missing.
*EDIT: Forgot to mention that I'm using "setOption" to change the appearance.
You can't set echarts option directly. Need to use setOption for add data, see documentation.
Update
Your implementation does not work because Echarts not understand what need do with inputs. Getting value you in fact calling the getter (special built-in function) of input component. The Echarts does't know how to call getter, it's expecting just value.
With regard to the implementation I would have the following way.
Define function that read value for inputs.
Define function that update Echart's min/max.
Attach event listener to body element for listen inputs change event.
And then after receive the event call the update Echarts.
var myChart = echarts.init(document.getElementById('main'));
var hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a',
'7a', '8a', '9a','10a','11a',
'12p', '1p', '2p', '3p', '4p', '5p',
'6p', '7p', '8p', '9p', '10p', '11p'];
var days = ['Saturday', 'Friday', 'Thursday',
'Wednesday', 'Tuesday', 'Monday', 'Sunday'];
var data = [[0,0,5],[0,1,1],[0,2,0],[0,3,0],[0,4,0],[0,5,0],[0,6,0],[0,7,0],[0,8,0],[0,9,0],[0,10,0],[0,11,2],[0,12,4],[0,13,1],[0,14,1],[0,15,3],[0,16,4],[0,17,6],[0,18,4],[0,19,4],[0,20,3],[0,21,3],[0,22,2],[0,23,5],[1,0,7],[1,1,0],[1,2,0],[1,3,0],[1,4,0],[1,5,0],[1,6,0],[1,7,0],[1,8,0],[1,9,0],[1,10,5],[1,11,2],[1,12,2],[1,13,6],[1,14,9],[1,15,11],[1,16,6],[1,17,7],[1,18,8],[1,19,12],[1,20,5],[1,21,5],[1,22,7],[1,23,2],[2,0,1],[2,1,1],[2,2,0],[2,3,0],[2,4,0],[2,5,0],[2,6,0],[2,7,0],[2,8,0],[2,9,0],[2,10,3],[2,11,2],[2,12,1],[2,13,9],[2,14,8],[2,15,10],[2,16,6],[2,17,5],[2,18,5],[2,19,5],[2,20,7],[2,21,4],[2,22,2],[2,23,4],[3,0,7],[3,1,3],[3,2,0],[3,3,0],[3,4,0],[3,5,0],[3,6,0],[3,7,0],[3,8,1],[3,9,0],[3,10,5],[3,11,4],[3,12,7],[3,13,14],[3,14,13],[3,15,12],[3,16,9],[3,17,5],[3,18,5],[3,19,10],[3,20,6],[3,21,4],[3,22,4],[3,23,1],[4,0,1],[4,1,3],[4,2,0],[4,3,0],[4,4,0],[4,5,1],[4,6,0],[4,7,0],[4,8,0],[4,9,2],[4,10,4],[4,11,4],[4,12,2],[4,13,4],[4,14,4],[4,15,14],[4,16,12],[4,17,1],[4,18,8],[4,19,5],[4,20,3],[4,21,7],[4,22,3],[4,23,0],[5,0,2],[5,1,1],[5,2,0],[5,3,3],[5,4,0],[5,5,0],[5,6,0],[5,7,0],[5,8,2],[5,9,0],[5,10,4],[5,11,1],[5,12,5],[5,13,10],[5,14,5],[5,15,7],[5,16,11],[5,17,6],[5,18,0],[5,19,5],[5,20,3],[5,21,4],[5,22,2],[5,23,0],[6,0,1],[6,1,0],[6,2,0],[6,3,0],[6,4,0],[6,5,0],[6,6,0],[6,7,0],[6,8,0],[6,9,0],[6,10,1],[6,11,0],[6,12,2],[6,13,1],[6,14,3],[6,15,4],[6,16,0],[6,17,0],[6,18,0],[6,19,0],[6,20,1],[6,21,2],[6,22,2],[6,23,6]];
data = data.map(function (item) {
return [item[1], item[0], item[2] || '-'];
});
option = {
tooltip: {
position: 'top'
},
animation: false,
grid: {
height: '50%',
top: '10%'
},
xAxis: {
type: 'category',
data: hours,
splitArea: {
show: true
}
},
yAxis: {
type: 'category',
data: days,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 10,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '15%'
},
series: [{
name: 'Punch Card',
type: 'heatmap',
data: data,
label: {
show: true
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
function updateChart(values){
myChart.setOption({ visualMap: values })
};
document.body.addEventListener('change', (event) => {
var targets = document.querySelectorAll('.changeable');
var new_values = [...targets].map(target => {
var key_name = target.id.split('_')[0];
return { [key_name]: target.value };
});
var new_values = Object.assign(new_values[0], new_values[1]);
updateChart(new_values);
});
myChart.setOption(option);
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.7.0/echarts.min.js"></script>
<span>
<input type="number" class="changeable" id="min_limit" value= 1>
<input type="number" class="changeable" id="max_limit" value= 5>
</span>
<div id="main" style="width: 600px;height:400px;"></div>

Tooltip in C3 Charts does not refresh

We use the bar chart capabilities of c3 charts library in an environment where live data is floating in. This did lead to a problem where if a user hovers over a bar the bar itself did update but not the tooltip that was shown. Is there a way to update/reload the tooltip?
#Update 1:
Sorry for the delayed response. Basically we have an observer listening for data changes. This will trigger a method called reload which has the following lines (how the data looks like is shown in the comments):
chart.load({
xs: xs, // AmberViolation:"facilityId",BlueViolation:"facilityId",RedViolation:"facilityId"
columns: columns, // [["facilityId", "SUB-GTW"],["RedViolation", 0],["BlueViolation", 2],["AmberViolation", 0]]
unload: _.difference(drawnChartYCols, nextDrawColumns),
types: types, // AmberViolation:"bar",BlueViolation:"bar",RedViolation:"bar"
colors: colors,
done: function () {
if (columns.length && columns[0].length > 10) {
chart.zoom([0, 11]);
d3.select(element[0]).selectAll('svg > g').filter(function(d, i) { return i === 1 }).attr('display', null);
chart.resize({width: $scope.width, height: $scope.height});
d3.select(element[0]).select('.extent').attr('x', 0);
} else {
chart.unzoom();
d3.select(element[0]).selectAll('svg > g').filter(function(d, i) { return i === 1 }).attr('display', 'none');
chart.resize({width: $scope.width, height: $scope.height + 70});
}
}
});
chart.groups([groups]);// ["RedViolation","BlueViolation","AmberViolation"]
#Update 2:
You can even see that behavior on http://c3js.org/samples/chart_bar_stacked.html. Just hover over one of the bars while data is being updated and let the mouse stay there. The tooltip will not update. Only if you move the mouse again it will refresh.
#Update 3: Since this happens even on examples of c3 charts I created a bug on Github: https://github.com/c3js/c3/issues/2307
You don't provide any code snippet so it's hard to answer. I guess you don't update your data properly. According to the documentation:
If you call load API soon after/before unload, unload param of load
should be used. Otherwise chart will not be rendered properly because
of cancel of animation.
Something like this, to unload the old values, could solve your problem:
chart.load({
unload: true,
columns: ['data1', 100]
});
Check out this previous answer on SO.
My current solution is to hide and show the tooltip once the data gets updated in order to refresh it. Its ugly since the user can see the position of the tooltip jumping.
var currentIndex = null;
var chart = c3.generate({
data: {
columns: [
['data1', 20],
['data2', 30],
['data3', 40]
],
type: 'bar',
groups: [
['data1', 'data2', 'data3']
],
onmouseover: function(e) {
currentIndex = e.index;
},
onmouseout: function(e) {
currentIndex = null;
}
},
axis: {
y: {
show: true,
},
x: {
show: true,
type: ({
NUMERIC: 'indexed',
TEXT: 'category',
DATE: 'timeseries'
})['TEXT']
}
},
bar: {
width: {
ratio: 0.9,
max: 100
}
},
padding: {
top: 25,
right: 25
},
zoom: {enabled: false},
subchart: {
show: true,
axis: {
x: {
show: false
}
}
},
legend: {
show: false
},
line: {
connectNull: true
},
transition: {
duration: null
},
grid: {
y: {
show: true
}
}
});
setTimeout(function () {
chart.load({
columns: [['data1', 30],
['data2', 10],
['data3', 10]]
});
if (currentIndex != null) {
chart.tooltip.hide();
chart.tooltip.show({x: currentIndex});
}
}, 3000);
<link href="https://rawgit.com/masayuki0812/c3/master/c3.css" rel="stylesheet"/>
<script src="https://rawgit.com/masayuki0812/c3/master/c3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>
I added a hover listener where I get the currentHoverIndex and a onmouseout listener to set currentHoverIndex to null so we don't accidently show a tooltip if user doesn't hover on a bar at that time.

Noty example with velocity - velocity() undefined

I am trying to use this example from Noty's site: http://ned.im/noty/animations.bouncejs.html
I have installed noty.js and its CSS counter part. And I also have downloaded velocity.js and have it linked properly in my site. I know it is linked properly because I can use JQuery to select an element and perform a function on it that is provided by velocity:
$("table").velocity("fadeOut", {
duration: 3500
});
The example that is provided on the noty site though uses a call formatted like this:
new Noty({
text: 'NOTY - animating with velocity!',
animation: {
open: function () {
var n = this;
Velocity(n.barDom, {
left: 450,
scaleY: 2
}, {
duration: 0
});
Velocity(n.barDom, {
left: 0,
scaleY: 1
}, {
easing: [ 8, 8 ]
});
},
It calls it by using Velocity(... when I put this code into my page it errors and using the chrome F12 it says it is undefined. What am I missing from the example? The example for bounce works but I don't like the movement as much.
With the help of the developer we found an issue with the declaration on his site. Velocity doesn't work the way it is called in the question. It needs to be declared with $.Velocity with the current version of NOTY & Velocity
new Noty({
text: 'NOTY - animating with velocity!',
animation: {
open: function () {
var n = this;
$.Velocity(n.barDom, {
left: 450,
scaleY: 2
}, {
duration: 0
});
$.Velocity(n.barDom, {
left: 0,
scaleY: 1
}, {
easing: [ 8, 8 ]
});
},

JQDateRangeSlider change default values

I'm new in JQDateRangeSlider and I'm using it as a time slider: JSFiddle
I've used:
$("#slider").dateRangeSlider({defaultValues:{ min:new Date("2016-01-05T03:00:00Z"), max:new Date("2016-01-05T20:00:00Z") } });
to change the default values when the user presses the 'Change' button but it doesn't happen anything.
Can the default values can be changed using this instruction?
Please check the below code values are changing now on click of change button
I just provided a sample one you can update code as per your requirement
$('#btn3').on('click', function(e) {
$("#slider").dateRangeSlider({
bounds: {
"min": min3,
"max": max3
},
range: {
min: {
minutes: 1
}
},
defaultValues: {
min: min3,
max: max3
}
});
});
http://jsfiddle.net/LJrYf/154/

Is it possible to have the linear gauge pointer start from the center?

I have a case where I measure negative and positive speed using the same linear gauge. I was wondering if it's possible to have the pointer start with the center as a zero-point? Here's my code:
<script>
function createSpeedGauge() {
$("#speedBar").kendoLinearGauge({
pointer: {
value: 0,
color: "black",
start: 0
},
scale: {
majorUnit: 20,
minorUnit: 2,
min: -120,
max: 120,
vertical: true,
reverse: true,
ranges: [
{
from: -120,
to: -30,
color: "#ffc700"
},
{
from: 120,
to: 30,
color: "#ffc700"
}
]
}
});
}
$(document).ready(function() {
createSpeedGauge();
});
</script>
I've attached an image of how it's setup (the gauge in question on the right side). If this was setup the way I wanted, this gauge would've read -120 from this picture. (Right now, it reads "0" on the black bar, as this is the value set in my js.) Any suggestions?
Solved by setting the starting point to 0 and using SignalR to update the other end of the bar. (Initial starting point)

Categories

Resources