Plotting Labels on NVD3 scatterChart - javascript

If I have the following code from the example at http://nvd3.org/examples/scatter.html, can I add a label to the plotted points? Not a tooltip, but have one of the values in my data render as a label which is always attached to the point? Obviously doing that in this specific example would be way too crowded, but in a less sparsely populated chart, it would be great to label if each point has a name. Thank you!
nv.addGraph(function() {
var chart = nv.models.scatterChart()
.showDistX(true) //showDist, when true, will display those little distribution lines on the axis.
.showDistY(true)
.transitionDuration(350)
.color(d3.scale.category10().range());
//Configure how the tooltip looks.
chart.tooltipContent(function(key) {
return '<h3>' + key + '</h3>';
});
//Axis settings
chart.xAxis.tickFormat(d3.format('.02f'));
chart.yAxis.tickFormat(d3.format('.02f'));
//We want to show shapes other than circles.
chart.scatter.onlyCircles(false);
var myData = randomData(4,40);
d3.select('#chart svg')
.datum(myData)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
/**************************************
* Simple test data generator
*/
function randomData(groups, points) { //# groups,# points per group
var data = [],
shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],
random = d3.random.normal();
for (i = 0; i < groups; i++) {
data.push({
key: 'Group ' + i,
values: []
});
for (j = 0; j < points; j++) {
data[i].values.push({
x: random()
, y: random()
, size: Math.random() //Configure the size of each scatter point
, shape: (Math.random() > 0.95) ? shapes[j % 6] : "circle" //Configure the shape of each scatter point.
});
}
}
return data;
}

You could just add labels. This is pretty cheesy, but gives an idea:
var svg = d3.select('svg');
svg.selectAll('path')
.each(function(scatterpoint) {
svg.append('text')
.x(scatterpoint.x)
.y(scatterpoint.y)
.text(scatterpoint.maybe_you_have_text_here);
})

Related

Implement zoom in datamaps

I have a globe with datamaps, and I would like to implement a little zoom feature into it. Not zooming to specific countries, just a normal zoom feature.
Where should I look for it? I'm new to d3 as well as datamaps. I managed to customize it, more or less, but this zoom function is still missing.
Here's the codepen:
https://codepen.io/simii/pen/yZvQmv
And my javascript:
//basic map config with custom fills, mercator projection
var series = [
["USA",36.2],["GBR",7.4],["CAN",6.2],["DEU",5.7],["FRA", 4.1],["ESP",4.1],["ITA",3.3],["MEX",3.0],["AUS",2.5],["NLD",2.4],
["IND",2.1],["BRA",2.0],["GRC",1.4],["AUT",1.2],["ROU",1.2],["SRB",1.0],["COL",0.8],["POL",0.8],["ZAF",0.7],["SWE",0.7],
["DNK",0.6],["VEN",0.6],["JPN",0.6],["KOR",0.6],["BEL",0.5],["RUS",0.5],["PRT",0.5]
];
var dataset = {};
// We need to colorize every country based on "percent"
// colors should be uniq for every value.
// For this purpose we create palette(using min/max series-value)
var onlyValues = series.map(function(obj){ return obj[1]; });
var minValue = Math.min.apply(null, onlyValues),
maxValue = Math.max.apply(null, onlyValues);
// create color palette function
// color can be whatever you wish
var paletteScale = d3.scale.linear()
.domain([minValue,maxValue])
.range(["rgb(0,0,0)","rgb(219,219,219)"]); // color
// fill dataset in appropriate format
series.forEach(function(item){ //
// item example value ["USA", 36.2]
var iso = item[0],
value = item[1];
dataset[iso] = { percent: value, fillColor: paletteScale(value) };
});
var map;
var globalRotation = [90,-30];
function redraw() {
d3.select("#world").html('');
init();
}// redraw
function init() {
map = new Datamap({//need global var
scope: 'world',
element: document.getElementById('world'),
projection: 'orthographic',
projectionConfig: {
rotation: globalRotation
},
fills: {defaultFill: 'rgba(30,30,30,0.1)'},
data: dataset,
geographyConfig: {
responsive: true,
borderColor: 'rgba(222,222,222,0.2)',
highlightBorderWidth: 1,
// don't change color on mouse hover
highlightFillColor: function(geo) {
return geo['fillColor'] || 'rgba(30,30,30,0.5)';
},
// only change border
highlightBorderColor: 'rgba(222,222,222,0.5)',
// show desired information in tooltip
popupTemplate: function(geo, data) {
// don't show tooltip if country don't present in dataset
if (!data) { return ; }
// tooltip content
return ['',
'<div style="opacity:0.7;" class="hoverinfo">% of visitors in ' + geo.properties.name,
': ' + data.percent,
''].join('');
}
}
});
//draw a legend for this map
map.legend();
map.graticule();
var drag = d3.behavior.drag().on('drag', function() {
var dx = d3.event.dx;
var dy = d3.event.dy;
// var rotation = livemapScope.rotation;
var rotation = map.projection.rotate();
var radius = map.projection.scale();
var scale = d3.scale.linear()
.domain([-1 * radius, radius])
.range([-90, 90]);
var degX = scale(dx);
var degY = scale(dy);
rotation[0] += degX;
rotation[1] -= degY;
if (rotation[1] > 90) rotation[1] = 90;
if (rotation[1] < -90) rotation[1] = -90;
if (rotation[0] >= 180) rotation[0] -= 360;
globalRotation = rotation;
redraw();
})
d3.select("#world").select("svg").call(drag);
}// init
redraw();

My data is not populating in dimple chart for dual axis. I want to show dual axis in dimple

var svg = dimple.newSvg("#chartContainer", 990, 400);
d3.json("http://localhost:8082/charts/dashboard/index", function (data) {
data = dimple.filterData(data, "monthYear", [
"Jan-2015", "Feb-2015", "Mar-2015", "Apr-2015", "May-2015", "Jun-2015",
"Jul-2015", "Aug-2015", "Sep-2015", "Oct-2015", "Nov-2015", "Dec-2015"
]);
//console.log(data);
//Create the indicator chart on the right of the main chart
var indicator = new dimple.chart(svg, data);
//Pick blue as the default and orange for the selected month
var defaultColor = indicator.defaultColors[0];
var indicatorColor = indicator.defaultColors[2];
//The frame duration for the animation in milliseconds
var frame = 2000;
var firstTick = true;
//Place the indicator bar chart to the right
indicator.setBounds(800, 49, 153, 311);
//Add dates along the y axis
var y = indicator.addCategoryAxis("y", "monthYear");
y.addOrderRule("Date", "Asc");
// Use sales for bar size and hide the axis
var x = indicator.addMeasureAxis("x", "energyConsumption");
x.hidden = true;
//Add the bars to the indicator and add event handlers
var s = indicator.addSeries(null, dimple.plot.bar);
s.addEventHandler("click", onClick);
// Draw the side chart
indicator.draw();
//Remove the title from the y axis
y.titleShape.remove();
// Remove the lines from the y axis
y.shapes.selectAll("line,path").remove();
// Move the y axis text inside the plot area
y.shapes.selectAll("text")
.style("text-anchor", "start")
.style("font-size", "11px")
.attr("transform", "translate(18, 0.5)");
// Manually set the bar colors
s.shapes
.attr("rx", 10)
.attr("ry", 10)
.style("fill", function (d) { return (d.y === 'Jan-2015' ? indicatorColor.fill : defaultColor.fill) })
.style("stroke", function (d) { return (d.y === 'Jan-2015' ? indicatorColor.stroke : defaultColor.stroke) })
.style("opacity", 0.4);
//draw the main chart
//this is the main chart for dual axis.
var chart = new dimple.chart(svg, data);
chart.setBounds(60,20,680,330);
// Add your x axis - nothing unusual here
var x = chart.addMeasureAxis("x", "Date");
// First y axis is the combination axis for revenue and profit
var y1 = chart.addMeasureAxis("y", "Temperature");
// Second is the units only
var y2 = chart.addMeasureAxis("y", "Energy Consumption");
var bars = chart.addSeries("Energy Comsuption", dimple.plot.bar, [x,y2]);
var lines = chart.addSeries("Weather Report", dimple.plot.line, [x,y1]);
bars.barGap = 0.5;
// Colour the bars manually so they don't overwhelm the lines
chart.assignColor("Energy Comsuption", "black", "black", 0.15);
var story = chart.setStoryboard("monthYear", onTick);
//Change the frame duration
story.frameDuration = frame;
// Order the storyboard by date
story.addOrderRule("Date");
//x.dateParseFormat = "%m/%Y";
//x.addOrderRule("Date");
// Here's how you add a legend for just one series. Excluding the last parameter
// will include every series or an array of series can be passed to select more than
// one
//chart.addLegend(60, 5, 680, 10, "right", lines);
chart.draw();
//Orphan the legends as they are consistent but by default they
// will refresh on tick
chart.legends = [];
// Remove the storyboard label because the chart will indicate the
// current month instead of the label
story.storyLabel.remove();
// On click of the side chart
function onClick(e) {
// Pause the animation
story.pauseAnimation();
// If it is already selected resume the animation
// otherwise pause and move to the selected month
if (e.yValue === story.getFrameValue()) {
story.startAnimation();
} else {
story.goToFrame(e.yValue);
story.pauseAnimation();
}
}
// On tick of the main charts storyboard
function onTick(e) {
if (!firstTick) {
// Color all shapes the same
s.shapes
.transition()
.duration(frame / 2)
.style("fill", function (d) { return (d.y === e ? indicatorColor.fill : defaultColor.fill) })
.style("stroke", function (d) { return (d.y === e ? indicatorColor.stroke : defaultColor.stroke) });
}
firstTick = false;
}
});
...................
My data is somewhat like this:-
[{"country":"Australia","state":"New south wales","region":"Sydney",
"suburbs":"Canterbury-Bankstown","temperature":20.0,"humidity":25.0,"precipitation":11.0,"date":"Jan/01/2015",
"energyConsumption":0.141,"monthYear":"Jan-2015"},
{"country":"Australia","state":"New south wales","region":"Sydney","suburbs":"Canterbury-Bankstown",
"temperature":20.0,"humidity":25.0,"precipitation":11.0,"date":"Jan/02/2015",
"energyConsumption":0.088,"monthYear":"Jan-2015"},
{"country":"Australia","state":"New south wales","region":"Sydney","suburbs":"Canterbury-Bankstown",
"temperature":20.0,"humidity":25.0,"precipitation":11.0,"date":"Jan/03/2015",
"energyConsumption":0.078,"monthYear":"Jan-2015"},{"country":"Australia","state":"New south wales","region":"Sydney","suburbs":"Canterbury-Bankstown",
"temperature":20.0,"humidity":25.0,"precipitation":11.0,"date":"Jan/04/2015",
"energyConsumption":0.151,"monthYear":"Jan-2015"},{"country":"Australia","state":"New south wales","region":"Sydney",
"suburbs":"Canterbury-Bankstown","temperature":20.0,"humidity":25.0,"precipitation":11.0,"date":"Jan/05/2015",
"energyConsumption":0.146,"monthYear":"Jan-2015"},
{"country":"Australia","state":"New south wales","region":"Sydney",
"suburbs":"Canterbury-Bankstown","temperature":20.0,"humidity":25.0,"precipitation":11.0,"date":"Jan/06/2015",
"energyConsumption":0.077,"monthYear":"Jan-2015"},{"country":"Australia","state":"New south wales","region":"Sydney",
"suburbs":"Canterbury-Bankstown","temperature":20.0,"humidity":25.0,"precipitation":11.0,
"date":"Jan/07/2015","energyConsumption":0.052,"monthYear":"Jan-2015"},
{"country":"Australia","state":"New south wales","region":"Sydney","suburbs":"Canterbury-Bankstown","temperature":20.0,"humidity":25.0,
"precipitation":11.0,"date":"Jan/08/2015","energyConsumption":0.055,"monthYear":"Jan-2015"}
JSBIN Example
Please take a look at the dual y-axis I created with your data.
There is few things your doing wrong.
var x = chart.addMeasureAxis("x", "Date");
// First y axis is the combination axis for revenue and profit
var y1 = chart.addMeasureAxis("y", "Temperature");
// Second is the units only
var y2 = chart.addMeasureAxis("y", "Energy Consumption");
var bars = chart.addSeries("Energy Comsuption", dimple.plot.bar, [x,y2]);
var lines = chart.addSeries("Weather Report", dimple.plot.line, [x,y1]);
Date, Temperature, Energy Consumption, Weather Report. All of this is not valid, because that not how its define on your data. You have to give exact name as appears on your data.
I only create dual axis for you, I think you can add all the other details starting from there. If you have any other question feel free to post

NVD3 lineChart Conditional Area Color Based On Y Axis

I'm trying to have positive Y values fill with blue and negatives with red. Here is what my graph looks like: Image of Current Graph.
I'm currently adding the color to my dataset in app.js:
if(displayData["VARIANCE"] >= 0){
ctvar.push({
x: Date.now(), y: displayData["VARIANCE"], color:"#0000ff"
});
}else{
ctvar.push({
x: Date.now(), y: displayData["VARIANCE"], color:"#ff0000"
});
}
The dataset is passed to my jade template file as ctvv where I set all the graph settings in js:
function myData() {
return [
{
key: "Cycle time Variance",
values: ctvv,
area: true
}
];
}
nv.addGraph(function() {
var chart = nv.models.lineChart();
chart.xAxis.axisLabel("Time").tickFormat(function(d) {
return d3.time.format('%H:%M')(new Date(d));
});
chart.lines.scatter.xScale(d3.time.scale());
chart.yAxis.axisLabel("Seconds").tickFormat(d3.format("d")).ticks(5);
chart.yDomain([-60,60]);
d3.select("svg").datum(myData()).transition().duration(0).call(chart);
nv.utils.windowResize(
function() {
chart.update();
}
);
return chart;
});
I've tried setting the chart colors using the ctvv and also a plain array of colors.

CanvasJS synchronize Panning with Image

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?

Updating Nvd3 chart priodically

I'm working with Nvd3 charts from the examples from their official website. Now I want a line chart to update periodically based on data sent from server but I couldn't found any useful Example for this on internet.
I have created a function which re-draws the chart when new data is arrived but i want to append every new point to the existing chart (like we can do in highcharts) but i'm stuck.
Here is the code I'm using for Updating the chart.
var data = [{
"key" : "Long",
"values" : getData()
}];
var chart;
function redraw() {
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
chart.xAxis.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d))
});
chart.yAxis.tickFormat(d3.format(',.1%'));
d3.select('#chart svg').datum(data)
//.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
}
function getData() {
var arr = [];
var theDate = new Date(2012, 01, 01, 0, 0, 0, 0);
for (var x = 0; x < 30; x++) {
arr.push({
x : new Date(theDate.getTime()),
y : Math.random() * 100
});
theDate.setDate(theDate.getDate() + 1);
}
return arr;
}
setInterval(function() {
var long = data[0].values;
var next = new Date(long[long.length - 1].x);
next.setDate(next.getDate() + 1)
long.shift();
long.push({
x : next.getTime(),
y : Math.random() * 100
});
redraw();
}, 1500);

Categories