I would like to update an interactive scatter plot in dimple using a dropdown menu, however I am having some issues with this task. An example of my code is below:
<select name="xAX" id="xAX">
<option value ="Distance">Distance</option>
<option value ="Redshift">Redshift</option>
</select>
<div id ="chartContainer">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
<script type="text/javascript">
var dropdown = d3.select("#xAX")
var xAX2 = dropdown.node().options[dropdown.node().selectedIndex].value;
d3.csv("tabula.csv", function(data) {
dataset = data.map(function(data) { return [
data["Object"],
+data["Redshift"],
+data["Distance"],
+data["Scale"],
data["Type"],
+data["IRAS12um"] ]; });
},
var svg = dimple.newSvg("#chartContainer", 900, 900);
var myChart = new dimple.chart(svg, data);
myChart.setBounds(100, 180, 730, 550)
myChart.showGridlines = true;
var x = myChart.addMeasureAxis("x", ["Redshift","Distance"]);
x.addOrderRule(["Redshift","Distance"]);
myChart.addMeasureAxis("y", "Redshift");
myChart.addMeasureAxis("z", "IRAS12um");
myChart.addSeries("Type", dimple.plot.bubble);
myChart.addLegend(70, 10, 610, 80, "right");
myChart.draw();
d3.select("#xAX").on("change", change)
function change() {
this.options[this.selectedIndex].value
}
myChart.draw(1000);
});
The "tabula.csv" table has X headers with Y elements per header. I would like that the x- and/or y-axis would have any possible option of the X header.
I have tried this example but it did not really make what I would like. Any help on the code or other example would be very helpful.
----- UPDATE ----
I updated the code and I can change the plot from a dropdown menu. However, the new graph is plotted on top of the old one. How the old plot can be removed?
<h2>X-Axis</h>
<select id="xAX" name="xAX">
<option value ="Distance" selected>Distance</option>
<option value ="Redshift">Redshift</option>
</select>
<div id="chartContainer">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer", 900, 900);
var dropdown = d3.select("#xAX")
var change = function() {
var source = dropdown.node().options[dropdown.node().selectedIndex].value;
d3.csv("tabula.csv", function(data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(100, 180, 730, 550)
var x = myChart.addMeasureAxis("x", source);
myChart.addMeasureAxis("y", "Redshift");
myChart.addMeasureAxis("z", "IRAS12um");
myChart.addSeries("Type", dimple.plot.bubble);
myChart.addLegend(70, 10, 610, 80, "right");
myChart.draw();
});
}
dropdown.on("change", change);
change();
</script>
try something like this:
<h2>X-Axis</h>
<select id="xAX" name="xAX">
<option value ="Distance" selected>Distance</option>
<option value ="Redshift">Redshift</option>
</select>
<div id="chartContainer">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer", 900, 900);
var dropdown = d3.select("#xAX")
var xAxis;
var myChart;
var draw = function() {
var source = dropdown.node().options[dropdown.node().selectedIndex].value;
d3.csv("tabula.csv", function(data) {
myChart = new dimple.chart(svg, data);
myChart.setBounds(100, 180, 730, 550)
xAxis = myChart.addMeasureAxis("x", source);
myChart.addMeasureAxis("y", "Redshift");
myChart.addMeasureAxis("z", "IRAS12um");
myChart.addSeries("Type", dimple.plot.bubble);
myChart.addLegend(70, 10, 610, 80, "right");
myChart.draw();
});
}
var change = function() {
var source = dropdown.node().options[dropdown.node().selectedIndex].value;
xAxis.categoryFields = source;
myChart.draw();
};
dropdown.on("change", change);
draw();
</script>
This will make it so you don't have to remove the original svg objects, if you add a delay in myChart.draw(800, false); in the change function, it will animate the change.
Related
im try using Amchart plugin into my system. Chart successful appear when i run basic code for chart. Then im try to use a custom for loading indicator. But the problem is indicator for loading not stopping even chart is appear.
Below is the JS script
am4core.useTheme(am4themes_animated);
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
// Add data
chart.data = [{
"category": "Research",
"value": 450
}, {
"category": "Marketing",
"value": 1200
}, {
"category": "Distribution",
"value": 1850
}];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "category";
categoryAxis.renderer.grid.template.location = 0;
//categoryAxis.renderer.minGridDistance = 30;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueY = "value";
series.dataFields.categoryX = "category";
var indicator;
var indicatorInterval;
function showIndicator() {
if (!indicator) {
indicator = chart.tooltipContainer.createChild(am4core.Container);
indicator.background.fill = am4core.color("#fff");
indicator.width = am4core.percent(100);
indicator.height = am4core.percent(100);
var indicatorLabel = indicator.createChild(am4core.Label);
indicatorLabel.text = "Loading stuff...";
indicatorLabel.align = "center";
indicatorLabel.valign = "middle";
indicatorLabel.dy = 50;
var hourglass = indicator.createChild(am4core.Image);
hourglass.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/hourglass.svg";
hourglass.align = "center";
hourglass.valign = "middle";
hourglass.horizontalCenter = "middle";
hourglass.verticalCenter = "middle";
hourglass.scale = 0.7;
}
indicator.hide(0);
indicator.show();
clearInterval(indicatorInterval);
indicatorInterval = setInterval(function() {
hourglass.animate([{
from: 0,
to: 360,
property: "rotation"
}], 2000);
}, 3000);
}
function hideIndicator() {
indicator.hide();
clearInterval(indicatorInterval);
}
showIndicator();
Below is the html code
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
im already try a few method, but no lucky for me. Any suggestion
On amchart4 documentation (https://www.amcharts.com/docs/v4/tutorials/custom-loading-indicator/), it only shows how you can create a custom loading indicator. It doesn't hook up hideIndicator() event when the chart is finished rendering.
There is a Ready event you can use now (https://github.com/amcharts/amcharts4/issues/436#issuecomment-441370242). You can just simply hook up hideIndicator() function to the Ready event:
...
chart.events.on("ready", function(ev){
hideIndicator();
});
...
fiddle: https://jsfiddle.net/davidliang2008/akpe5f4b/1/
My chart needs to have tick values in multiples of 3. For example, if I have 5 data points, my x-axis should show (3, 6, 9, 12, 15). How do I get nvd3 to display all tick numbers? I pasted my code below for reference
var chart = nv.models.lineChart()
.options({
margin: {left: 100, bottom: 100},
x: function(d,i) { return i*3},
showXAxis: true,
showYAxis: true,
showLegend: true,
reduceXTicks: false,
showMaxMin: false,
//values: $scope.data.values.map( function(d,i) { return i*3; }),
useInteractiveGuideline: true,
transitionDuration: 2500,
showControls : true
})
;
chart.xAxis //Chart x-axis settings
.axisLabel('Ager')
.orient('bottom')
//.tickValues( function(d,i) { return i*3;})
.tickFormat(d3.format(',r'));
chart.yAxis //Chart y-axis settings
.axisLabel('Voltage (v)')
.tickFormat(d3.format('.02f')); nv.utils.windowResize(chart.update);
I've tried everything I can think of and read online to get nvd3 show all ticks in multiples of 3. Please help me out of this tricky situation.
Thanks in advance!
You could have read the d3 docs and see that .tickValues does not accept a function.
Construct the array of tick values based on the domain of the x-axis. Because the domain is not yet set you have to construct it yourself based on the data.
Using the SinCos example from the nvd3 site
var myData = sinAndCos();
var xExtent = d3.extent(myData[0].values, d=>d.x);
xExtent = [Math.floor(xExtent[0]), Math.ceil(xExtent[1])+1];
var xTicks = d3.range(xExtent[0], xExtent[1]).filter(n => n%3===0);
chart.xAxis
.axisLabel('Time (ms)')
.tickValues(xTicks)
.tickFormat(d3.format(',r'));
Complete example. It will not run directly from the browser (will not load nvd3 inside an iframe(??)). Copy it to a local file and run it from there.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="https://nvd3.org/assets/css/nv.d3.css" rel="stylesheet"/>
<script src="https://nvd3.org/assets/lib/d3.v3.js"></script>
<script src="https://nvd3.org/assets/js/nv.d3.js"></script>
</head>
<body>
<div id="chart">
<svg style="width:800px;height:500px;"></svg>
</div>
<script>
/*These lines are all chart setup. Pick and choose which chart features you want to utilize. */
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
var myData = sinAndCos();
var xExtent = d3.extent(myData[0].values, d=>d.x);
xExtent = [Math.floor(xExtent[0]), Math.ceil(xExtent[1])+1];
var xTicks = d3.range(xExtent[0], xExtent[1]).filter(n => n%3===0);
chart.xAxis //Chart x-axis settings
.axisLabel('Time (ms)')
.tickValues(xTicks)
.tickFormat(d3.format(',r'));
chart.yAxis //Chart y-axis settings
.axisLabel('Voltage (v)')
.tickFormat(d3.format('.02f'));
d3.select('#chart svg') //Select the <svg> element you want to render the chart in.
.datum(myData) //Populate the <svg> element with chart data...
.call(chart); //Finally, render the chart!
//Update the chart when window resizes.
nv.utils.windowResize(function() { chart.update() });
return chart;
});
/**************************************
* Simple test data generator
*/
function sinAndCos() {
var sin = [],sin2 = [],
cos = [];
//Data is represented as an array of {x,y} pairs.
for (var i = 0; i < 100; i++) {
sin.push({x: i, y: Math.sin(i/10)});
sin2.push({x: i, y: Math.sin(i/10) *0.25 + 0.5});
cos.push({x: i, y: .5 * Math.cos(i/10)});
}
//Line chart data should be sent as an array of series objects.
return [
{
values: sin, //values - represents the array of {x,y} data points
key: 'Sine Wave', //key - the name of the series.
color: '#ff7f0e' //color - optional: choose your own line color.
},
{
values: cos,
key: 'Cosine Wave',
color: '#2ca02c'
},
{
values: sin2,
key: 'Another sine wave',
color: '#7777ff',
area: true //area - set to true if you want this line to turn into a filled area chart.
}
];
}
</script>
</body>
</html>
--I'm brand new to coding, but slowly working my way through fiddles. Your patience is appreciated!--
I'm working on creating a visual representation of the diaspora of a small village in Ukraine. I have so far found a fiddle that does what I need, up to a point. I'm having trouble with the following bits though:
I have no issue with a single var departure --> var arrival line animating, as per the original fiddle, but I can't quite find resources on how to add another line (whether same var departure or different).
I would also like to add multiple points along the same itinerary. Everything I've found uses a list of LatLng coordinates but I can't get that to animate.
Any help would be greatly appreciated! Thanks!
http://jsfiddle.net/bz4b9jkg/6/
var map;
$(document).ready(function () {
var latlng = new google.maps.LatLng(41.142556, -42.219561);
var myOptions = {
zoom: 2,
center: latlng,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map($('#map_canvas').get(0), myOptions);
var departure = new google.maps.LatLng(49.461686, 23.174658); //Set to whatever lat/lng you need for your departure location
var arrival = new google.maps.LatLng(40.6983279,-74.0433196); //Set to whatever lat/lng you need for your arrival location
var line = new google.maps.Polyline({
path: [departure, departure],
strokeColor: "#FF0000",
strokeOpacity: 0.7,
strokeWeight: 2,
geodesic: true, //set to false if you want straight line instead of arc
map: map,
});
var step = 0;
var numSteps = 250; //Change this to set animation resolution
var timePerStep = 5; //Change this to alter animation speed
var interval = setInterval(function() {
step += 1;
if (step > numSteps) {
clearInterval(interval);
} else {
var are_we_there_yet = google.maps.geometry.spherical.interpolate(departure, arrival, step / numSteps);
line.setPath([departure, are_we_there_yet]);
}
}, timePerStep);
line.setMap(map);
});
#import url('http://getbootstrap.com/dist/css/bootstrap.css');
body{padding-top:25px;}
#map_canvas {
width: 100%;
height: 400px;
}
<script src="http://maps.google.com/maps/api/js?sensor=false&dummy=.js"></script>
<div class="container">
<div class="well">
<div id="map_canvas"></div>
</div>
</div>
Check out my html5 based clipping constraint on
http://shedlimited.debrucellc.com/test3/canvaskinclip.html
(messing with jsfiddle on http://jsfiddle.net/aqaP7/4/)
So, in html5 I can easily draw a shaped boundary like the following:
context.beginPath();
context.moveTo(5, 5);
context.lineTo(34, 202);
context.lineTo(2, 405);
context.lineTo(212, 385);
context.lineTo(425, 405);
context.lineTo(400, 202);
context.lineTo(415, 10);
context.lineTo(212, 25);
context.clip();
In kinetic.js though, all I see for clipping options is: height, width, and x, y,
I came across the following : Mask/Clip an Image using a Polygon in KineticJS, but the inner/fill image can't be set to draggable
any help please!
In the new kineticJS versions, a lot of the work is done in the background for you.
Take a look at this tutorial:
This fiddle gets you pretty close, here's the code:
<body>
<div id="container"></div>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.0-beta2.js"></script>
<script>
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function draw(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 600,
height: 700
});
var layer = new Kinetic.Layer();
var patternPentagon = new Kinetic.RegularPolygon({
x: 220,
y: stage.getHeight() / 4,
sides: 5,
radius: 70,
fillPatternImage: images.yoda,
fillPatternOffset: [-220, 70],
stroke: 'black',
strokeWidth: 4,
draggable: true
});
patternPentagon.on('dragmove', function() {
//this.setFillPatternImage(images.yoda);
//this.setFillPatternOffset(-100, 70);
var userPos = stage.getUserPosition();
this.setFillPatternOffset(-userPos.x,-userPos.y);
layer.draw();
this.setX(220);
this.setY(stage.getHeight() / 4);
});
layer.add(patternPentagon);
stage.add(layer);
}
var sources = {
darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg',
yoda: 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg'
};
loadImages(sources, function(images) {
draw(images);
});
</script>
</body>
There is a more complex/accurate way of doing this without making it a background pattern, like with grouping objects together
i just want to set some markers based on a xml file and additionally create three different marker clusterer with own icons!
the problems are:
no markers are displayed
how i have to implement three marker groups (marker clusterer) with my own icons
index.html
<html>
<head>
<title>Google Maps Integration</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="js/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="js/data.json"></script>
<script type="text/javascript" src="js/markerclusterer.js"></script>
<script type="text/javascript" src="js/markers.js"></script>
</head>
<body>
<div id="map"></div>
</body>
</html>
marker.js
$(document).ready(function() {
$("#map").css({
height: 675,
width: 659
});
var myLatLng = new google.maps.LatLng(51.918, 4.47663);
MYMAP.init('#map', myLatLng, 7);
MYMAP.placeMarkers("markers.xml"); // xml data
});
var MYMAP = {
map: null,
}
MYMAP.init = function(selector, latLng, zoom) {
var myOptions = {
zoom:zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map($(selector)[0], myOptions);
}
// set markers
MYMAP.placeMarkers = function(filename) {
var markers = []; // create new array for marker points
$.get(filename, function(xml){
$(xml).find("marker").each(function(){
var name = $(this).find('name').text();
var address = $(this).find('address').text();
// create a new LatLng point for the marker
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
// set marker new
var marker = new google.maps.Marker({position: point});
markers.push(marker);
// set marker info
var infoWindow = new google.maps.InfoWindow();
var html='<b>'+name+'</b><br>'+address;
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(MYMAP.map, marker);
});
});
var markerCluster = new MarkerClusterer(map, markers);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
marker.xml
<?xml version="1.0"?>
<markers>
<marker>
<name>Heineken Amsterdam</name>
<address>Joop Geesinkweg 5</address>
<city>Amsterdam</city>
<postcode>1096 AT</postcode>
<lat>52.3354</lat>
<lng>4.92938</lng>
</marker>
</markers>
Check out the newest version of markerclusterPlus here:
http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.6/
There is a good doc and some examples too.