I'm trying to work with Bokeh JS implementation i.e. trying to use the JS API of bokeh to display glyphs. I followed the instructions provided in bokeh documentation, but the page error's out. For example var plt = Bokeh. Plotting is undefined. What's going wrong?
I have included all the CSS/JS files as indicated in the documentation. Below is the code copied from the documentation - trying to get it working
Can someone with bokehjs experience help?
$(function() {
var plt = Bokeh.Plotting;
console.log(Bokeh.Plotting);
// set up some data
var M = 100;
var xx = [];
var yy = [];
var colors = [];
var radii = [];
for (var y = 0; y <= M; y += 4) {
for (var x = 0; x <= M; x += 4) {
xx.push(x);
yy.push(y);
colors.push(plt.color(50 + 2 * x, 30 + 2 * y, 150));
radii.push(Math.random() * 0.4 + 1.7)
}
}
// create a data source
var source = new Bokeh.ColumnDataSource({
data: {
x: xx,
y: yy,
radius: radii,
colors: colors
}
});
// make the plot and add some tools
var tools = "pan,crosshair,wheel_zoom,box_zoom,reset,save";
var p = plt.figure({
title: "Colorful Scatter",
tools: tools
});
// call the circle glyph method to add some circle glyphs
var circles = p.circle({
field: "x"
}, {
field: "y"
}, {
source: source,
radius: radii,
fill_color: colors,
fill_alpha: 0.6,
line_color: null
});
// add the plot to a document and display it
// var doc = new Bokeh.Document();
// doc.add_root(plt);
// var div = $("#plot");
// cosole.log(div);
// Bokeh.embed.add_document_standalone(doc, div);
plt.show(p);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.4.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.4.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.4.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.4.min.css">
<div id="plot">
</div>
Turns out, Bokeh has changed the JS APIs since 0.12.1 So the above code works for <=0.12.1 but for more recent releases the JS code breaks. The documentation has not changed though. Hoping the documentation is updated soon
Finally, I was able to get BokehJS 0.12.4 to work. The release notes of 0.12.2 contain a small note that the BokehJS API has been split into its own bundle. So when migrating from pre-0.12.2 to a recent version, it is necessary to add the following javascript
https://cdn.bokeh.org/bokeh/release/bokeh-api-0.12.4.min.js
in addition to the existing bokeh-0.12.4.min.js and bokeh-widgets-0.12.4.min.js. After adding this file to your example it works. Unfortunately, this information didn't make it into the official BokehJS documentation yet.
$(function() {
var plt = Bokeh.Plotting;
// set up some data
var M = 100;
var xx = [];
var yy = [];
var colors = [];
var radii = [];
for (var y = 0; y <= M; y += 4) {
for (var x = 0; x <= M; x += 4) {
xx.push(x);
yy.push(y);
colors.push(plt.color(50 + 2 * x, 30 + 2 * y, 150));
radii.push(Math.random() * 0.4 + 1.7)
}
}
// create a data source
var source = new Bokeh.ColumnDataSource({
data: {
x: xx,
y: yy,
radius: radii,
colors: colors
}
});
// make the plot and add some tools
var tools = "pan,crosshair,wheel_zoom,box_zoom,reset,save";
var p = plt.figure({
title: "Colorful Scatter",
tools: tools
});
// call the circle glyph method to add some circle glyphs
var circles = p.circle({
field: "x"
}, {
field: "y"
}, {
source: source,
radius: radii,
fill_color: colors,
fill_alpha: 0.6,
line_color: null
});
plt.show(p);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.4.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-api-0.12.4.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.4.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.4.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.4.min.css">
<div id="plot"></div>
Related
i am just getting started with plotly js. And, I am trying to use boxplot, but it is showing min, max, q1, q3 and median. But, I want to display only min,max and median on hover.
My code:
var y0 = [];
var y1 = [];
for (var i = 0; i < 50; i ++) {
y0[i] = Math.random();
y1[i] = Math.random() + 1;
}
var trace1 = {
y: y0,
type: 'box'
};
var data = [trace1];
Plotly.newPlot('myDiv', data);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
jsfiddle
I would like to display breaks in the x axis of the line chart and display them with a fixed width, like at the image below:
Found this nice article that describes the functionality:
https://www.arction.com/news/using-scale-breaks-data-visualization/
If I understand correctly, there is the possibility in the SDK to display these with scaleAreas or even better with ClipAreas.
But I could not find this possibility in the LightningChart JS framework.
As starting point I was able to generate breaks in data with a NaN value and added a Textbox.
So my questions are:
1. How to add breaks and fit to predefined width in xaxis
2. How to rotate the Textbox 90 degrees?
Help would be greatly appreciated.
Thanks in advance. :o)
// Extract required parts from LightningChartJS.
const {
lightningChart,
AxisTickStrategies,
DataPatterns,
emptyFill,
ColorHEX,
emptyLine,
UIElementBuilders,
UIBackgrounds,
UIOrigins,
UIDraggingModes,
SolidLine,
SolidFill
} = lcjs
// Create a XY Chart.
const dateOrigin = new Date(2020, 0, 1)
const chart = lightningChart().ChartXY({
defaultAxisXTickStrategy: AxisTickStrategies.DateTime(
dateOrigin
)
})
.setTitle('Demo')
chart.setPadding({ right: '1' })
// Add a progressive line series.
// Using the DataPatterns object to select the horizontalProgressive pattern for the line series.
const lineSeries = chart.addLineSeries({ dataPattern: DataPatterns.horizontalProgressive })
.setName('Demo')
// Generate some points using for each month
const dataFrequency = 10;
// Setup view nicely.
chart.getDefaultAxisY()
.setScrollStrategy(undefined)
.setInterval(-20, 120)
.setTitle('Demo y')
// Data for the plotting
const data = [];
for (let i = 0; i < 1500; i++) {
let index = i;
if (i === 500) {
index = NaN;
}
if (i > 500) {
index = i + 1000;
}
data.push({
x: index,
y: Math.floor(Math.random() * 100)
});
}
chart.addUIElement(
UIElementBuilders.TextBox
.setBackground(UIBackgrounds.Rectangle),
chart.uiScale
)
.setText('Break')
.setPosition({ x: 45, y: 50 })
.setOrigin(UIOrigins.Center)
.setDraggingMode(UIDraggingModes.notDraggable)
.setFont((font) => font
.setSize(40)
)
.setBackground(style => style
.setFillStyle(new SolidFill({ color: ColorHEX('#f00') }))
)
.setTextFillStyle((style) => style
.setColor(ColorHEX('#0f0'))
)
// Adding points to the series
lineSeries.add(data.map((point) => ({ x: point.x * dataFrequency, y: point.y })))
<script src="https://unpkg.com/#arction/lcjs#1.3.1/dist/lcjs.iife.js"></script>
LightningChart JS doesn't have support for scale breaks yet. It's something that will most likely be developed at some point but there is no timeline for it yet.
TextBox rotation is not yet possible for UITextBox, it's coming in a future release but not the next release.
I am rendering an Graph with CanvasJS.
It´s generated dynamically.
After I stop the generation (or after an specified time) I generate from that an image.
Now I want to load that image AND take the generation of the Graph. So... I am again generating the same data, but this time with the complete (mostly scaled) picture of the data. - This shall work as an fast Overview.
That´s how I am doing it basiclly: (the dynamic data)
<script type="text/javascript">
window.onload = function ()
{
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer",{
zoomEnabled:true,
title :{
text: "Live Random Data"
},
data: [{
type: "stackedColumn",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 100;
var dataLength = 500; // number of dataPoints visible at any point
var arr = [];
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
arr.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
var d= setInterval(function(){updateChart()}, updateInterval);
$("#test").click(function () {
console.log("baa");
clearInterval(d);
});
$("#show").click(function () {
console.log("baa");
dps=[];
dps.push(arr);
chart.render();
});
}
</script>
http://canvasjs.com/editor/?id=http://canvasjs.com/example/gallery/dynamic/realtime_line/
Now, if I am zooming or panning the "Live Data" or on the Image:
I want an synchronization between those two. If I am zooming or panning on the Image I only want to see an opaque rect and the dynamic data has to be really zoomed.
An sync. Example is here http://jsfiddle.net/canvasjs/m5jgk5sg/, but how do I do that with an Image?
Does anyone of you has an idea or how to make an workaround?
I am using SnapSVG library. I am trying to add a dynamically created SVG circle into a SVG group. A new circle is added every time I click a link (Add Composite). Then I try to push that newly created circle to an array and pass the array to the group (drag) function. I basically want to drag all the circles and rectangle as a group. But its not working. Here is my code ...
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="snap.svg-min.js"></script>
</head>
<body>
<svg id="svg"></svg>
<div id="addComp">Add Composite</div>
<script>
// JavaScript Document
(function() {
var s = Snap("#svg");
// Construct Composite
function composite(y, i) {
var CirArray = [];
$("svg g").remove();
$("svg rect").remove();
$("svg circle").remove();
var square = s.rect(30, 40, y, 40);
console.log("Square:" + y);
square.attr({
fill: 'lightblue',
stroke: 'lightblue',
//strokeOpacity: .3,
//strokeWidth: 10
});
CirArray.push(square);
var k = 0;
for (z = 1; z <= i; z++) {
k = k + 45;
console.log("Circle:" + k);
var mycircle = s.circle(k, 120, 20);
mycircle.attr({
fill: 'coral',
stroke: 'coral',
strokeOpacity: .3,
strokeWidth: 10
});
CirArray.push(mycircle);
} // For loop end
drag.apply(null, CirArray);
} // Construct Composite End
// Group
function drag(CirArray) {
var tableset = s.group(CirArray);
for (p = 0; p < CirArray.length; p++) {
console.log(CirArray[p])
}
console.log(CirArray.length)
// Drag
var move = function(dx, dy) {
this.attr({
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
});
}
var start = function() {
this.data('origTransform', this.transform().local);
}
var stop = function() {
console.log('finished dragging');
}
tableset.drag(move, start, stop);
} //Drag End
// Add Composite
var x = 0;
var clct = 0;
$("#addComp").click(function() {
x = x + 45;
clct = clct + 1;
composite(x, clct);
}); // Add Composite End
}()); // Iffe End
</script>
</body>
</html>
Visit this site and click on 'Add composite' link a couple of times to see it in action
Any help is very appreciated ....
Thanks
Basically adding the array on the .group(CirArray) does not seem to add all the array items into a group (Inspect the SVG output) the group tag is empty.
Instead adding them in the for-loop below. Made the following changes and it seems to work as expected and moving all squares and circles together.
var tableset = s.group();
for (p = 0; p < CirArray.length; p++) {
tableset.add(CirArray[p]);
console.log(CirArray[p])
}
In the drag function also calling it simply drag(cirArray) (as suggested by #Paul-lebeau ie. drag(CirArray);).
Forked Plunker
The second argument to the function.apply() method is supposed to be an array of parameters.
But you are passing in an array of Snap elements. So in your drag() function, the CirArray parameter is getting set to the first element of your original CirArray, not the whole array.
Either change the call to
drag.apply(null, [CirArray]);
or just call it normally
drag(CirArray);
I am trying to apply a simple clustering stategy to my OpenLayers v2.13 map, but it is not working.
Here is my code so far, it all loads correctly but the random points on the map do not cluster, they just overlap horribly...
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>OpenLayers 2.13.x Clustered Markers</title>
<script src="../OpenLayers.js"></script>
</head>
<body onload="run()" style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;">
<div id='map' style="width: 100%; height: 100%">
</div>
<script>
function run(){
// create the map
var map = new OpenLayers.Map("map");
// add a google maps layer to the map
var layer = new OpenLayers.Layer.WMS("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {
layers: "basic"
});
map.addLayers([layer]);
// set up cluster strategy and vector layer
var strategy = new OpenLayers.Strategy.Cluster({
distance: 15,
clustering: true
});
var markersLayer = new OpenLayers.Layer.Vector("Clustered markers", {strategies: [strategy]});
// create and add all markers randomly
var markers = [];
for (var i = 0; i < 700; i++) {
var r1 = Math.random();
var r2 = Math.random();
var r3 = Math.random();
var r4 = Math.random();
var px = r1 * 180 * ((r2 < 0.5) ? -1 : 1);
var py = r3 * 90 * ((r4 < 0.5) ? -1 : 1);
var p = new OpenLayers.Geometry.Point(px, py);
var clazz = (i % 10 === 0) ? 4 : Math.ceil(r4 * 3);
var f = new OpenLayers.Feature.Vector(p, {clazz: clazz});
markers.push(f);
}
markersLayer.addFeatures(markers);
// add markers layer to the map
map.addLayer(markersLayer);
map.zoomToMaxExtent();
}
</script>
</body>
</html>
Note: OpenLayers is locally on my machine and is version 2.13.1
I have looked at several examples, none have helped me solve this issue. I have looked at several stack overflow answers, the best of them was about marker clustering, but also didn't help.
I must be missing something obvious but I cant see what?
[UPDATE]
Taking advice from the answers below, here is the code snippet (from above) edited to run correctly, adding the markers after the layer has been added to the map and not including the clustering flag...
// set up cluster strategy and vector layer
var strategy = new OpenLayers.Strategy.Cluster({
distance: 15 // <-- removed clustering flag
});
var markersLayer = new OpenLayers.Layer.Vector("Clustered markers", {strategies: [strategy]});
// add markers layer to the map
map.addLayer(markersLayer); // <-- adding layer before adding features
// create and add all markers randomly
var markers = [];
for (var i = 0; i < 700; i++) {
var r1 = Math.random();
var r2 = Math.random();
var r3 = Math.random();
var r4 = Math.random();
var px = r1 * 180 * ((r2 < 0.5) ? -1 : 1);
var py = r3 * 90 * ((r4 < 0.5) ? -1 : 1);
var p = new OpenLayers.Geometry.Point(px, py);
var clazz = (i % 10 === 0) ? 4 : Math.ceil(r4 * 3);
var f = new OpenLayers.Feature.Vector(p, {clazz: clazz});
markers.push(f);
}
markersLayer.addFeatures(markers); // <-- now can add features
// zoom to extent
map.zoomToMaxExtent();
It looks like maybe a good practice to follow is to make sure that you add a layer to the map before adding/removing features to it.
I removed "clustering" from the cluster strategy options
// set up cluster strategy and vector layer
var strategy = new OpenLayers.Strategy.Cluster({
distance: 15
});
and then added the markers after I'd added the layer to the map
// add markers layer to the map
map.addLayer(markersLayer);
markersLayer.addFeatures(markers);
map.zoomToMaxExtent();
then all seemed to work.
Mailed similar to Angela to you internally.
Not sure why removing clustering has any affect, I think its true by default anyway.
As for the order of adding the points, I seem to remember reading something about the fact your points are replaced by the clusters so adding the layer to map after adding points to layer may mean that process doesn't happen. Or something. ;)
Cheers
Ian