gpt4 book ai didi

javascript - 如何在 d3 折线图中的线上创建点(散点图)

转载 作者:行者123 更新时间:2023-12-01 04:09:56 26 4
gpt4 key购买 nike

我的代码工作正常,但该行的第一个点有问题。第一个点总是获得 y=2 和 x=1 的位置,但其他点放置正确。请帮我将第一个点放在正确的位置。

图表:- enter image description here

图表的 JSON 数据:-

  var data = [{
"label": "Execution: 6 - defadmin@gmail.com",
"x": [1, 2, 3, 4, 5, 6],
"y": [2, 1, 1, 1, 1, 1],
"xAxisDisplayData": ["1", "2", "3", "4", "5", "6"]
}];

这是我关于点创建的代码,

  // Set the ranges
var x = d3.time.scale().range([0, innerwidth]);
var y = d3.scale.linear().range([innerheight, 0]);

// Scale the range of the data
x.domain(d3.extent(datasets[0]['x'], function (d, i) {

return datasets[0]['x'][i];
}));
y.domain([1, d3.max(datasets[0]['y'], function (d, i) {
return datasets[0]['y'][i];
})]);

// Add the scatterplot
svg.selectAll("dot")
.data(datasets[0]['x'])
.enter().append("circle")
.attr("r", 3.5)
.attr("cx", function (d, i) {
return x(datasets[0]['x'][i]);
})
.attr("cy", function (d, i) {

return y(datasets[0]['y'][i]);
});

