Multiple views/renders of the same kineticjs model - html5-canvas

I am building a graph utility that displays a rather large graph containing a lot of data.
One of the things I would like to be able to support is having multiple views of the data simultaneously in different panels of my application.
I've drawn a picture to try and demonstrate what i mean. Suppose i've built the gradiented image in the background using kinetic.
I'd like to be able to grab show the part outlined in red and the part outlined in green simultaneously, without having to rebuild the entire image.
var stage1 = new Kinetic.Stage({
container: 'container1',
width: somewidth,
height: someheight
});
var stage2 = new Kinetic.Stage({
container: 'container1',
width: someotherwidth,
height: someotherheight
});
var Layer1 = new Kinetic.Layer({
y: someY,
scale: someScale
});
// add stuff to first layer here...
var Layer2 = new Kinetic.Layer({
y: otherY,
scale: otherScale
});
// add other stuff to second layer here...
stage1.add(mapLayer);
stage1.add(topLayer);
stage2.add(mapLayer);
stage2.add(topLayer);
at the point at which I've added my layers to stage1, everything is fine, but as soon as i try to add them to stage2 as well, it breaks down. I'm sifting through the source but I cant see anything forcing data to be unique to a stage. Is this possible? Or do i have to duplicate all of my shapes?

Adding a node into multiple parents is not possible by KineticJS design. Each Layer has <canvas> element. As I know it is not possible to insert a DOM element into document twice.

Related

Can I set different type of loading animation in echarts

Currently I am calling an API to populate data in the bar chart made using echarts, I used the following code.
var mychart = echarts.init(document.getElementById("test"));
mychart.showLoading();
Once the data comes then I hide the loading, but in echarts I am getting only the circular shape loading option, can I use vertical bars for showing loading animation in echarts.
Echarts has no another loading spinner but you can make own or take any spinner lib (for example) and place above. Of course you can use the custom series or graphic and draw something but is not quite right spent time because it's loader and its role just to show that chart is not dead and will continue action soon to prevent user leaving.
Try the DOC
https://echarts.apache.org/en/api.html#echartsInstance.showLoading
default: {
text: 'loading',color: '#c23531',
textColor: '#000',
maskColor: 'rgba(255, 255, 255, 0.8)',
zlevel: 0,
// Font size. Available since `v4.8.0`.
fontSize: 12,
// Show an animated "spinner" or not. Available since v4.8.0`.
showSpinner: true,
// Radius of the "spinner". Available since `v4.8.0`.
spinnerRadius: 10,
// Line width of the "spinner". Available since `v4.8.0`.
lineWidth: 5
}

Plotly.js, show tooltips outside of chart container

I need to implement a plotly.js chart on a page with a very restricted width. As a result, a tooltip is partially cut. Is it possible to cause tooltip not to be limited by plotly.js container size?
My code example at codepen: https://codepen.io/anatoly314/pen/gOavXzZ?editors=1111
//my single trace defined as following but it's better to see example at codepen
const yValue1 = [1000];
const trace1 = {
x: [1],
y: yValue1,
name: `Model 1`,
text: yValue1.map(value => Math.abs(value)),
type: 'bar',
textposition: 'outside'
};
It is, by design, not possible for any part of the chart to overflow its container.
I would say it is wrong to say that by design this is not possible! It is a bit hacky, but when you add the following lines, it shows the label outside of svg:
svg.main-svg,svg.main-svg *
{
overflow:visible !important;
}
The answer given by rokdd works. However the css selector should be more specific, otherwise it's natural that you will introduce subtle bugs (particularly if you need to scroll the content where the plotly chart is contained).
If we look at the DOM tree constructed by Plotly, we find that the tooltips are created inside the <g class="hoverlayer"></g> element (which is a direct child of one of the three <svg class="main-svg"></svg>). So that parent (that svg.main-svg element) is only one that needs to affected.
The ideal css selector in this case would be the :has selector. However it's still not supported (as of 2022): https://css-tricks.com/the-css-has-selector/
So the next simplest thing is to use a little bit of javascript right after we call Plotly.newPlot:
// get the correct svg element
var mainSvgEl = document.querySelector('#positive g.hoverlayer').parentElement;
mainSvgEl.style['overflow'] = 'visible';
Or in a more generic way (works for any chart):
Array.from(document.querySelectorAll('g.hoverlayer')).forEach(hoverEl => {
let mainSvgEl = hoverEl.parentElement;
mainSvgEl.style['overflow'] = 'visible';
});

