I'm trying to integrate a map in Angular Material tabs. To be exact, a map in all the tabs. I'm using Datamaps for rendering the maps.
I made a pen with the demo I worked on, http://codepen.io/sgsvenkatesh/pen/yJbYOj
The code works exactly as expected when I wrap initialisation of map with setTimeout. (which I commented out in the above pen in line 128)
The code works perfectly fine when setTimeout is applied like shown below.
setTimeout(function () {
new Datamap({
element: elem[0].querySelector(".map"),
scope: 'usa',
projection: 'equirectangular',
height: 500,
fills: {
defaultFill: '#F5F5F5'
},
data: scope.dataset,
geographyConfig: {
highlightBorderColor: '#bada55',
popupTemplate: function (geography) {
return '<div class="hoverinfo">' + geography.properties.name + '</div>';
},
highlightBorderWidth: 2
}
}).labels({'customLabelText': scope.USData});
}, 1000);
In my opinion, the problem is because of Datamaps being rendered even before Angular Material rendering is complete. (probably, that is why the svg doesn't have any width/height)
Does Angular Material provide a callback after the rendering is complete? If not, how do we achieve any DOM manipulation, which is supposed to happen after material rendering.
Please comment if more information is needed.
Related
I have made a line chart using react-chartjs-2 with a plugin called chartjs-plugin-zoom. I want to display the zoom level in console when zooming the chart. However, the onZoom seems not being triggered or called when zooming as I can't see any updates in the console panel. Would like to ask whether my syntax for onZoom is wrong and how can I fix that?
online example
https://codesandbox.io/s/musing-frost-m6fuz?file=/src/App.js
This is because you putted the onZoom callback in the wrong place in the options object. You putted it at the root of the zoom plugin config while it has to be configured in the zoom part so in this namespace: options.plugins.zoom.zoom.onZoom
https://codesandbox.io/s/happy-forest-9mtii?file=/src/App.js
You have placed the onZoom in the wrong nested object.
If u place the onZoom function inside the plugins-zoom-zoom object it will work.
https://codesandbox.io/s/lively-river-zry93?file=/src/App.js:3038-3538
plugins: {
zoom: {
zoom: {
wheel: {
enabled: true
},
mode: "x",
onZoom: function ({ chart }) {
console.log(`I'm zooming!!!`);
},
// Function called once zooming is completed
onZoomComplete: function ({ chart }) {
console.log(`I was zoomed!!!`);
}
},
}
Is there a way to make combined map which could use "drill-down" behaviour for some areas and "select" behaviour for other ones areas?
I believe that what you are asking can be achieved also with some of the standard functionalities provided by jVectorMap. In my example below, all US regions other than Texas can be selected, whereby the normal multimap drill-down is performed just only for US-TX.
$(document).ready(function () {
new jvm.MultiMap({
container: $('#map'),
maxLevel: 1,
main: {
map: 'us_lcc',
regionsSelectable: true,
regionStyle: {
selected: {
fill: 'green'
}
},
onRegionClick: function(event, code) {
if(code == "US-TX") {
return false;
} else {
event.stopImmediatePropagation();
}
}
}
});
});
Explanation:
As the documentation says here, the main Map of the MultiMap object can be configured the same way as the "normal" Map.
Inside the multi-map onRegionClick handler, the region selection can be avoided by returning false, and the drilldown can be stopped by invoking stopImmediatePropagation(). I tested this snippet with jVectorMap version 2.0.2 but it should work also with the latest versions.
BTW, thanks to bjornd for the great jVectorMap.
There's no standart behaviour to reach this.
To handle this I had to modify MultiMap file. In addMap function you could add
hardcode check region code or add it to config and pass or deny drilling down.
I have inherited a project that is using Highcharts.
The previous dev used the .addSeries method to add all of the series to each chart that was being rendered. From what I've read of Highcharts, it seems like .addSeries is really for adding data dynamically.
The data that is being used to populate the charts are coming from an AJAX request. The old dev's approach was to get the data, render the chart, and then add a series using .addSeries. I was thinking that it might be better to update options.series and then pass the whole thing along to new Highcharts.Chart() for rendering, taking the .addSeries out of the equation.
However, since I'm new with Highcharts, I was hoping to get some feedback on what the better method would be.
You're on a good path, though your question suggests you may simply be looking for preference over a strict right/wrong answer.
From what I've seen, unless you have interactions on the page that would trigger a need to update your chart after it's been drawn, the benefit to using addSerie would be to add some visual flare. Using addSerie, your charts will visually draw themselves in front of the visitor - vs them already being drawn. (I believe HighCharts demo site has some good examples of this.)
I also recently inherited a HighCharts project and am generating a new Highcharts.Chart() using dynamic data by parsing the AJAXed data on the fly. The good news is that all of the charts still have nice visual flare (flare is important) since they don't draw until the AJAXed data is fully loaded. This snippet illustrates how I've been loading dynamic charts, parsing the JSON data on the fly:
$(function () {
var visitsChart;
$(document).ready( function() {
$.getJSON('/json-data-url', function(json){
var visitsChart = new Highcharts.Chart({
chart: {
renderTo: 'visitsContainer',
type: 'spline',
},
title: {
text: 'Test Widget'
},
series: [{
name: 'Speed',
data: [parseInt(json.visits)],
}],
...
});
});
});
});
I won't lie ... I had a few minutes of hair pulling when I got started but now I wish I had more time to work with Highcharts as it's quite fun once you get on a roll. Hope this helps.
I'm trying to draw a graph inside an infowindow, but flot is not executing—and is not throwing any errors. I read in the flot forum that often people have trouble with doing something like this because the placeholder element must be visible (that might be a red-herring here tho).
I'm able to get the following to produce the graph appropriately in a different element:
$.plot(
$("#placeholder"),
[ f_data[loc] ],
{
grid: { hoverable: true, clickable: true },
series: {
bars: { show: true },
clickable:true,
color:'#3FA9F5',
shadowSize: 0
},//series
xaxis: {
tickDecimals:0,
tickSize:1
}//xaxis
}
);//$.plot
But when I put the above into, or referenced from, the google.maps.event.addListener(), it does nothing (not even add the <canvas> elements).
I made sure to put it after infowindow.open(map,marker);, so that makes me think the placeholder element is visible. I also made sure #placeholder has substance/defined dimensions.
P.S. I tried what Mike Williamson reported as his eventual solution to Google Maps V3: Loading infowindow content via AJAX, but that didn't work either.
EDIT
Example of flot working outside of infowindow: index2.html
Example of flot not working inside of infowindow (addListener 'domready'): index3.html
Example of flot not working inside of infowindow (setTimeout): index4.html
The issue is that the content div has not been attached to the domain yet (so $("#placeholer") can't find it). You need to wait for the infowindow domready event to fire before running your code to plot the graph, something like this:
UPDATE: The code below works for me on a local copy (I did modify the css, but I don't think that was required).
google.maps.event.addListener(marker, 'click', (function(marker, locale, s, flot_data) {
return function() {
var fname = 'http://clients.frende.me/incognito/images/'+date+'_'+locale.toLowerCase().replace(/\s/g,'')+'.svg';
infowindow.setContent('<div id="gMaps_infowindow"><h3>'+locale+' ('+hour+':00): $'+s.total+'</h3><div id="flotIW" style="height:200px; width:350px;" name="'+locale+'"></div></div>');
google.maps.event.addListener(infowindow, 'domready', function() {(function(f_data,loc) {
$.plot(
$("#flotIW"),
[ f_data[loc] ],
{
grid: { hoverable: true, clickable: true },
series: {
bars: { show: true },
clickable:true,
color:'#3FA9F5',
shadowSize: 0
},//series
xaxis: {
tickDecimals:0,
tickSize:1
}//xaxis
}
);//$.plot
})(flot_data,locale)});
infowindow.open(map, marker);
//open_popUp(flot_data,locale);
//open_drawGraph(locale);
}//return
})(marker, locale, s, flot_data));//google.maps.event.addListener
(another option is to create the domain node directly, use that to render your graph, and pass that into the setContent call (which will take either a string or a DOM node).
Have you tried wrapping your $.plot in a setTimeout(function(){$.plot({stuff})}, 0) ?
Sometimes this helps give the browser time to finish drawing whatever elements it needs to before it executes.
You can find more information why this might be useful here: Why is setTimeout(fn, 0) sometimes useful?
I'm working on an implementation of a live-updating line graph using gRaphael which is a graphic extension of the Raphael SVG library.
I can't seem to find any examples of somebody doing this as a near-realtime updating project, which is fine. I'm assuming there's a way to call refresh on the graph with a new data set (without the need to re-initialize a whole new Raphael object each time!), but therein lies the problem:
There doesn't seem to be accurate documentation anywhere. I discovered this StackOverflow question: Graphael line chart which in turn led to this documentation project: https://github.com/kennyshen/g.raphael/tree/master/docs , but the results were cold. Using the examples provided, I ran into some errors:
the syntax r.g.linechart() used in the examples was no longer valid (where r is the Raphael object and I assume g is a gRaphael property within). Somewhere along the way somebody must have switched to properly extending the Raphael object so that r.linechart() worked.
The parameters passed into linechart() were incorrect, resulting in an undefined error again. If I passed in only the #x, #y, width, height, arrayX, arrayY parameters and dropped the chart labels, etc., I could render a plain line. But of course I need to be able to label my axes and provide a legend, etc.
Needless to say, a library without an API document isn't going to do anybody much good, but there are stalwarts out there who are willing to learn based strictly on reading the code itself. I'm not one of those. I would probably do OK with a well-commented example, preferably using live updates.
So I guess the questions are:
Does anybody know better documentation than the one I linked to?
Can someone point me to examples, documentation failing?
Can someone provide a proper itemization of the parameters that linechart() will accept?
Thanks!
For the record, here's how far I am so far:
var r = Raphael('line-chart');
// did NOT work -->
var linechart = r.g.linechart(
10,10,300,220,[1,2,3,4,5],[10,20,15,35,30],
{"colors":["#444"], "symbol":"s", axis:"0 0 1 1"}
);
// worked in a limited way, rendering a plain line with no visible labels/graph -->
var linechart = r.linechart(
10,10,300,220,[1,2,3,4,5],[10,20,15,35,30]
);
I am still trying to learn Raphael myself, but here are the primary resources I have been using: http://g.raphaeljs.com/reference.html and the same sans the "g."
here is a fiddle that pretty much pulls off an updating linechart with knockout/gRaphael, prob not the best solution, but its an idea: http://jsfiddle.net/kcar/mHG2q/
Just a note, I didn't start learning it until I combined reading with trial/error (with a lot of error), so play with the fiddle and see how things change.
but the basic code for it is like:
//constructor
var lines = r.linechart(10, 10, width, height, xVals, yVals, { nostroke: false, axis: "0 0 1 1", symbol: "circle", smooth: true })
.hoverColumn(function () { //this function sets the hover tag effect
this.tags = r.set();
for (var i = 0, ii = this.y.length; i < ii; i++) {
this.tags.push(r.tag(this.x, this.y[i], this.values[i], 160, 10).insertBefore(this).attr([{ fill: "#fff" }, { fill: this.symbols[i].attr("fill") }]));
}
}, function () {
this.tags && this.tags.remove();
});
lines.symbols.attr({ r: 3 }); //this adjusts size of the point symbols
There is a fork in GitHub that is working on the documentation and examples.
You will need to download the code and view it from you computer. It is a work in progress but it's more than you can find in the official g.Raphael page.
I also found this small post with some examples.