How to add toolbar to BokehJS plot? - javascript

My goal is to add a toolbar to a BokehJS plot. According to the plot tools documention this should be possible by doing (translating the Python example to Javascript):
plot.add_tools(new Bokeh.BoxZoomTool());
plot.add_tools(new Bokeh.ResetTool());
plot.toolbar_location = "right";
I have added these lines to the basic BokehJS example from the documentation, and they don't produce errors/warnings. However, the toolbar does not show up (properly) and the tools don't really seem to work.
I have prepared a minimal JSFiddle to demonstrate the problem: When using the rectangle select tool the plot moves around strangely, which uncovers an unstyled version of the toolbar rendered underneath the plot.
So the question is how can I get a properly working toolbar in BokehJS?

Add bk-root to the root element. <div id="plot" class="mybokehplot bk-root"></div>
Add corresponding css files (bokeh-0.12.0.min.css and bokeh-widgets-0.12.0.min.css).
JSFiddle here:
https://jsfiddle.net/blackmiaool/xzvgrqLj/
Snippet here:
// create some data and a ColumnDataSource
var x = Bokeh.LinAlg.linspace(-0.5, 20.5, 10);
var y = x.map(function(v) {
return v * 0.5 + 3.0;
});
var source = new Bokeh.ColumnDataSource({
data: {
x: x,
y: y
}
});
// create some ranges for the plot
var xdr = new Bokeh.Range1d({
start: -0.5,
end: 20.5
});
var ydr = Bokeh.Range1d(-0.5, 20.5);
// make the plot
var plot = new Bokeh.Plot({
title: "BokehJS Plot",
x_range: xdr,
y_range: ydr,
plot_width: 400,
plot_height: 400,
background_fill_color: "#F2F2F7"
});
// add axes to the plot
var xaxis = new Bokeh.LinearAxis({
axis_line_color: null
});
var yaxis = new Bokeh.LinearAxis({
axis_line_color: null
});
plot.add_layout(xaxis, "below");
plot.add_layout(yaxis, "left");
// add grids to the plot
var xgrid = new Bokeh.Grid({
ticker: xaxis.ticker,
dimension: 0
});
var ygrid = new Bokeh.Grid({
ticker: yaxis.ticker,
dimension: 1
});
plot.add_layout(xgrid);
plot.add_layout(ygrid);
// add a Line glyph
var line = new Bokeh.Line({
x: {
field: "x"
},
y: {
field: "y"
},
line_color: "#666699",
line_width: 2
});
plot.add_glyph(line, source);
// now add the tools
plot.add_tools(new Bokeh.BoxZoomTool());
plot.add_tools(new Bokeh.ResetTool());
plot.toolbar_location = "right";
// add the plot to a document and display it
var doc = new Bokeh.Document();
doc.add_root(plot);
var div = document.getElementById("plot");
Bokeh.embed.add_document_standalone(doc, div);
.mybokehplot {
position: relative;
width: 100%;
height: 100%;
border: 1px dashed #ccc;
}
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.0.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.0.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.0.min.css">
<div id="plot" class="mybokehplot bk-root"></div>
P.S. I found that the edition of bokeh's css files and js files must be same, or you would get lots of bugs.

Related

How to change marker labels in anychart horizontal gauge?