Handling large data set(100000) on Google Map using angular2

I am using google map in my angular2 app. I have also used MarkerCluster as below.
for (let marker of this._markers) {
let lat = +marker.latitude;
let long = +marker.longitude;
let markerobj = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
title: marker.name,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 6,
fillOpacity: 0.8,
fillColor: '#5A7793',
strokeColor: '#FFFFFF',
strokeWeight: 2,
},
map: this.map,
visible: true,
});
this.markerLayer.push(markerobj);
latlngbounds.extend(markerOnMap.getPosition());
markerList.push(markerOnMap);
}
let markerCluster = new MarkerClusterer(this.map, markerList, { imagePath: '../assets/images' });
I want to show around 100000 markers on google map. I am facing lot of performance issues when i tried to plot 100000 markers.
As per client requirement I can not use other map libraries. I need to stick with Google Map.
Do you have any suggestion which help me to improve the performance.
You don't plot 100,000 markers at once. What you need to do is reduce the amount of data you are displaying at a time. Only display individual markers when you are zoomed in so there are not so many markers in the view.
So what I would suggest is that load the markers from the server based on the bounds of your google map. So that would be the coordinates at the top left and bottom right.
So lets say you have 100,000 markers spread all over the world. At the world view it would be best not to show anything and ask the user to zoom in. Once you are at a lower zoom level use the bounds of the map to get markers from the server which lie inside those bounds. This should reduce the number of markers you have to display substantially. I don't know the coverage of your data but you can figure out what zoom levels work best for you.

How do I clone a Kinetic.node without its children?

I have a Kinetic.Stage and 2 layers: layer1 and layer2. I drag elements from layer1 to drop them in layer2, knowing that I made a design of a grid in layer2. I need to clone layer2 in its initial state, I mean without the shapes and images that have been drawn on it, just an empty grid.
document.getElementById('buttonAdd').addEventListener('click', function () {
var cloneLayer = layer2.clone({id: layer2.attrs.id + 1});
cloneLayer.draw();
stage.draw();
});
This code clones the whole thing: the layer and its children. What should I add, in order to remove children?
Things I tried and failed:
cloneLayer.destroyChildren();
var x = cloneLayer.getChildren();
x.hide();
"...just an empty grid". You can always create an empty grid with:
var newLayer=new Kinetic.Layer();
stage.add(newLayer);

Better way to draw a quadratic Curve in KineticJS?

I am writing an app in which I have to draw a lot of draggable quadratic curves.
I am using Kinetic.Shape for this (KineticJS 4.4.3).
Since the performance is not great I tried to analyze and optimize the code and found out that the drawFunc function is executed twice.
Look at the attached Demo Code.
var stage = new Kinetic.Stage({
container: 'kinetic',
width: 400,
height: 300
});
var curveLayer = new Kinetic.Layer();
var line = new Kinetic.Shape({
drawFunc: function (canvas) {
console.log("drawFunc executed");
var context = canvas.getContext();
context.beginPath();
context.moveTo(10, 10);
context.quadraticCurveTo(95, 100, 200, 10);
canvas.stroke(this);
},
strokeWidth: 10
});
curveLayer.add(line);
stage.add(curveLayer);
If you run the script there will be 2 times "drawFunc executed" in the console.
I do not understand why and I ask myself if there is any better way to do it.
The Link to the Fiddle:
http://jsfiddle.net/solitud/ZpU4J/9/
The Link to my project:
http://modulargrid.net/e/patches/view/92
KineticJS always creates a non-visible buffer canvas that it uses for drags, etc.
You are seeing drawFunc execute once for that buffer canvas and once for your visible canvas.
No way to eliminate that 2X drawing.
Looking at your project link, I'm guessing that the user creates connections into various receptors by visually dragging the plugs. No way to make that more efficient.
But, once any connection is complete, you can greatly speed redrawing of that connector by caching it to an image: connector1.toImage( ... );
Redrawing your image-cached "connectors" create much less performance penalty than redrawing quad-beziers.

Resources