I would like to have vertical zooming and horizontal panning with a simple bar chart. Here's my example: http://jsfiddle.net/bjames/rR7ee/.
Most of what I've tried involves viewBox and I understand I might have more luck with a clipPath. But all the examples I've found use a continuous x-axis in the zoom function to get the job done.
In my example, there are 8 bars but only 4 are visible. I'd like to drag the panel to the left. What am I missing?
Thanks in advance.
width = 600
height = 600
padding = {left:40, top:20, right:20, bottom:30}
size = {
x: width - padding.left - padding.right,
y: height - padding.top - padding.bottom
}
var svg = d3.select('.container').append('div')
.append("svg")
.attr("width", 300)
.attr("height", height)
.attr('class', 'frame')
.append("g")
.attr("transform", "translate(" + padding.left + "," +
padding.top + ")")
svg.append('rect')
.attr('class', 'background')
.attr('pointer-events', 'all')
.attr('fill', 'none')
.attr('height', size.y + 'px')
.attr('width', size.x + 'px')
var d = [5,6,7,8,9,10,11,12]
var x = d3.scale.ordinal()
.domain(d3.range(d.length))
.rangeRoundBands([0, size.x], .15)
var y = d3.scale.linear()
.domain([0,d3.max(d)])
.range([size.y, 0])
var xax = d3.svg.axis().scale(x)
.tickSize(-size.y).orient('bottom')
var yax = d3.svg.axis().scale(y)
.tickSize(-size.x).orient('left')
svg.append("g")
.attr("class", "y axis")
.call(yax)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + size.y+ ")")
.call(xax)
svg.append('g').attr('class', 'rects')
function update(){
var rects = d3.select('.rects').selectAll('rect')
.data(d)
rects.attr('x', function(d,i) { return x(i)})
.attr('width', x.rangeBand())
.attr('y', function(d) { return y(d)})
.attr('height', function(d) { return size.y - y(d)})
rects.enter().append('rect')
.attr('x', function(d,i) { return x(i) })
.attr('width', x.rangeBand())
.attr('y', function(d) { return y(d)})
.attr('height', function(d) { return size.y - y(d)})
.style('fill', 'orange')
svg.select('.y.axis')
.call(yax)
svg.select('.x.axis')
.call(xax)
svg.select('.background')
.call(zoom)
}
var zoom = d3.behavior.zoom()
.on("zoom", zoomed)
function zoomed() {
y.domain([0, d3.max(d)*1/d3.event.scale])
update();
}
update()
The vertical zooming was already implemented. I implemented the horizontal panning.
Note: Both zooming and panning happens on the rectangle in the background, as listeners attached to it.
I have added comments in the fiddle code that should help you out in the logic.
width = 600
height = 600
padding = {left:40, top:20, right:20, bottom:30}
size = {
x: width - padding.left - padding.right,
y: height - padding.top - padding.bottom
}
var svg = d3.select('.container').append('div')
.append("svg")
.attr("width", 300)
.attr("height", height)
.attr('class', 'frame')
.append("g")
.attr("transform", "translate(" + padding.left + "," +
padding.top + ")")
svg.append('rect')
.attr('class', 'background')
.attr('pointer-events', 'all')
.attr('fill', 'none')
.attr('height', size.y + 'px')
.attr('width', size.x + 'px')
var d = [5,6,7,8,9,10,11,12]
var x = d3.scale.ordinal()
.domain(d3.range(d.length))
.rangeRoundBands([0, size.x], .15)
var y = d3.scale.linear()
.domain([0,d3.max(d)])
.range([size.y, 0])
var xax = d3.svg.axis().scale(x)
.tickSize(-size.y).orient('bottom')
var yax = d3.svg.axis().scale(y)
.tickSize(-size.x).orient('left')
svg.append("g")
.attr("class", "y axis")
.call(yax)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + size.y+ ")")
.call(xax)
var svg1 = svg.append('svg')
.attr('height', size.y + 'px')
.attr('width', size.x + 'px')
svg1.append('g').attr('class', 'rects')
function update(){
var rects = d3.select('.rects').selectAll('rect')
.data(d)
rects.attr('x', function(d,i) { return x(i)})
.attr('width', x.rangeBand())
.attr('y', function(d) { return y(d)})
.attr('height', function(d) { return size.y - y(d)})
rects.enter().append('rect')
.attr('x', function(d,i) { return x(i) })
.attr('width', x.rangeBand())
.attr('y', function(d) { return y(d)})
.attr('height', function(d) { return size.y - y(d)})
.style('fill', 'orange')
svg.select('.y.axis')
.call(yax)
svg.select('.x.axis')
.call(xax)
svg.select('.background')
.call(zoom)
svg.select('.background')
.call(drag)
}
var zoom = d3.behavior.zoom()
.on("zoom", zoomed)
function zoomed() {
y.domain([0, d3.max(d)*1/d3.event.scale])
update();
}
var drag = d3.behavior.drag()
.on("drag", dragmove).on("dragstart", dragstart);
var moved = 0;//record the translate x moved by the g which contains the bars.
var dragStartX = 0;//record the point from where the drag started
var oldTranslateX = 0;
function dragstart(d){
dragStartX = d3.event.sourceEvent.clientX;
oldTranslateX = moved;//record the old translate
console.log(d3.event)
}
function dragmove(d) {
var x = d3.event.x;
var y = d3.event.y;
var dx = x-dragStartX
x = dx + oldTranslateX + 50; //add the old translate to the dx to get the resultant translate
moved = x; //record the translate x given
//move the bars via translate x
d3.select('.rects').attr("transform", "translate(" + x + "," + 0 + ")");
//move the x axis via translate x
d3.select('.x').attr("transform", "translate("+x +" ," + size.y+ ")")
}
update()
Here is the fiddle: http://jsfiddle.net/cyril123/o0qeom7n/3/
Related
I have three charts in different positions. The tooltips look fine for my first chart, but for the other two the tooltips show in the first chart.
I've tried BBbox and getboundindclientrect(), and none of them work for d3.select(this).
// This is my chart module, I'm struggling to get xPosition and yPosition right.
function chart(selection) {
innerWidth = width - margin.left - margin.right,
innerHeight = height - margin.top - margin.bottom,
selection.each(function (data) {
// Select the svg element, if it exists.
var svg = d3.select(this).selectAll("svg").data([data]);
// Otherwise, create the skeletal chart.
var svgEnter = svg.enter().append("svg");
var gEnter = svgEnter.append("g");
gEnter.append("g").attr("class", "x axis");
gEnter.append("g").attr("class", "y axis");
// Update the outer dimensions.
svg.merge(svgEnter).attr("width", width)
.attr("height", height);
// Update the inner dimensions.
var g = svg.merge(svgEnter).select("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
xScale.rangeRound([0, innerWidth])
.domain(data.map(xValue)); //xValue = function(d) { return d[0]; }
yScale.rangeRound([innerHeight, 0])
.domain([0, d3.max(data, yValue)]);
g.select(".x.axis")
.attr("transform", "translate(0," + innerHeight + ")")
.call(d3.axisBottom(xScale));
g.select(".y.axis")
.call(d3.axisLeft(yScale).ticks(10))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Frequency");
var bars = g.selectAll(".bar")
.data(function (d) { return d; });
bars.enter().append("rect")
.attr("class", "bar")
.merge(bars)
.attr("x", X) // function X(d) {return xScale(xValue(d));}
.attr("y", Y)
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return innerHeight - Y(d); })
.attr("fill", "rgb(0, 18, 65") // International Klein blue
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.bandwidth()/2; // + parseFloat(bars.node().getBBox().x);
var yPosition = parseFloat(d3.select(this).attr("y"))/2 + innerHeight/2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#value")
.text(yValue(d));
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
})
.on("click", onClick);
bars.exit().remove();
});
}
I'd like to get the tooltips on top of my rectangles when I place the mouse over them.
I create a line chart like that.
However, I added the possibility to update data. The "darker line" is updated correctly, the area no.
Here is a piece of code:
var margin = {top: 10, right: 10, bottom: 35, left: 30};
var width = 500 - margin.left - margin.right;
var height = 220 - margin.top - margin.bottom;
var x = d3.scalePoint().range([width, 0]);
var y = d3.scaleLinear().range([height, 0]);
x.domain([...new Set(dataFilter.map(function(d) {
return d.year;
}))]);
y.domain([minX, 100]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var valueline = d3.line()
.x(function(d) {
return x(d.year);
})
.y(function(d) {
return y(d.euro);
})
.defined(function(d) {
return (d.euro !== 0 && !isNaN(d.euro));
});
var area = d3.area()
.x(function(d) {
return x(d.year);
})
.y0(function(d) {
return y(d.euro);
})
.y1(height)
.defined(function(d) {
return (d.euro !== 0 && !isNaN(d.euro));
});
var svg = d3.select("#chart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
svg.append("path")
.attr("class", "linePath")
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 1)
.attr("d", valueline(dataFilter));
svg.append('path')
.datum(dataFilter)
.attr('d', area)
.attr('fill', 'steelblue')
.attr('stroke', 'none')
.attr('opacity', '0.1')
.attr('class', 'areaLines');
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + height + ")")
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
function updateData() {
dataFilter = ...; // other data
// Scale the range of the data again minX is now different
x.domain([...new Set(dataFilter.map(function(d) {
return d.year;
}))]);
y.domain([minX, 100]);
var svg = d3.select("#chart").transition();
svg.select(".linePath")
.duration(1000)
.attr("d", valueline(dataFilter));
svg.select(".x.axis")
.duration(1000)
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
// update area (doesn't work): TypeError: svg.select(...).datum is not a function
svg.select('.areaLines')
.datum(dataFilter)
.attr('d', area)
.duration(1000);
svg.select(".y.axis")
.duration(1000)
.call(yAxis);
}
When I run it I get: TypeError: svg.select(...).datum is not a function.
Why?
I found this question but I'cant able to solve the problem. Thanks a lot!!
You cannot transition the datum, it makes no sense. That's why datum() is not a transformation method.
Instead of that, transition the d attribute:
svg.select('.areaLines')
.attr('d', area(dataFilter))
.duration(1000);
I have the following segment in one of my d3 graph.
What I want is to display some text in a rectangle.
var values = $('#<%=hdnDtArray.ClientID%>').val();
var data = JSON.parse(values);
margin = {
top: 20,
right: 60,
bottom: 20,
left: 100
};
var width = 900,
height = 350;
var vis = d3.select("#line_chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var parseTime = d3.time.format("%Y.%m.%d").parse;
max_y = 0;
min_y = data[0].close;
var extent = d3.extent(data.map(function(d) {
return d.date
}));
max_x = extent[1];
min = extent[0];
for (i = 0; i < data.length; i++) {
max_y = Math.max(max_y, data[i].close);
min_y = Math.min(min_y, data[i].close);
}
var x = d3.time.scale()
.rangeRound([margin.left, width]);
xScale = x.domain(d3.extent(data, function(d) {
return parseTime(d.date);
}));
yScale = d3.scale.linear().range([height - margin.top, margin.bottom]).domain([0, max_y]),
xAxis = d3.svg.axis()
.scale(xScale),
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.innerTickSize(-width + margin.left)
.outerTickSize(0)
.tickPadding(10);
vis.append("svg:g")
.attr("class", "x axis")
.style({
'stroke': 'Black',
'fill': 'none',
"stroke-width": 1,
"font-size": "13px"
})
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(xAxis)
.selectAll("text")
.attr("transform", "translate(-10,0) rotate(-40)")
.style("text-anchor", "end");
vis.append("text")
.attr("class", "x label")
.attr("text-anchor", "end")
.attr("x", width + 120)
.attr("y", height - 10)
.attr("font-weight", "bold");
vis.append("svg:g")
.attr("class", "y axis")
.style({
'stroke': 'Black',
'fill': 'none',
'stroke-width': 1,
"font-size": "13px"
})
.attr("transform", "translate(" + (margin.left) + ",0)")
.call(yAxis);
vis.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("x", margin.left + 5)
.attr("y", margin.top - 2)
.attr("font-weight", "bold");
var line = d3.svg.line()
.x(function(d) {
return xScale(parseTime(d.date));
})
.y(function(d) {
return yScale(d.close);
})
.interpolate("basis");
vis.append('svg:path')
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
var hoverLineGroup = vis.append("g")
.attr("class", "hover-line");
var hoverLine = hoverLineGroup.append("line")
.attr("stroke", "#000000")
.attr("stroke-width", "1px")
.attr("x1", 10).attr("x2", 10)
.attr("y1", 20).attr("y2", height - 20);
var hoverTT = hoverLineGroup.append('text')
.attr("class", "hover-tex capo")
.attr('dy', "0.35em");
var cle = hoverLineGroup.append("circle")
.attr("r", 4.5);
var hoverTT2 = hoverLineGroup.append('text')
.attr("class", "hover-text capo")
.attr('dy', "0.55em");
hoverLineGroup.style("opacity", 1e-6);
var rectHover = vis.append("rect")
.data(data)
.attr("fill", "none")
.attr("width", width)
.attr("height", height);
var hoverCircle = hoverLineGroup.append("circle");
var hoverRect = hoverLineGroup
.append("rect");
vis.on("mouseout", hoverMouseOff)
.on("mousemove", hoverMouseOn);
var bisectDate = d3.bisector(function(d) {
return parseTime(d.date);
}).left;
function hoverMouseOn() {
var mouse_x = d3.mouse(this)[0];
var mouse_y = d3.mouse(this)[1];
var graph_y = yScale.invert(mouse_y);
var graph_x = xScale.invert(mouse_x);
var mouseDate = xScale.invert(mouse_x);
var i = bisectDate(data, mouseDate);
var d0 = data[i - 1]
var d1 = data[i];
var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;
hoverRect.attr("class", "y")
.style("fill", "none")
.style("stroke", "black")
.attr('x', mouse_x + 8)
.attr('y', yScale(d.close) - 20)
.attr("width", 200)
.attr("height", 50);
hoverTT.text("Test Text")
.attr("opacity", "1");
hoverTT.attr('x', mouse_x + 23);
hoverTT.attr('y', yScale(d.close));
/*
hoverTT.text("Date: " + d.date);
hoverTT.attr('x', mouse_x + 23);
hoverTT.attr('y', yScale(d.close));
hoverTT2.text("Portfolio Value: " + Math.round(d.close * 100) / 100)
.attr('x', mouse_x + 23)
.attr('y', yScale(d.close) + 10);
*/
hoverLine.attr("x1", mouse_x).attr("x2", mouse_x)
hoverLineGroup.style({
'font-weight': 'bold',
'opacity': 1
});
hoverCircle.attr("class", "y")
.style("fill", "blue")
.style("stroke", "blue")
.attr("r", 4)
.attr('cx', mouse_x)
.attr('cy', yScale(d.close));
}
function hoverMouseOff() {
hoverLineGroup.style("opacity", 1e-6);
}
The text is not visible now. But if I set the "fill" property to "none", then the text becomes visible.
What I want is the background to be non transparent, that's why I made it white.
Still I want the text to be visible.
The problem with your code is the order of the selections.
In an SVG, just like a real painter using ink in a real canvas, what is painted later remains on top. So, if you want the text to be on top of the rectangle (with any fill you want), set the text's selection after the rectangle's selection.
Therefore, in your case, this...
var hoverTT = hoverLineGroup.append('text')
.attr("class", "hover-tex capo")
.attr('dy', "0.35em");
... has to be after this:
var hoverRect = hoverLineGroup
.append("rect");
Here is a demo, the rectangle has a solid white fill. Have a look at the order of the selections:
var svg = d3.select("svg");
var hoverRect = svg.append("rect")
.attr("fill", "white")
.attr("stroke", "firebrick")
.attr("width", 40)
.attr("height", 30)
.attr("opacity", 0);
var hoverText = svg.append("text")
.text("foo")
svg.on("mousemove", function() {
var coords = d3.mouse(this);
hoverRect.attr("x", coords[0] + 15)
.attr("y", coords[1])
.attr("opacity", 1)
hoverText.attr("x", coords[0] + 25)
.attr("y", coords[1] + 20)
})
svg {
border: 1px solid gray;
background-color: gainsboro;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
I've modified nice AlainRo’s Block for my needs (unfortunately can't link to it, because have not enough reputation), and I can't remove old data chart after entering new data. There is my codepen. In another example I've added merge(), and the chart is well aligned but the old one is still visible and text values are missed.
I spent a lot of time on it, and I run out of ideas.
There's code
barData = [
{ index: _.uniqueId(), value: _.random(1, 20) },
{ index: _.uniqueId(), value: _.random(1, 20) },
{ index: _.uniqueId(), value: _.random(1, 20) }
];
var margin = {top: 20, right: 20, bottom: 50, left: 70},
width = 400 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom,
delim = 4;
var scale = d3.scaleLinear()
.domain([0, 21])
.rangeRound([height, 0]);
var x = d3.scaleLinear()
.domain([0, barData.length])
.rangeRound([0, width]);
var y = d3.scaleLinear()
.domain([0, 21])
.rangeRound([height, 0]);
var svg = d3.select('#chart')
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));
function draw() {
x.domain([0, barData.length]);
var brush = d3.brushY()
.extent(function (d, i) {
return [[x(i)+ delim/2, 0],
[x(i) + x(1) - delim/2, height]];})
.on("brush", brushmove);
var svgbrush = svg.selectAll('.brush')
.data(barData)
.enter()
.append('g')
.attr('class', 'brush')
.append('g')
.call(brush)
.call(brush.move, function (d){return [d.value, 0].map(scale);});
svgbrush
.append('text')
.attr('y', function (d){return scale(d.value) + 25;})
.attr('x', function (d, i){return x(i) + x(0.5);})
.attr('dx', '-.60em')
.attr('dy', -5)
.style('fill', 'white')
.text(function (d) {return d3.format('.2')(d.value);});
svgbrush
.exit()
.append('g')
.attr('class', 'brush')
.remove();
function brushmove() {
if (!d3.event.sourceEvent) return; // Only transition after input.
if (!d3.event.selection) return; // Ignore empty selections.
if (d3.event.sourceEvent.type === "brush") return;
var d0 = d3.event.selection.map(scale.invert);
var d = d3.select(this).select('.selection');;
var d1 =[d0[0], 0];
d.datum().value = d0[0]; // Change the value of the original data
d3.select(this).call(d3.event.target.move, d1.map(scale));
svgbrush
.selectAll('text')
.attr('y', function (d){return scale(d.value) + 25;})
.text(function (d) {return d3.format('.2')(d.value);});
}
}
draw();
function upadateChartData() {
var newBarsToAdd = document.getElementById('charBarsCount').value;
var newBarData = function() {
return { index: _.uniqueId(), value: _.random(1, 20) }
};
newBarData = _.times(newBarsToAdd, newBarData);
barData = _.concat(barData, newBarData)
draw();
};
Is it also possible to remove cross pointer and leave only resize, when I'm dragging top bar border?
You're appending g elements twice. This:
svgbrush.enter()
.append('g')
.attr('class', 'brush')
.merge(svgbrush)
.append('g')
.call(brush)
.call(brush.move, function (d){return [d.value, 0].map(scale);});
Should be:
svgbrush.enter()
.append('g')
.attr('class', 'brush')
.merge(svgbrush)
.call(brush)
.call(brush.move, function (d){return [d.value, 0].map(scale);});
Here is your updated Pen: http://codepen.io/anon/pen/VmavyX
PS: I also made other changes, declaring some new variables, just to organize your enter and update selections and solving the texts problem.
I have a scatter plot that don't zoom and don't move the line of mean when drag and zoom.
The mean line stay fixed.
var margin = {top: 50, right: 20, bottom: 100, left: 80};
var width = 1024 - margin.left - margin.right;
var height = 390;
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
d3.json("data.json", function(error, data) {
data.forEach(function(d)
d.date = parseDate(d.date);
d.tiempo = +d.tiempo;
});
var x = d3.time.scale().range([0, width])
.domain(d3.extent(data, function(d) { return d.date; }))
.nice();
var y = d3.scale.linear().range([height, 0])
.domain([0, d3.max(data, function(d) { return d.tiempo; })])
.nice();
var zoom = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([1, 100])
.on("zoom", zoomed);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(15)
.tickSize(-height);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(15)
.tickSize(-width);
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
var Rect = svg.append("rect")
.attr("width", width)
.attr("height", height);
// Eje X
svg.append("g")
.classed("x axis", true)
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.classed("label", true)
.attr("x", width)
.attr("y", margin.bottom - 10)
.style("text-anchor", "end")
.text("Tiempo de llegada");
// Eje Y
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.classed("label", true)
.attr("transform", "rotate(-90)")
.attr("y", -margin.left)
.attr("dy", "1.91em")
.style("text-anchor", "end")
.text("Tiempos de espera")
// Objetos, puntos.
var objects = svg.append("svg")
.classed("objects", true)
.attr("width", width)
.attr("height", height);
objects.append("svg:line")
.classed("axisLine hAxisLine", true)
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", width)
.attr("y2", 0)
.attr("transform", "translate(0," + height + ")");
objects.append("svg:line")
.classed("axisLine vAxisLine", true)
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", height);
var puntos = objects.selectAll(".dot")
.data(data)
.enter().append("circle")
.classed("dot", true)
.attr("r", 3.5)
.attr("class", function(d) {
if(d.d7up==1) {
return "dot s7";
}else if(d.d7do==1) {
return "dot b7";
};
return "dot pu";
});
puntos.attr("transform", transform);
var meanData = [
{date: data[0].date, tiempo: 6.22},
{date: data[data.length - 1].date, tiempo: 6.22}
];
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.tiempo); });
var l = objects.selectAll(".lineamedia")
.data(meanData)
.enter().append("circle")
.classed("lineamedia", true)
.attr("r", 5)
.attr("stroke", "red")
.attr("fill", "red")
.attr("transform", transform);
var ll = objects.append("g")
.classed("grupolinea", true);
ll.append("line")
.attr("x1", x(meanData[0].date))
.attr("y1", y(meanData[0].tiempo))
.attr("x2", x(meanData[meanData.length - 1].date))
.attr("y2", y(meanData[meanData.length - 1].tiempo))
.attr("stroke", "red")
.attr("fill", "red")
.attr("stroke-width", 4)
.classed("medias", true);
function zoomed() {
svg.select(".x.axis").call(xAxis);
svg.select(".y.axis").call(yAxis);
//svg.selectAll(".dot").attr("transform", transform);
puntos.attr("transform", transform);
l.attr("transform", transform);
//svg.select(".grupolinea").attr("transform", transform);
}
function transform(d) {
return "translate(" + x(d.date) + "," + y(d.tiempo) + ")";
}
})
My data array is:
var = data[{"date":"2016-04-25 07:37:24","tiempo":29.366666666667}, {"date":"2016-04-25 08:18:36","tiempo":8.4833333333333},{"date":"2016-04-25 08:32:15","tiempo":5.25},{"date":"2016-04-25 08:40:57","tiempo":2.4166666666667},{"date":"2016-04-25 08:41:09","tiempo":5.3166666666667},{"date":"2016-04-25 08:58:10","tiempo":5.5833333333333},{"date":"2016-04-25 09:00:20","tiempo":4.2166666666667},{"date":"2016-04-25 09:00:42","tiempo":5.2666666666667}]
Is a graph de times wait where
date: of comming patient;
time: time of wait;