Display a value when modifying a control using dat.GUI - dat.gui

Can anybody help me what I am showing in the image?
[1]: http://www.romualdorivera.com/three.js/dat.GUI_img_01.jpg
Here is my code:
var gui = new dat.GUI();
parameters = { x: 1, area: 1,}
gui.add(parameters, 'x', 1,400).name("Scale XY (in)").onChange();
gui.add(parameters, "area", value).name("Surface area=").onChange( x = x * 2);

If you have a plane on the XZ-plane (1 x 1):
var planeGeom = new THREE.PlaneGeometry(1, 1);
planeGeom.rotateX(-Math.PI / 2);
var plane = new THREE.Mesh(planeGeom, new THREE.MeshStandardMaterial({
color: "green"
}));
scene.add(plane);
then you can create an instance of dat.GUI and set its controllers like this:
parameters = {
x: 1,
area: 1,
}
var gui = new dat.GUI();
gui.add(parameters, 'x', 1, 400).name("Scale XY (in)").onChange(
function(value) {
plane.scale.set(value, 1, value);
parameters.area = value * value; // update the value of parameters.area
}
);
gui.add(parameters, "area", 1).name("Surface area=").listen(); // listen for updating of the value
It's based on the example of dat.GUI
jsfiddle example.

Related

How to subclass Polygon in Leaflet?

I am trying to create a Hex class for Leaflet where the center and side length should be in screen units (pixels) as opposed to lat/lng to obtain an effect like this over the map.
Code is here:
L.Hex = L.Polygon.extend({
initialize: function (args) {
console.log('arguments', JSON.stringify(arguments));
console.log('arguments[0]', JSON.stringify(arguments[0]));
// options = options || {};
this.center = args[0];
this.size = args[1];
this.options = args[2] || {};
L.Polygon.prototype.initialize.call(this, [], this.options);
},
points: function(center, size, map){
var latlngs = [0, 1, 2, 3, 4, 5, 6]
.map(p => this.hexCorner(center, size, p))
.map(p => map.layerPointToLatLng(p));
return latlngs;
},
hexCorner: function(center, size, i){
var angle_deg = 60 * i - 30;
var angle_rad = Math.PI / 180 * angle_deg;
return [center[0] + size * Math.cos(angle_rad),
center[1] + size * Math.sin(angle_rad)]
},
})
L.hex = function(){ return new L.Hex(arguments) }
Since the coordinates are in user space I think can only calculate them after adding to the map - but that's what fails. If add the points like this:
var h = L.hex([100, 100], 30);
var points = h.points([100, 100], 30, e.map);
h.setLatLngs(points);
h.addTo(map);
things work ok but my best attempt at onAdd which is this:
onAdd: function (map) {
var points = this.points(this.center, this.size, map);
this.setLatLngs(points);
map.addLayer(this);
},
with message TypeError: t._path is undefined
So the question is: where is the problem and how should I do it otherwise?
Change this.setLatLngs(points) to this._setLatLngs(points);.
With setLatLngs() the function this.redraw(); is called and this needs the map variable, which is applied with map.addLayer(this)

Grid line only on data point for scratter points

I need to draw x & y intercepts for all data points in a scratter chart. I went through major and minor grid lines. But it could not be my perfect solution.
Like the image below:
The sample image with x and y intercepts only on data points
You can use the render function of the chart to draw the horizontal and vertical lines on the chart surface. In the following demo, I name the x and y axes so that in the render function I can use the getAxis() method along with slot and range. See DOCS.
DEMO
var data = [[0.67, 5.4], [2.2, 2], [3.1, 3]];
$("#chart").kendoChart({
series: [{
type: "scatter",
data: data,
markers: {size: 16},
}],
yAxis: { name: "value", majorGridLines: {visible: false } },
xAxis: { name: "category", majorGridLines: {visible: false } },
render: function(e){
var chart = e.sender;
var yAxis = chart.getAxis("value");
var xAxis = chart.getAxis("category");
//iterate each point on the chart
for (var i=0; i<data.length; i++){
//vertical line
var valRange = yAxis.range();
var valSlot = yAxis.slot(valRange.min, valRange.max);
var point = data[i];
var catSlot = xAxis.slot(point[0]);
var path = new kendo.drawing.Path({
stroke: {color: "#B3BDBD", width: 1}
}).moveTo(catSlot.origin.x + catSlot.size.width/2, valSlot.origin.y)
.lineTo(catSlot.origin.x + catSlot.size.width/2, valSlot.bottomRight().y);
chart.surface.draw(path);
//horizontal line
var ySlot = yAxis.slot(point[1]);
var xRange = xAxis.range();
var xSlot = xAxis.slot(xRange.min, xRange.max);
var pathH = new kendo.drawing.Path({
stroke: {color: "#B3BDBD", width: 1}
}).moveTo(xSlot.origin.x, ySlot.origin.y + ySlot.size.width/2)
.lineTo(xSlot.bottomRight().x, ySlot.origin.y + ySlot.size.width/2);
chart.surface.draw(pathH);
}
}
});