I am using anychart for creating a percentage horizontal gauge.
And i want to change the marker information to show what i want.
I found nothing on the documentation about it.
I'm using the javascript anychart playground (link below).
The final implementation is on Angular 5.
The original code :
https://playground.anychart.com/docs/v8/samples/GAUGE_Linear_04
(Optional) The typescript method :
createAnyChartsCustomGauges() {
let array = [];
this.listItem.forEach(item => {
// Gauge type and data
const gauge = anychart.gauges.linear();
gauge.layout('horizontal');
// Set the data
gauge.data([item.percent]); //number
// Create the custom scale bar
const scaleBarre = gauge.scaleBar(0);
// color and style setting
const colorScale = anychart.scales.ordinalColor().ranges([
{
from: 0,
to: 25,
color: ['#D81E05', '#EB7A02'],
},
{
from: 25,
to: 50,
color: ['#EB7A02', '#FFD700'],
},
{
from: 50,
to: 75,
color: ['#FFD700', '#CAD70b'],
},
{
from: 75,
to: 100,
color: ['#CAD70b', '#2AD62A'],
},
]);
scaleBarre.width('5%');
scaleBarre.offset('31.5%');
scaleBarre.colorScale(colorScale);
// Add a marker pointer
const marker = gauge.marker(0);
marker.offset('31.5%');
marker.type('triangle-up');
marker.zIndex(10);
marker.labels().format('{%data[0]}%');
// Add a scale
const scale = gauge.scale();
scale.minimum(0);
scale.maximum(100);
scale.maxTicksCount(10);
// Add an axis
const axis = gauge.axis();
axis.minorTicks(true);
axis.minorTicks().stroke('#cecece');
axis.width('1%');
axis.offset('29.5%');
axis.orientation('top');
// format axis labels
axis.labels().format('{%value}%');
// set paddings
gauge.padding([0, 20]);
array.push(gauge);
});
}
Actual :
{
Pointer 0
Value 63
}
Expected :
{
Value 63%
}
#gugateider was absolutely right! Also, if you don't want to use HTML styling for tooltip and disable tooltip title and separator, you can use the code below:
gauge.tooltip().title(false);
gauge.tooltip().separator(false);
gauge.tooltip().format("Value: {%value}%");
You should be using the format() methods of the Tooltip class.
There's a similar example on Any charts playground
// enable HTML for tooltips
chart.tooltip().useHtml(true);
// tooltip settings
var tooltip = gauge.tooltip();
tooltip.positionMode("point");
tooltip.format("Value: <b>${%value} %</b>");
Try that and see if works?

How to have source as rectangle for dragg