更新1:完整代码

                        function createLineChart(data, number) {

// var data = [ { label: "Execution 1 - buddhika@gmail.com",
// x: [1,2,3,4,5,6],
// y: [2,1,1,1,1,1] }] ;


var widthForSVG;
var widthForChart;

if ((data[0]['x']).length < 13) {

widthForSVG = 1220;
widthForChart = 960;

} else {


widthForSVG = (((data[0]['x']).length - 12) * 80) + 1220;
widthForChart = (((data[0]['x']).length - 12) * 80) + 960;

}


var xy_chart = d3_xy_chart()
.width(widthForChart)
.height(500)
.xlabel("TCS")
.ylabel("STATUS");


// creating main svg
var svg = d3.select(".lineChartDiv" + number).append("svg")
.datum(data)
.call(xy_chart)
.attr("class", "lineChart" + number)
.attr('width', widthForSVG);


function d3_xy_chart() {
//1220px for 12 steps in svg
var width = widthForChart,
height = 480,
xlabel = "X Axis Label",
ylabel = "Y Axis Label";


function chart(selection, svg) {

var numberNUmber = 0;
selection.each(function (datasets) {
//
// Create the plot.
//


var margin = {top: 20, right: 80, bottom: 30, left: 50},
innerwidth = width - margin.left - margin.right,
innerheight = height - margin.top - margin.bottom;


// Set the ranges



var x_scale = d3.scale.linear()
.range([0, innerwidth])
.domain([d3.min(datasets, function (d) {


return d3.min(d.x);
}),
d3.max(datasets, function (d) {

return d3.max(d.x);
})]);


var y_scale = d3.scale.linear()
.range([innerheight, 0])
.domain([d3.min(datasets, function (d) {

return 1;
}),
d3.max(datasets, function (d) {
// d3.max(d.y)
return 3;
})]);

var color_scale = d3.scale.category10()
.domain(d3.range(datasets.length));

var x_axis = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickFormat(function (d, i) {


if (d % 1 == 0) {

return parseInt(datasets[0]['xAxisDisplayData'][i])

} else {

return " "

}

})
.ticks(d3.max(datasets, function (d) {

return d3.max(d.x);
}));



var y_axis = d3.svg.axis()
.scale(y_scale)
.orient("left")
.ticks(d3.max(datasets, function (d) {

return d3.max(d.y);
}))
.tickFormat(function (d, i) {


if (d == "1") {

return "NOT EXECUTED"

} else if (d == "2") {

return "FAILED"

} else if (d == "3") {

return "PASSED"

} else {

return " "

}

});

var x_grid = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickSize(-innerheight)
.ticks(d3.max(datasets, function (d) {
// d3.max(d.y)
return d3.max(d.x);
}))
.tickFormat("");

var y_grid = d3.svg.axis()
.scale(y_scale)
.orient("left")
.tickSize(-innerwidth)
.tickFormat("")
.ticks(d3.max(datasets, function (d) {

return d3.max(d.y);
}));

var draw_line = d3.svg.line()
.interpolate("linear")
.x(function (d) {

return x_scale(d[0]);
})
.y(function (d) {

return y_scale(d[1]);
});

var svg = d3.select(this)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 90 + "," + margin.top + ")");

svg.append("g")
.attr("class", "x grid")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_grid);

svg.append("g")
.attr("class", "y grid")
.call(y_grid);

svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_axis)
.append("text")
.attr("dy", "-.71em")
.attr("x", innerwidth)
.style("text-anchor", "end")
.text(xlabel);

svg.append("g")
.attr("class", "y axis")
.call(y_axis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text(ylabel);


var data_lines = svg.selectAll(".d3_xy_chart_line")
.data(datasets.map(function (d) {

return d3.zip(d.x, d.y);
}))
.enter().append("g")
.attr("class", "d3_xy_chart_line");


data_lines.append("path")
.attr("class", "line")
.attr("d", function (d) {

return draw_line(d);
})
.attr("stroke", function (_, i) {
return color_scale(i);
});

data_lines.append("text")
.datum(function (d, i) {
return {name: datasets[i].label, final: d[d.length - 1]};
})
.attr("transform", function (d) {
return ( "translate(" + x_scale(d.final[0]) + "," +
y_scale(d.final[1]) + ")" );
})
.attr("x", 3)
.attr("dy", ".35em")
.attr("fill", function (_, i) {
return color_scale(i);
})
.text(function (d) {
return d.name;
});


// Set the ranges
var x = d3.time.scale().range([0, innerwidth]);
var y = d3.scale.linear().range([innerheight, 0]);


// Scale the range of the data
x.domain(d3.extent(datasets[0]['x']));
y.domain([1, d3.max(datasets[0]['y'])]);

svg.selectAll("dot")
.data(d3.zip(datasets[0].x, datasets[0].y))
.enter().append("circle")
.attr("r", 3.5)
.attr("cx", function (d) {
return x(d[0]);
})
.attr("cy", function (d) {
return y(d[1]);
});



});
}

chart.width = function (value) {
if (!arguments.length) return width;
width = value;
return chart;
};

chart.height = function (value) {
if (!arguments.length) return height;
height = value;
return chart;
};

chart.xlabel = function (value) {
if (!arguments.length) return xlabel;
xlabel = value;
return chart;
};

chart.ylabel = function (value) {
if (!arguments.length) return ylabel;
ylabel = value;
return chart;
};

return chart;
}


}

更新2:

创建的圆圈的 html View -(检查第一个圆圈,它始终具有 cx=0 和 cy=0 坐标。其他圆圈都可以)

enter image description here

更新3:fiddle

feddle

最佳答案

您对d3.extent()的使用以及 d3.max()是有缺陷的。提供给这些方法的函数只是访问器;没有参数i用于实际迭代。它们是实际访问数组相关数据的一种方法,数组作为第一个参数传入。因为您已经传入平面数据数组,所以两个访问器函数都可以减少为 function (d) { return d; } 。这些可能会被进一步省略,因为这是默认行为。您的域设置因此变为:

// Scale the range of the data
x.domain(d3.extent(datasets[0]['x']));
y.domain([1, d3.max(datasets[0]['y'])]);

就我个人而言,我还会重写您的数据绑定(bind)逻辑以提高可读性:

// Add the scatterplot
svg.selectAll("dot")
.data(d3.zip(datasets[0].x, datasets[0].y))
.enter().append("circle")
.attr("r", 3.5)
.attr("cx", function (d) {
return x(d[0]);
})
.attr("cy", function (d) {
return y(d[1]);
});

而不是对 datasets 进行繁琐的深度访问每次需要这些值时,都会使用 d3.zip() 数组构建一个包含点坐标的新数组,然后将其绑定(bind)到选择。如您所见,这为您提供了干净的代码来设置 cxcy属性值。

除了这些技术缺陷之外,设置 y 时还存在逻辑故障。尺度域—如安德鲁 comment 所示—,你在哪里做什么

y.domain([1, d3.max(datasets[0]['y'])]);

不过,在您提供的数据集中,y 的最大值为 2。这样您的域名将被设置为 [1, 2]省略 3 。有了这个域,点就会被绘制在原点。因为你的 y 值是类别,这显然不是你想要的。要始终绘制完整的类别范围,您可以使用静态值来设置比例域:

y.domain([1, 3]);

对于您的其他规模 y_scale,您已经这样做了(尽管方式相当尴尬) ,这就是正确绘制线条的原因。

当然,您也可以决定仅绘制数据集中包含的类别,在这种情况下,您将保留 d3.max()在域中,但您还必须对您的 y_scale 执行相同的操作的域名。

看看下面的代码片段,了解一个工作示例。它包含来自 JSFiddle 的代码,仅更改了一行,其中 y秤的域已设置。

var data = [{
"label": "Execution: 6 - defadmin@gmail.com",
"x": [1, 2, 3, 4, 5, 6],
"y": [2, 1, 1, 1, 1, 1],
"xAxisDisplayData": ["1", "2", "3", "4", "5", "6"]
}];

var number = 1;

var widthForSVG;
var widthForChart;

if ((data[0]['x']).length < 13) {

widthForSVG = 1220;
widthForChart = 960;

} else {


widthForSVG = (((data[0]['x']).length - 12) * 80) + 1220;
widthForChart = (((data[0]['x']).length - 12) * 80) + 960;

}


var xy_chart = d3_xy_chart()
.width(widthForChart)
.height(500)
.xlabel("TCS")
.ylabel("STATUS");


// creating main svg
var svg = d3.select(".lineChartDiv1").append("svg")
.datum(data)
.call(xy_chart)
.attr("class", "lineChartDiv1")
.attr('width', widthForSVG);