How do I leave the clicked point highlighted in dygraphs?

I am using the selected shapes to draw a larger diamond shape on my graph. When a user clicks a point. I display the data in another div, but I want to leave the clicked point highlighted. In other words, I want to 'toggle' data behind the points on and off and the clicked points need to show if they are included in the dataset. I believe I have seen this somewhere but I cannot find it. Is there a 'standard' way of leaving a clicked point in the 'highlight' state when you mouse away after clicking?
Here is my code. The pointClickCallback is getting the data through ajax and displaying it in another div. That part works. I just want to leave the point highlighted so I know which points I have clicked on.
I also need the point to revert back to normal when I click a second time. This is a toggle that allows me to select and unselect points.
EDIT: I found the interaction model example but when I add it to my code I lose my pointClickCallback functionality. I saw the call to captureCanvas and the interaction model structure.
var g = new Dygraph(document.getElementById('rothmangraph'), lines, {
//showRangeSelector: true,
title: "Personal Wellness Index (PWI)",
labels: ['Date', 'Index'],
color: ['#006699'],
valueRange: [0, 101],
axisLabelFontSize: 12,
drawPoints: true,
gridLineColor: "#aaaaaa",
includeZero: true,
strokeWidth: 2,
rightGap: 20,
pointSize: 4,
highlightCircleSize: 8,
series : {
Index: {
drawHighlightPointCallback : Dygraph.Circles.DIAMOND
},
},
axes: {
y: {
pixelsPerLabel: 20,
},
x: {
valueFormatter: function(ms) {
return ' ' + strftime('%m/%d/%Y %r',new Date(ms)) + ' ';
},
axisLabelWidth: 60,
axisLabelFormatter: function(d, gran) {
return strftime('%m/%d %I:%M %p',new Date(d.getTime())) ;
}
}
},
underlayCallback: function (canvas, area, g) {
var warning = g.toDomCoords(0,41);
var critical = g.toDomCoords(0,66);
// set background color
canvas.fillStyle = graphCol;
canvas.fillRect(area.x, area.y, area.w, area.h);
// critical threshold line
canvas.fillStyle = "#cc0000";
canvas.fillRect(area.x,warning[1],area.w,2);
// warning threshold line
canvas.fillStyle = "#cccc00";
canvas.fillRect(area.x,critical[1],area.w,2);
},
pointClickCallback: function(e,point) {
var idx = point.idx;
var line = lines[idx];
var sqltime = strftime('%Y-%m-%d %H:%M:%S',new Date(line[0]));
var dispdate = strftime('%m/%d %r',new Date(line[0]));
_secureAjax({
url: '/ajax/getDataPoint',
data: {'patient_id': pid, "rdate": sqltime},
success: function (result) {
// parse and add row to table if not exists.
var data = JSON.parse(result);
var aid = data['id'];
var indexCol = "#a9cced"
if (line[1] <= 65) indexCol = "#ede1b7";
if (line[1] <= 40) indexCol = "#e5bfcc";
var headerinfo = '<th class="'+aid+'"><span class="showindex" style="background-color:'+indexCol+'">'+line[1]+'</span></th>';
var fixdate = dispdate.replace(' ','<br>');
var headerdate = '<th class="'+aid+'">'+fixdate+'</th>';
// skip if already exists
var found = false;
var whichone = false;
$('#headerdate tr th').each(function(idx, item) {
if (fixdate == $(this).html()) {
found = true;
whichone = idx;
}
});
if (!found) {
$.each(data, function (idx, item) {
$('#' + idx).append('<td class="'+aid+'" style="width:70px">' + item + '</td>');
});
$('#headerdate tr').append(headerdate);
$('#headerinfo tr').append(headerinfo);
} else {
$('tr').each(function() {
$('.'+aid).remove();
});
}
}
});
}
});
}

How to add a style role column to a google charts aggregated datatable

