问题描述
我已经编辑了问题,现在的值已经解决了,以前的值不再反映在x轴上.现在,随着滑块的移动,数据在图中没有变化,我可以看到更改x值.
I have edited the question, earlier values were not reflecting on the x axis now that got resolved .Now as the slider moves the data doesn't change in the graph and i can see changing x values.
我正在尝试按照链接在d3中实现一个jquery滑块.该示例以以下格式生成一些随机数的数据:
I'm trying to implement a jquery slider in d3 following this link. The example is generating data of some random numbers while my data is in the below format:
{storeid: 5722646637445120, peoplesum: 87, date: "2018-06-03"}
{storeid: 5722646637445120, peoplesum: 90, date: "2018-06-04"}
{storeid: 5722646637445120, peoplesum: 114, date: "2018-06-05"}
我可以在移动滑块时触发事件,但是这些值现在未反映在图形上.因此,这意味着我的观点是无法正确更新SVG,这是我的假设.我在这里也可能是错的.
I'm able to trigger events when i move my slider but the values are not reflecting on the graph now. So that mean my view is not updating the SVG correctly which is my assumption. I could be wrong here as well.
我的x轴应该有日期范围,而y应该是peoplesum,它可以是单线图或多线图.
My x axis should have the date range and y should be peoplesum and it could be a single or a multiline graph.
更新代码:
private initSvg() {
d3.select("svg").remove();
this.svg = d3.select("#d3Id")
.append("svg")
.attr("width", this.width + this.margin.left + this.margin.right)
.attr("height", this.height + this.margin.top + this.margin.bottom)
.append("g")
.attr("transform",
"translate(" + this.margin.left + "," + this.margin.top + ")")
.attr("stroke-width", 2);
}
private initAxis() {
// Parse the date / time
var parseDate = timeParse("%b %Y");
this.formatTime = timeParse("%e %B");
// Set the ranges
this.x = d3Scale.scaleTime().range([0, this.width]);
this.y = d3Scale.scaleLinear().range([this.height, 0]);
}
private drawAxis() {
var X = this.x;
var Y = this.y;
this.xAxis = d3.axisBottom(this.x)
.ticks(5);
// var xAxis = d3.axisBottom(this.x).tickSize(-this.height).ticks(3);
// // Add the x-axis.
// this.svg.append("svg:g")
// .attr("class", "x axis")
// .attr("transform", "translate(0," + this.height + ")")
// .call(xAxis);
this.yAxis = d3.axisLeft(this.y)
.ticks(5);
// Define the line
this.priceline = d3Shape.line()
.x(function (d) { return X(new Date(d['date'])); })
.y(function (d) { return Y(d['peoplesum']); });
}
private drawLine() {
if ( this.data[0]['d3_parameter_maker'] === true)
{
this.x.domain([0, d3.max(this.data, function (d) { return d['date']; })]);
}
else if ( this.data[0]['d3_parameter_maker'] === undefined)
{
//console.log("aksdad")
var mindate = new Date(this.dashboard_date['startTime']),
maxdate = new Date(this.dashboard_date['endTime']);
this.x.domain([mindate,maxdate]);
}
console.log(new Date(this.dashboard_date['startTime']));
// Scale the range of the data
var svgVar = this.svg;
var pricelineVar = this.priceline;
var margin = this.margin;
var height = this.height;
let thisObj = this;
this.mouseOver = [];
let X = this.x;
let Y = this.y;
if ( this.mouseFlag < 0) {
for ( let i = 0; i < this.peopleInSumArr.length; i++) {
this.mouseOver[i] = true;
}
} else {
for (let i = 0; i < this.peopleInSumArr.length; i++) {
if (i !== this.mouseFlag) {
this.mouseOver[i] = false;
}
}
this.mouseOver[this.mouseFlag] = true;
}
this.y.domain([0, d3.max(this.data, function (d) { return d['peoplesum']; })]);
// Nest the entries by symbol
var dataNest = d3.nest()
.key(function (d) { return d['storeid']; })
.entries(this.data);
// set the colour scale
var color = d3.scaleOrdinal(d3.schemeCategory10);
var legendSpace = this.width / dataNest.length; // spacing for the legend
var div1 = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
dataNest.forEach(function (data, i) {
thisObj.svg.append("path")
.attr("class", "line")
.style("fill", "none")
.attr("d", thisObj.priceline(data.values))
.attr('opacity', thisObj.mouseOver !== undefined && thisObj.mouseOver[i] === true ? 1 : 0.2)
.style('cursor', 'pointer')
.style("stroke", function () { // Add the colours dynamically
return data['color'] = color(data.key);
})
.attr("stroke-width", 3)
.on('click', function () { // on mouse in show line, circles and text
thisObj.mouseFlag = i;
thisObj.initSvg();
thisObj.initAxis();
thisObj.drawAxis();
thisObj.drawLine();
});
// Add the scatterplot
thisObj.svg.selectAll("dot")
.data(data.values)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function (d) { return thisObj.x(new Date(d.date)); })
.attr("cy", function (d) { return thisObj.y(d.peoplesum); })
.style('cursor', 'pointer')
.on("mouseover", function (d) {
div1.transition()
.duration(200)
.style("opacity", .9);
// tslint:disable-next-line:no-unused-expression
div1.html("<b>Date: </b>" + d.date + "<br/>" + "<b>Sum: </b>" + d.peoplesum.toFixed(2))
.style('position', 'absolute')
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style('text-align', 'center')
.style('width', '100px')
.style('height', '30px')
.style('padding', '2px')
.style('font', '12px sans-serif')
.style('background-color', 'lightsteelblue')
.style('border', '0px')
.style('border-radius', '8px')
.style('cursor', 'pointer')
.style('pointer-events', 'none');
})
.on("mouseout", function (d) {
div1.transition()
.duration(500)
.style("opacity", 0);
});
// Add the X Axis
// Add the Y Axis
thisObj.svg.append("text")
.attr("x", (legendSpace / 2) + i * legendSpace) // space legend
.attr("y", height + (margin.bottom / 2) + 5)
.attr("class", "legend") // style the legend
.style('cursor', 'pointer')
.style("fill", function () { // Add the colours dynamically
return data['color'] = color(data.key);
})
.text(data.key)
.attr("stroke-width", 3)
.on('click', function () { // on mouse in show line, circles and text
thisObj.mouseFlag = i;
thisObj.initSvg();
thisObj.initAxis();
thisObj.drawAxis();
thisObj.drawLine();
});
});
// Add the X Axis
let xAxisSelection= this.svg.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0," + this.height + ")")
xAxisSelection.call(d3.axisBottom(this.x));
// Add the Y Axis
let yAxisLeft =this.svg.append("g")
.attr("class", "y axis")
yAxisLeft.call(d3.axisLeft(this.y));
var clip = this.svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("id", "clip-rect")
.attr("x", "0")
.attr("y", "0")
.attr("width", this.width)
.attr("height", this.height);
// Add the line by appending an svg:path element with the data line we created above
// do this AFTER the axes above so that the line is above the tick-lines
var path = this.svg.append("svg")
.attr("class","path")
.attr("clip-path", "url(#clip)")
.attr( thisObj.priceline(this.data));
function zoom(begin, end) {
thisObj.x.domain([begin, end - 1]);
var t = thisObj.svg.transition().duration(0);
var size = moment(moment(end).toDate()).diff(moment(begin).toDate(), 'days');
console.log("size",size);
var step = size / 10;
var ticks = [];
const startDate = new Date(moment(begin).toDate());
for (var i = 0; i <= 10; i++) {
var xAxisDate = new Date(moment(begin).toDate())
// Add a day
xAxisDate.setDate(startDate.getDate() + i)
ticks.push(xAxisDate);
}
xAxisSelection.call(d3.axisBottom(thisObj.x.domain(d3.extent(ticks))));
}
//console.log("this.data)",this.data)
$(function() {
$( "#slider-range" ).slider({
range: true,
min: new Date(mindate).getTime() / 1000,
max: new Date(maxdate).getTime() / 1000,
step: 86400,
values: [ new Date(mindate).getTime() / 1000, new Date(maxdate).getTime() / 1000 ],
slide: function( event, ui ) {
//console.log("ui.values[0]",ui.values)
var begin = d3.min([(new Date(ui.values[ 0 ] *1000).toDateString() ), thisObj.data.length]);
var end = new Date(ui.values[ 1 ] *1000).toDateString(); // 0]);
//console.log("begin:", moment(begin).toDate(), "end:", moment(end).format('yyyy-mm-dd'), thisObj.data);
console.log(begin);
console.log(end);
zoom(begin, end);
}
});
});
}
}
请在下面的图表屏幕截图中找到
Please find below the screenshot of the graph
推荐答案
添加剪切路径功能,因为数据超出了y轴.
Adding the clip path functionality because data was going beyond y axis.
private initSvg() {
d3.select("svg").remove();
this.svg = d3.select("#d3Id")
.append("svg")
.attr("width", this.width + this.margin.left + this.margin.right)
.attr("height", this.height + this.margin.top + this.margin.bottom)
.append("g")
.attr("transform",
"translate(" + this.margin.left + "," + this.margin.top + ")")
.attr("stroke-width", 2);
}
private initAxis() {
// Parse the date / time
// var parseDate = timeParse("%b %Y");
// this.formatTime = timeParse("%e %B");
// Set the ranges
this.x = d3Scale.scaleTime().range([0, this.width]);
this.y = d3Scale.scaleLinear().range([this.height, 0]);
}
private drawAxis() {
var X = this.x;
var Y = this.y;
this.xAxis = d3.axisBottom(this.x)
.ticks(5);
// var xAxis = d3.axisBottom(this.x).tickSize(-this.height).ticks(3);
// // Add the x-axis.
// this.svg.append("svg:g")
// .attr("class", "x axis")
// .attr("transform", "translate(0," + this.height + ")")
// .call(xAxis);
this.yAxis = d3.axisLeft(this.y)
.ticks(5);
// Define the line
this.priceline = d3Shape.line()
.x(function(d) {
return X(new Date(d['date']));
})
.y(function(d) {
return Y(d['peoplesum']);
});
}
private drawLine() {
if (this.data[0]['d3_parameter_maker'] === true) {
this.x.domain([1, d3.max(this.data, function(d) {
return parseInt(d['date']);
})]);
} else if (this.data[0]['d3_parameter_maker'] === undefined) {
var mindate = new Date(this.dashboard_date['startTime']),
maxdate = new Date(this.dashboard_date['endTime']);
this.x.domain([mindate, maxdate]);
}
console.log(new Date(this.dashboard_date['startTime']));
// Scale the range of the data
var svgVar = this.svg;
var pricelineVar = this.priceline;
var margin = this.margin;
var height = this.height;
let thisObj = this;
this.mouseOver = [];
let X = this.x;
let Y = this.y;
if (this.mouseFlag < 0) {
for (let i = 0; i < this.peopleInSumArr.length; i++) {
this.mouseOver[i] = true;
}
} else {
for (let i = 0; i < this.peopleInSumArr.length; i++) {
if (i !== this.mouseFlag) {
this.mouseOver[i] = false;
}
}
this.mouseOver[this.mouseFlag] = true;
}
this.y.domain([0, d3.max(this.data, function(d) {
return d['peoplesum'];
})]);
var clip = thisObj.svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("id", "clip-rect")
.attr("x", "0")
.attr("y", "0")
.attr("width", this.width)
.attr("height", this.height);
// Nest the entries by symbol
var dataNest = d3.nest()
.key(function(d) {
return d['storeid'];
})
.entries(this.data);
// set the colour scale
var color = d3.scaleOrdinal(d3.schemeCategory10);
var legendSpace = this.width / dataNest.length; // spacing for the legend
var div1 = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
dataNest.forEach(function(data, i) {
thisObj.svg.append("path")
.attr("class", "line")
.style("fill", "none")
.datum(data)
.attr("d", function(d) {
return thisObj.priceline(d.values);
})
.attr('opacity', thisObj.mouseOver !== undefined && thisObj.mouseOver[i] === true ? 1 : 0.2)
.style('cursor', 'pointer')
.style("stroke", function() { // Add the colours dynamically
return data['color'] = color(data.key);
})
.attr("stroke-width", 3)
.attr("clip-path", "url(#clip)")
.on('click', function() { // on mouse in show line, circles and text
thisObj.mouseFlag = i;
thisObj.initSvg();
thisObj.initAxis();
thisObj.drawAxis();
thisObj.drawLine();
});
// Add the scatterplot
thisObj.svg.selectAll("dot")
.data(data.values)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) {
return thisObj.x(new Date(d.date));
})
.attr("cy", function(d) {
return thisObj.y(d.peoplesum);
})
.style('cursor', 'pointer')
.on("mouseover", function(d) {
div1.transition()
.duration(200)
.style("opacity", .9);
// tslint:disable-next-line:no-unused-expression
div1.html("<b>Date: </b>" + d.date + "<br/>" + "<b>Sum: </b>" + d.peoplesum.toFixed(2))
.style('position', 'absolute')
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style('text-align', 'center')
.style('width', '100px')
.style('height', '30px')
.style('padding', '2px')
.style('font', '12px sans-serif')
.style('background-color', 'lightsteelblue')
.style('border', '0px')
.style('border-radius', '8px')
.style('cursor', 'pointer')
.style('pointer-events', 'none');
})
.on("mouseout", function(d) {
div1.transition()
.duration(500)
.style("opacity", 0);
});
// Add the X Axis
// Add the Y Axis
thisObj.svg.append("text")
.attr("x", (legendSpace / 2) + i * legendSpace) // space legend
.attr("y", height + (margin.bottom / 2) + 5)
.attr("class", "legend") // style the legend
.style('cursor', 'pointer')
.style("fill", function() { // Add the colours dynamically
return data['color'] = color(data.key);
})
.text(data.key)
.attr("stroke-width", 3)
.on('click', function() { // on mouse in show line, circles and text
thisObj.mouseFlag = i;
thisObj.initSvg();
thisObj.initAxis();
thisObj.drawAxis();
thisObj.drawLine();
});
});
// Add the X Axis
let xAxisSelection = this.svg.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0," + this.height + ")")
xAxisSelection.call(d3.axisBottom(this.x));
// Add the Y Axis
this.svg.append("g")
.attr("class", "axis")
.call(d3.axisLeft(this.y));
if (this.data[0]['d3_parameter_maker'] === undefined)
{
this.daily_Data_slider(mindate,xAxisSelection,maxdate)
}
else
{
this.hourly_Data_slider(xAxisSelection)
}
}
private daily_Data_slider(mindate,xAxisSelection,maxdate){
var svgVar = this.svg;
var pricelineVar = this.priceline;
var margin = this.margin;
var height = this.height;
let thisObj = this;
function zoom(begin, end) {
thisObj.x.domain([new Date(begin), new Date(end)]);
var t = thisObj.svg.transition().duration(0);
var size = moment(moment(end).toDate()).diff(moment(begin).toDate(), 'days');
console.log("size", size);
var step = size / 10;
var ticks = [];
const startDate = new Date(moment(begin).toDate());
for (var i = 0; i <= 10; i++) {
var xAxisDate = new Date(moment(begin).toDate())
// Add a day
xAxisDate.setDate(startDate.getDate() + i)
ticks.push(xAxisDate);
}
xAxisSelection.call(d3.axisBottom(thisObj.x.domain(d3.extent(ticks))));
// Redraw the line:
d3.selectAll("circle")
.attr("cx", function(d) {
return thisObj.x(new Date(d.date));
})
.attr("cy", function(d) {
return thisObj.y(d.peoplesum);
})
d3.selectAll(".line").attr("d", function(d) {
return thisObj.priceline(d.values);
})
}
//console.log("this.data)",this.data)
$(function() {
$("#slider-range").slider({
range: true,
min: new Date(mindate).getTime() / 1000,
max: new Date(maxdate).getTime() / 1000,
step: 86400,
values: [new Date(mindate).getTime() / 1000, new Date(maxdate).getTime() / 1000],
slide: function(event, ui) {
//console.log("ui.values[0]",ui.values)
var begin = d3.min([(new Date(ui.values[0] * 1000).toDateString()), thisObj.data.length]);
var end = new Date(ui.values[1] * 1000).toDateString(); // 0]);
//console.log("begin:", moment(begin).toDate(), "end:", moment(end).format('yyyy-mm-dd'), thisObj.data);
console.log("begin", begin);
console.log("end", end);
if (new Date(moment(moment(moment(begin).toDate()).add(10, 'days')).format("YYYY-MM-DD")) <= new Date(end)) {
zoom(begin, end);
}
}
});
});
}
这篇关于更新:基于x轴上的滑块日期更改图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!