i have a requirement to have rectangle shape of fixed size and must be draggable to container, so that i can connect them.
i have searched alot but did not find any solution.
Question: single rectangle shape(fixed size) should be dragged to container
For full view Code pen:https://codepen.io/eabangalore/pen/LvzXxX
here is how:
Code Demo:
<!--
$Id: helloworld.html,v 1.6 2013/10/28 08:44:54 gaudenz Exp $
Copyright (c) 2006-2013, JGraph Ltd
Hello, World! example for mxGraph. This example demonstrates using
a DOM node to create a graph and adding vertices and edges.
-->
<html>
<head>
<title>Hello, World! example for mxGraph</title>
<!-- Sets the basepath for the library if not in same directory -->
<script type="text/javascript">
mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
function main(container)
{
// Checks if the browser is supported
if (!mxClient.isBrowserSupported())
{
// Displays an error message if the browser is not supported.
mxUtils.error('Browser is not supported!', 200, false);
}
else
{
// Disables the built-in context menu
mxEvent.disableContextMenu(container);
// Creates the graph inside the given container
var graph = new mxGraph(container);
// Enables rubberband selection
new mxRubberband(graph);
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
var parent = graph.getDefaultParent();
// Adds cells to the model in a single step
graph.getModel().beginUpdate();
try
{
var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
var e1 = graph.insertEdge(parent, null, '', v1, v2);
}
finally
{
// Updates the display
graph.getModel().endUpdate();
}
}
};
</script>
</head>
<!-- Page passes the container for the graph to the program -->
<body onload="main(document.getElementById('graphContainer'))">
<!-- Creates a container for the graph with a grid wallpaper -->
<div id="graphContainer"
style="position:relative;overflow:scroll;width:321px;height:241px;background:url('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/grid.gif');cursor:default;">
</div>
</body>
</html>
Please help me thanks in advance!!!!!
You can try something like
$(".rectagle").draggable({helper: 'clone'});
$("#canvas").droppable({
accept: ".rectagle",
drop: function(ev,ui){
$(ui.draggable).clone().appendTo(this);
}
});
#canvas {
height: 100px;
border: 1px solid lightgrey;
}
.rectagle {
display: inline-block;
height: 50px;
width: 50px;
border: 1px solid lightblue;
text-align: center;
background-color: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<div class="rectagle"></div>
<div id="canvas"></div>
function addToolbarItem(graph, toolbar, prototype, image)
{
// Function that is executed when the image is dropped on
// the graph. The cell argument points to the cell under
// the mousepointer if there is one.
var funct = function(graph, evt, cell)
{
graph.stopEditing(false);
var pt = graph.getPointForEvent(evt);
var vertex = graph.getModel().cloneCell(prototype);
vertex.geometry.x = pt.x;
vertex.geometry.y = pt.y;
graph.setSelectionCells(graph.importCells([vertex], 0, 0, cell));
}
// Creates the image which is used as the drag icon (preview)
var img = toolbar.addMode(null, image, funct);
mxUtils.makeDraggable(img, graph, funct);
}
try this example

How to define property type in SampledProperty in Cesium

I am using Cesiumjs to create a polygon which is moving around an area.
To show its movement I tried to create a sampledPropertyof PolygonHierarchy. Each sample is an array of Cartesian3 positions (three endpoints of my polygon at each time step).
I need to know the type of the property that I am using in sampledProperty as it is mentioned in Cesiumjs website: Cesiumjs.org/SampledProperty.
But I don't know how to define it and I couldn't find any explanation on the website on how to identify property type especially when each sample by itself is an array of properties.
The SampledProperty doesn't work here, since it attempts to interpolate smoothly between the points you've given it, and it doesn't know how to interpolate a polygon hierarchy.
So instead, you can use a TimeIntervalCollectionProperty. The difference here is that this property animates by steps, not interpolation, so the property does not need to know how to construct the intermediate values between control points.
I made a small demo, to show how this works with a polygon hierarchy. Click Run Code Snippet at the bottom, or copy-and-paste just the JavaScript into Sandcastle.
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationInstructionsInitiallyVisible: false
});
// Set up a limited range of time for this demo.
var time = Cesium.JulianDate.fromIso8601('2016-04-08T12:00:00Z');
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
viewer.clock.startTime = time;
viewer.clock.currentTime = time;
viewer.clock.stopTime = Cesium.JulianDate.addSeconds(time, 20, new Cesium.JulianDate());
viewer.clock.multiplier = 1;
viewer.timeline.updateFromClock();
viewer.timeline.zoomTo(time, viewer.clock.stopTime);
// Construct a TimeIntervalCollection showing the changes to the hierarchy over time.
var hierarchy = new Cesium.TimeIntervalCollectionProperty();
for (var i = 0; i < 40; ++i) {
var nextTime = Cesium.JulianDate.addSeconds(time, 0.5, new Cesium.JulianDate());
// Inside the loop, per iteration we add one window of time for this polygon.
hierarchy.intervals.addInterval(new Cesium.TimeInterval({
start: time,
stop: nextTime,
isStartIncluded : true,
isStopIncluded : false,
data : Cesium.Cartesian3.fromDegreesArrayHeights([-108.0+i/4, 35.0, 100000,
-100.0+i/4, 35.0, 100000,
-100.0+i/4, 40.0, 100000,
-108.0+i/4, 40.0, 100000])
}));
time = nextTime;
}
// Create the polygon, using the animated hierarchy.
var orangePolygon = viewer.entities.add({
name : 'Orange polygon with time-varying position',
polygon : {
hierarchy : hierarchy,
extrudedHeight: 0,
perPositionHeight : true,
material : Cesium.Color.ORANGE.withAlpha(0.5),
outline : true,
outlineColor : Cesium.Color.WHITE
}
});
viewer.zoomTo(viewer.entities);
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.19/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.19/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>

Remove transitions in scatter plot in NVD3