function d3_xy_chart() {

var width = widthForChart,
height = 480,
xlabel = "X Axis Label",
ylabel = "Y Axis Label";


function chart(selection, svg) {

var numberNUmber = 0;
selection.each(function(datasets) {
//
// Create the plot.
//


var margin = {
top: 20,
right: 80,
bottom: 30,
left: 50
},
innerwidth = width - margin.left - margin.right,
innerheight = height - margin.top - margin.bottom;


// Set the ranges



var x_scale = d3.scale.linear()
.range([0, innerwidth])
.domain([d3.min(datasets, function(d) {


return d3.min(d.x);
}),
d3.max(datasets, function(d) {

return d3.max(d.x);
})
]);


var y_scale = d3.scale.linear()
.range([innerheight, 0])
.domain([d3.min(datasets, function(d) {

return 1;
}),
d3.max(datasets, function(d) {
// d3.max(d.y)
return 3;
})
]);

var color_scale = d3.scale.category10()
.domain(d3.range(datasets.length));

var x_axis = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickFormat(function(d, i) {


if (d % 1 == 0) {

return parseInt(datasets[0]['xAxisDisplayData'][i])

} else {

return " "

}

})
.ticks(d3.max(datasets, function(d) {

return d3.max(d.x);
}));



var y_axis = d3.svg.axis()
.scale(y_scale)
.orient("left")
.ticks(d3.max(datasets, function(d) {

return d3.max(d.y);
}))
.tickFormat(function(d, i) {


if (d == "1") {

return "NOT EXECUTED"

} else if (d == "2") {

return "FAILED"

} else if (d == "3") {

return "PASSED"

} else {

return " "

}

});

var x_grid = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickSize(-innerheight)
.ticks(d3.max(datasets, function(d) {
// d3.max(d.y)
return d3.max(d.x);
}))
.tickFormat("");

var y_grid = d3.svg.axis()
.scale(y_scale)
.orient("left")
.tickSize(-innerwidth)
.tickFormat("")
.ticks(d3.max(datasets, function(d) {

return d3.max(d.y);
}));

var draw_line = d3.svg.line()
.interpolate("linear")
.x(function(d) {

return x_scale(d[0]);
})
.y(function(d) {

return y_scale(d[1]);
});

var svg = d3.select(this)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 90 + "," + margin.top + ")");

svg.append("g")
.attr("class", "x grid")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_grid);

svg.append("g")
.attr("class", "y grid")
.call(y_grid);

svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_axis)
.append("text")
.attr("dy", "-.71em")
.attr("x", innerwidth)
.style("text-anchor", "end")
.text(xlabel);

svg.append("g")
.attr("class", "y axis")
.call(y_axis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text(ylabel);


var data_lines = svg.selectAll(".d3_xy_chart_line")
.data(datasets.map(function(d) {

return d3.zip(d.x, d.y);
}))
.enter().append("g")
.attr("class", "d3_xy_chart_line");


data_lines.append("path")
.attr("class", "line")
.attr("d", function(d) {

return draw_line(d);
})
.attr("stroke", function(_, i) {
return color_scale(i);
});

data_lines.append("text")
.datum(function(d, i) {
return {
name: datasets[i].label,
final: d[d.length - 1]
};
})
.attr("transform", function(d) {
return ("translate(" + x_scale(d.final[0]) + "," +
y_scale(d.final[1]) + ")");
})
.attr("x", 3)
.attr("dy", ".35em")
.attr("fill", function(_, i) {
return color_scale(i);
})
.text(function(d) {
return d.name;
});


// Set the ranges
var x = d3.time.scale().range([0, innerwidth]);
var y = d3.scale.linear().range([innerheight, 0]);


// Scale the range of the data
x.domain(d3.extent(datasets[0]['x']));
y.domain([1, 3]);

// console.log(JSON.stringify(d3.extent(datasets[0]['x'])))
// console.log(JSON.stringify(d3.max(datasets[0]['y'])))

// Add the scatterplot

svg.selectAll("dot")
.data(d3.zip(datasets[0].x, datasets[0].y))
.enter().append("circle")
.attr("class", datasets[0]['label'])
.attr("r", 3.5)
.attr("cx", function(d) {

// console.log(JSON.stringify(d[0])+" XXXXXXXXXXx ")

return x(d[0]);


})
.attr("cy", function(d) {
//console.log(JSON.stringify(d[1])+" YYYYYYYyy ")
return y(d[1]);
});



});
}

chart.width = function(value) {
if (!arguments.length) return width;
width = value;
return chart;
};

chart.height = function(value) {
if (!arguments.length) return height;
height = value;
return chart;
};

chart.xlabel = function(value) {
if (!arguments.length) return xlabel;
xlabel = value;
return chart;
};

chart.ylabel = function(value) {
if (!arguments.length) return ylabel;
ylabel = value;
return chart;
};

return chart;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.grid path,
.grid line {
fill: none;
stroke: rgba(0, 0, 0, 0.25);
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke-width: 2.5px;
}
svg {
font: 10px sans-serif;
}
.area {
fill: lightgray;
clip-path: url(#clip);
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
clip-path: url(#clip);
}
rect.pane {
cursor: move;
fill: none;
pointer-events: all;
}
<script src="https://d3js.org/d3.v3.js"></script>
<div class="row">
<div class="col-sm-12">
<div class="lineChartDiv1" style=" overflow-x: scroll">

</div>
</div>
</div>

关于javascript - 如何在 d3 折线图中的线上创建点(散点图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41577353/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com