I have a datatable created from database data that gets aggregated by google.visualization.data.group, then fed into a columnChart.
By default, the resulting chart's bars are all the same color but i would like to make the bars different colors (by iterating through the datatable and assigning a different color to each row in the datable).For now, i'll just try to assign the colour 'gold' to each bar, for simplicity.
This is the documentation for a columnChart and is the documentation for style roles.
I don't think my code can be far wrong:
var groupedCategoryData = new google.visualization.data.group(
stacked01Data, // arg 1 is the array of input data
[{ // arg 2 is the key (An array of numbers/objects being columns to group by)
column: 0, type: 'string'
}],
[{ 'column': 1, 'aggregation': google.visualization.data.avg, 'type': 'number' }]
);//group. col 1 = score
//*****************
groupedCategoryData.addColumn({ type: 'string', role: 'style' });
for (var i = 0; i < groupedCategoryData.length; i++) {
groupedCategoryData[i][2] = 'color: gold';
}//for
//*****************
var stacked01_options = {
width: 500,
height: 300
};//options
var stacked01 = new google.visualization.ColumnChart(document.getElementById('stackedChart01_div'));
stacked01.draw(groupedCategoryData, stacked01_options);
The result is a chart whose bars are all default blue. I admit this is my first foray into javascript. any help would be appreciated.
Yep, that did it. thanks WhiteHat. working code:
//include the bar color data
var colorsGreen = [
[0, 1, '#6AB293'],
[1, 2, '#449371'],
[2, 3, '#277553'],
[3, 4, '#115639'],
[4, 5, '#043822']
];
groupedCategoryData.addColumn('string', 'barColor');
var groupedCategoryDataView = new google.visualization.DataView(groupedCategoryData);
groupedCategoryDataView.setColumns([0, 1, {
calc: function (dt, row) {
var rowValue = dt.getValue(row, 1);
var color;
colorsGreen.forEach(function (range, index) {
if ((rowValue >= range[0]) && ((rowValue < range[1]) || (range[1] === null))) {
color = range[2];
}
});
return color;
},
role: 'style',
type: 'string'
}]);
var stacked01_options = {
width: 500,
height: 300
};//options
var stacked01 = new google.visualization.ColumnChart(document.getElementById('stackedChart01_div'));
stacked01.draw(groupedCategoryDataView, stacked01_options);
}

Add a vertical line marker to Google Visualization's LineChart that moves when mouse move?

Is it possible to display a vertical Line marker showing the current x-axis value on LineChart, and moving when mouse moves ?
Thanks in advance.
While this was difficult before, a recent update to the API makes it much easier! You need to use a mouseover event handler to get the mouse coordinates and the new ChartLayoutInterface to translate the coordinates into chart values. Here's some example code:
[edit - fixed cross-browser compatibility issue]
*[edit - updated to get the value of points near the annotation line]*
function drawChart() {
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
// add an "annotation" role column to the domain column
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn('number', 'y');
// add 100 rows of pseudorandom data
var y = 50;
for (var i = 0; i < 100; i++) {
y += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
data.addRow([i, null, y]);
}
// add a blank row to the end of the DataTable to hold the annotations
data.addRow([null, null, null]);
// get the index of the row used for the annotations
var annotationRowIndex = data.getNumberOfRows() - 1;
var options = {
annotation: {
1: {
// set the style of the domain column annotations to "line"
style: 'line'
}
},
height: 400,
width: 600
};
// create the chart
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
// create 'ready' event listener to add mousemove event listener to the chart
var runOnce = google.visualization.events.addListener(chart, 'ready', function () {
google.visualization.events.removeListener(runOnce);
// create mousemove event listener in the chart's container
// I use jQuery, but you can use whatever works best for you
$('#chart_div').mousemove(function (e) {
var xPos = e.pageX - container.offsetLeft;
var yPos = e.pageY - container.offsetTop;
var cli = chart.getChartLayoutInterface();
var xBounds = cli.getBoundingBox('hAxis#0#gridline');
var yBounds = cli.getBoundingBox('vAxis#0#gridline');
// is the mouse inside the chart area?
if (
(xPos >= xBounds.left || xPos <= xBounds.left + xBounds.width) &&
(yPos >= yBounds.top || yPos <= yBounds.top + yBounds.height)
) {
// if so, draw the vertical line here
// get the x-axis value at these coordinates
var xVal = cli.getHAxisValue(xPos);
// set the x-axis value of the annotation
data.setValue(annotationRowIndex, 0, xVal);
// set the value to display on the line, this could be any value you want
data.setValue(annotationRowIndex, 1, xVal.toFixed(2));
// get the data value (if any) at the line
// truncating xVal to one decimal place,
// since it is unlikely to find an annotation like that aligns precisely with the data
var rows = data.getFilteredRows([{column: 0, value: parseFloat(xVal.toFixed(1))}]);
if (rows.length) {
var value = data.getValue(rows[0], 2);
// do something with value
}
// draw the chart with the new annotation
chart.draw(data, options);
}
});
});
// draw the chart
chart.draw(data, options);
}
See it working here: http://jsfiddle.net/asgallant/tVCv9/12