I have created a scatter chart in NVD3.js with dynamic data, but I cannot manage to prevent points from moving across the screen when the data changes (see 'demo snippet' at the end of this question). I would like these points to appear and disappear instantaneously, without any movement at all. Is this possible?
What I have tried
Played around with chart's settings:
chart.duration(0): no effect (from How to remove NVD3 chart resize/update delay)
chart.duration(-1): idem
chart.transitionDuration(0): shown in examples on nvd3.org but found out that function no longer exists (see: transitionDuration function does not exist in nvd3.js).
chartElement.transition().duration(0): no effect
Simply reinitialize chart everytime the data changes (not elegant, I know). This did not work because the chart also animates when it initializes.
Even uglier: disable all D3 animations as explained in Disabling all D3 animations (for testing), but also no success.
I have found out that someone else had a similar problem with NVD3's pie chart (https://github.com/novus/nvd3/issues/1474). It turned out that duration is not even used anywhere in the pie chart model. This does not seem to apply to the scatter chart (see https://github.com/novus/nvd3/blob/master/src/models/scatterChart.js#L96-L101, line 96 until 101):
chart.update = function() {
if (duration === 0)
container.call(chart);
else
container.transition().duration(duration).call(chart);
};
More details
I am using:
D3.js v3.4.11
NVD3.js v1.8.2
In case that this turns out the be a bug then I will try to write and commit a bug fix. Nevertheless, it would be nice to have a quick workaround.
Demo snippet
Run the snippet and move the slider to see the problem.
var chart;
var dataset; // All data points
var subset; // Datapoints that are close to
function randomPoint() {
return {
x: Math.random(),
y: Math.random(),
time: Math.random()
}
}
// Calculate the subset
function updateSubset(time) {
var upperBound = time + 0.1;
var lowerBound = time - 0.1;
subset[0].values = dataset[0].values.filter(function(d) {
return lowerBound < d.time && d.time < upperBound;
});
}
subset = [{
key: "Foobar",
values: []
}];
for (var i = 0; i < 100; i++) {
subset[0].values.push(randomPoint());
}
// Make a deep copy of the full dataset
dataset = jQuery.extend(true, {}, subset);
chart = nv.models.scatterChart()
.forceX([0, 1])
.forceY([0, 1])
.pointRange([150, 150])
.duration(0); // This doesn't seem to work?
updateSubset(0.5);
d3.select("#chart svg")
.datum(subset)
.call(chart);
// Recalculate subset and update chart when the slider is changed
$("#time").on("input", function() {
var time = Number($("#time").val());
updateSubset(time);
chart.update();
});
#time {
width: 100%;
}
#chart {
width: 100%;
height: 400px;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
Time control:
</div>
<div>
<input id="time" type="range" min="0" max="1" value="0.5" step="0.01" />
</div>
<div>
Points around that time:
</div>
<div id="chart">
<svg></svg>
</div>

kinetic-v3.8.2.js breaks kinetic-v3.6.0.js and kinetic-image-plugin-v1.0.1.js, how to fix?

I'm trying to make a kinetic canvas where I can add pictures from another source dynamically and I wanted a grid in the background so I used the kinetic.rect from kinetic v3.8.2.
The images needs to be draggable, from kinetic v.3.6.0, but if I set draggable when having v3.8.2 active it breaks.
"config is undefined" according to FireBug.
"img.kinetic.draggable is not a method" says FireBug.
Is there a fix for this?
Can you post a small example? There have been changes to the Kinetic API. Here is a draggable image with 3.8.2:
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='js/kinetic/kinetic-v3.8.2.js'></script>
<script type='text/javascript'>
window.onload = function () {
var stage = new Kinetic.Stage('container', 400, 300);
var layer = new Kinetic.Layer({
name: 'someLayer'
});
var logo = new Image();
logo.onload = function() {
var myImage = new Kinetic.Image({
x: stage.width / 2 - (logo.width / 2)
, y: stage.height - logo.height - 5
, image: logo
, width: logo.width
, height: logo.height
});
myImage.draggable(true)
layer.add(myImage);
layer.draw();
}
logo.src = "\./resources/images/ccs_logo.png";
stage.add(layer)
}
</script>
</head>
<body onmousedown="return false;" bgcolor=#000000>
<div id="container">
</div>
</body>
</html>
Most notably, configs were recently introduced for class instantiation. A Kinetic rectangle used to be defined like so:
var rect = new Kinetic.Rectangle(function () {
//do drawing stuff here
});
But now it is defined with a config (an object literal):
var rect = new Kinetic.Rectangle({
x: 0,
y: 0,
height: 20,
width: 20
});
You can see examples in the docs; also check out the updated KineticJS Tutorials.

Categories

Resources