javascript - how to create dots(scatterplot) on a line in a d3 line chart -
my code working fine, there issue first dot on line. first dot y=2 , x=1 position, other dots placed correctly. please me place first dot in correct place.
json data graph:-
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"] }];
here code regarding dot creation,
// set ranges var x = d3.time.scale().range([0, innerwidth]); var y = d3.scale.linear().range([innerheight, 0]); // scale range of 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 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]); });
update 1: full code
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 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 plot. // var margin = {top: 20, right: 80, bottom: 30, left: 50}, innerwidth = width - margin.left - margin.right, innerheight = height - margin.top - margin.bottom; // set 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 ranges var x = d3.time.scale().range([0, innerwidth]); var y = d3.scale.linear().range([innerheight, 0]); // scale range of 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; } }
update 2:
html view of created circles-(check first circle, has cx=0 , cy=0 cordinates.other circles fine)
update 3: feddle
your use of d3.extent()
d3.max()
flawed. functions provided these methods accessors; there no parameter i
actual iteration. meant means access relevant data of array, passed in first parameter. because passing in flat data arrays, both accessor function can reduced function (d) { return d; }
. these might further omitted because default behavior. domain setup becomes:
// scale range of data x.domain(d3.extent(datasets[0]['x'])); y.domain([1, d3.max(datasets[0]['y'])]);
personally, rewrite data binding logic improve readability:
// add 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]); });
instead of doing cumbersome deep access datasets
array each time need values, uses d3.zip()
build new array of arrays containing points' coordinates, bound selection. can see, leaves clean code setting cx
, cy
attribute values.
besides these technical shortcomings there logical glitch in setting y
scale's domain—as indicated andrew's comment—, doing
y.domain([1, d3.max(datasets[0]['y'])]);
in dataset provided maximum value y 2, though. way domain set [1, 2]
leaving out 3
. domain point consequently drawn @ origin. because y values categories, not want. draw full range of categories, use static values set scale's domain:
y.domain([1, 3]);
you doing way—in rather awkward way, though—for other scale y_scale
, why line drawn correctly.
of course, decide draw categories contained in dataset, in case keep d3.max()
in domain, have same y_scale
's domain.
have @ following snippet working example. contains code jsfiddle having 1 line changed, y
scale's domain set up.
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 plot. // var margin = { top: 20, right: 80, bottom: 30, left: 50 }, innerwidth = width - margin.left - margin.right, innerheight = height - margin.top - margin.bottom; // set 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 ranges var x = d3.time.scale().range([0, innerwidth]); var y = d3.scale.linear().range([innerheight, 0]); // scale range of 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 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>
Comments
Post a Comment