score:1
Accepted answer
In your data, nodes2.data
is not sorted properly. d3
will not sort your data for you, it'll plot it as it's given.
Here's a running sample with the data properly sorted:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg id="visualisation" width="900" height="900"></svg>
<script>
var data = {
"nodes": {
"data": [{
"name": "sum_ordered",
"items": [{
"from": "2017-03-01",
"sum_ordered": "3",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}, {
"from": "2017-03-06",
"sum_ordered": "5",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}, {
"from": "2017-03-10",
"sum_ordered": "116",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}, {
"from": "2017-03-20",
"sum_ordered": "51",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}],
"price": false
}, {
"name": "sum_income",
"items": [{
"from": "2017-03-01",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}, {
"from": "2017-03-06",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}, {
"from": "2017-03-10",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}, {
"from": "2017-03-20",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}],
"price": false
}, {
"name": "sum_sales_by_payment",
"items": [{
"from": "2017-03-01",
"sum_sales_by_payment": "7",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}, {
"from": "2017-03-06",
"sum_sales_by_payment": "5",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}, {
"from": "2017-03-10",
"sum_sales_by_payment": "53",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}, {
"from": "2017-03-20",
"sum_sales_by_payment": "18",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}],
"price": false
}],
"xAxis": [
"2017-03-20",
"2017-03-20",
"2017-03-20",
"2017-03-20",
"2017-03-10",
"2017-03-10",
"2017-03-10",
"2017-03-10",
"2017-03-06",
"2017-03-06",
"2017-03-06",
"2017-03-06",
"2017-03-01",
"2017-03-01",
"2017-03-01",
"2017-03-01"
],
"yAxis": [
"116",
"53",
"51",
"18",
"7",
"5",
"5",
"3",
"0",
"0",
"0",
"0"
],
"zAxis": [],
"x2Domain": {
"from": "2017-03-01",
"to": "2017-03-20"
},
"colors": [
"#19c2ff",
"#ff9019",
"#6fc522",
"#e95fcd",
"#a02424",
"#6a56c1",
"#4fc494",
"#ffd324",
"#ff78be"
],
"options": [{
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)",
"color": "#19c2ff",
"id": "sum_ordered"
}, {
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)",
"color": "#ff9019",
"id": "sum_income"
}, {
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)",
"color": "#6fc522",
"id": "sum_sales_by_payment"
}]
},
"nodes2": {
"data": [{
"name": "sum_ordered",
"items": [{
"from": "2017-01-30",
"sum_ordered": "2",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}, {
"from": "2017-03-01",
"sum_ordered": "19",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}, {
"from": "2017-03-09",
"sum_ordered": "1",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}, {
"from": "2017-03-10",
"sum_ordered": "15",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)"
}],
"price": false
}, {
"name": "sum_income",
"items": [{
"from": "2017-01-30",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}, {
"from": "2017-03-01",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}, {
"from": "2017-03-09",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}, {
"from": "2017-03-10",
"sum_income": "0",
"price": false,
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)"
}],
"price": false
}, {
"name": "sum_sales_by_payment",
"items": [{
"from": "2017-01-30",
"sum_sales_by_payment": "1",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}, {
"from": "2017-03-01",
"sum_sales_by_payment": "5",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}, {
"from": "2017-03-09",
"sum_sales_by_payment": "0",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}, {
"from": "2017-03-10",
"sum_sales_by_payment": "11",
"price": false,
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)"
}],
"price": false
}],
"xAxis": [
"2017-03-10",
"2017-03-10",
"2017-03-10",
"2017-03-10",
"2017-03-09",
"2017-03-09",
"2017-03-09",
"2017-03-09",
"2017-03-01",
"2017-03-01",
"2017-03-01",
"2017-03-01",
"2017-01-30",
"2017-01-30",
"2017-01-30",
"2017-01-30"
],
"yAxis": [
"19",
"15",
"11",
"5",
"2",
"1",
"1",
"0",
"0",
"0",
"0",
"0"
],
"zAxis": [],
"x2Domain": {
"from": "2017-01-30",
"to": "2017-03-10"
},
"colors": [
"#19c2ff",
"#ff9019",
"#6fc522",
"#e95fcd",
"#a02424",
"#6a56c1",
"#4fc494",
"#ffd324",
"#ff78be"
],
"options": [{
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u0417\\u0430\\u043a\\u0430\\u0437\\u0430\\u043d\\u043e (\\u0448\\u0442)",
"color": "#19c2ff",
"id": "sum_ordered"
}, {
"label": "\\u041f\\u043e\\u0441\\u0442\\u0443\\u043f\\u043b\\u0435\\u043d\\u0438\\u044f (\\u0448\\u0442)",
"color": "#ff9019",
"id": "sum_income"
}, {
"label": "\\u0412\\u0441\\u0435\\u0433\\u043e \\u041f\\u0440\\u043e\\u0434\\u0430\\u0436\\u0438 \\u043f\\u043e \\u043e\\u043f\\u043b\\u0430\\u0442\\u0430\\u043c (\\u0448\\u0442)",
"color": "#6fc522",
"id": "sum_sales_by_payment"
}]
}
}
chart(data, ['red', 'green', 'blue', 'orange'])
function chart(dataArray, colors) {
var data = dataArray.nodes;
// console.log(dataArray.nodes2)
//$('#visualisation').empty();
//$('.no-data').hide();
var MARGINS = {
top: 20,
right: 20,
bottom: 30,
left: 30
},
WIDTH = 600,
HEIGHT = 600;
var canvas = d3.select("#visualisation");
var parseTime = d3.timeParse("%Y-%m-%d");
var yDomain = [d3.min(data.yAxis, function(d) {
return Math.min(d)
}), d3.max(data.yAxis, function(d) {
return Math.max(d);
})];
// var yDomain = [d3.min(dataArray.nodes2.yAxis, function(d) {return Math.min(d)}), d3.max(dataArray.nodes2.yAxis, function(d) {return Math.max(d);})];
var zDomain = [d3.min(data.zAxis, function(d) {
return Math.min(d)
}), d3.max(data.zAxis, function(d) {
return Math.max(d);
})];
xScale = d3.scaleTime().range([0, WIDTH]);
x2Scale = d3.scaleTime().range([0, WIDTH]);
yScale = d3.scaleLinear().range([HEIGHT, 0]);
zScale = d3.scaleLinear().range([HEIGHT, 0]);
for (var i = 0; i < data.xAxis.length; i++) {
data.xAxis[i] = parseTime(data.xAxis[i]);
}
data.xAxis.sort();
// console.log(data.xAxis)
xScale.domain(d3.extent(data.xAxis, function(d) {
return d;
}));
yScale.domain(yDomain);
zScale.domain(zDomain);
xAxis = d3.axisBottom()
.scale(xScale)
.ticks(10)
.tickSizeInner(-HEIGHT)
.tickPadding(10)
.tickSizeOuter(0);
yAxis = d3.axisLeft()
.scale(yScale)
.tickSizeInner(-WIDTH)
.tickPadding(10)
.tickSizeOuter(0)
.ticks(15);
zAxis = d3.axisLeft()
.scale(zScale)
.ticks(10)
vis = canvas.append("svg:g")
.attr("transform", "translate(25,25)")
vis.append("svg:g")
.call(zAxis)
.attr("transform",
"translate(" + (WIDTH + 30) + ",0)")
.attr('y', 120 - MARGINS.left);
vis.append("svg:g")
.attr('class', 'line-transparent')
.attr("width", WIDTH + MARGINS.left + MARGINS.right)
.attr("height", HEIGHT + MARGINS.top + MARGINS.bottom)
.attr("transform", "translate(25," + HEIGHT + ")")
.call(xAxis);
vis.append("svg:g")
.call(yAxis)
.attr('class', 'line-transparent')
.attr("transform",
"translate(" + MARGINS.left + ",0)")
.attr('y', 20 - MARGINS.left);
var zLineGen = d3.line()
.x(function(d) {
return xScale(parseTime(d.from)) + 30;
})
.y(function(d, name) {
var names = Object.keys(d);
return zScale(d[names[1]]);
});
if (dataArray.nodes2) {
for (var i = 0; i < dataArray.nodes2.xAxis.length; i++) {
dataArray.nodes2.xAxis[i] = parseTime(dataArray.nodes2.xAxis[i]);
}
dataArray.nodes2.xAxis.sort();
// console.log(dataArray.nodes2.xAxis)
x2Scale.domain(d3.extent(dataArray.nodes2.xAxis, function(d) {
return d;
}));
x2Axis = d3.axisTop()
.scale(x2Scale)
vis.append("svg:g")
.attr('class', 'line-transparent')
.attr("width", WIDTH + MARGINS.left + MARGINS.right)
.attr("height", HEIGHT + MARGINS.top + MARGINS.bottom)
.attr("transform", "translate(25,0)")
// .attr('y', 0)
.call(x2Axis);
makeLines(vis, dataArray.nodes2, 2)
//makeLabels(dataArray.nodes2.options, 1, dataArray.nodes2.colors)
//TODO separate it to function
var line2 = vis.selectAll('.scale_2')
.data(dataArray.nodes2.data);
line2.each(function(d) {
d.items.forEach(function(r) {
var newNode = vis.append('g');
newNode
.attr('class', 'chart-dot')
.append('text')
.attr('x', function(el) {
var names = Object.keys(r);
var text = r.label + ': ' + r[names[1]];
var tWidth = getTextWidth(text, 10, 'Arial');
if (x2Scale(parseTime(r.from)) > WIDTH / 2) {
return x2Scale(parseTime(r.from)) - (tWidth + 10)
} else {
return x2Scale(parseTime(r.from)) + 30
}
})
.attr('y', function() {
var names = Object.keys(r);
if (r.price == true) {
return zScale(r[names[1]]);
} else {
return yScale(r[names[1]]);
}
})
.attr('font-size', '10')
.attr('class', 'chart-dot-text')
.text(function() {
var names = Object.keys(r);
//return r.from + ' - ' + r.label + ': ' + r[names[1]];
});
newNode.append('circle')
.attr('cx', function() {
return x2Scale(parseTime(r.from)) + 30
})
.attr('cy', function() {
var names = Object.keys(r);
if (r.price == true) {
return zScale(r[names[1]]);
} else {
return yScale(r[names[1]]);
}
})
.attr('r', 5)
})
})
//
}
makeLines(vis, data, 1)
var line = vis.selectAll('.scale_1')
.data(data.data);
line.each(function(d) {
d.items.forEach(function(r) {
var newNode = vis.append('g');
newNode
.attr('class', 'chart-dot')
.append('text')
.attr('x', function(el) {
var names = Object.keys(r);
var text = r.label + ': ' + r[names[1]];
var tWidth = getTextWidth(text, 10, 'Arial');
if (xScale(parseTime(r.from)) > WIDTH / 2) {
return xScale(parseTime(r.from)) - (tWidth + 10)
} else {
return xScale(parseTime(r.from)) + 30
}
})
.attr('y', function() {
var names = Object.keys(r);
if (r.price == true) {
return zScale(r[names[1]]);
} else {
return yScale(r[names[1]]);
}
})
.attr('font-size', '10')
.attr('class', 'chart-dot-text')
.text(function() {
var names = Object.keys(r);
//return r.label + ': ' + r[names[1]];
});
newNode.append('circle')
.attr('cx', function() {
return xScale(parseTime(r.from)) + 30
})
.attr('cy', function() {
var names = Object.keys(r);
if (r.price == true) {
return zScale(r[names[1]]);
} else {
return yScale(r[names[1]]);
}
})
.attr('r', 5)
})
})
function makeLines(vis, data, scale) {
var i = 0;
data.data.forEach(function(row) {
if (scale == 1) {
var stroke = colors[i];
} else {
var stroke = colors[(colors.length - 1) - i]
}
vis.append('svg:path')
.attr('d', function(d) {
if (row.price == true) {
console.log(row.items)
return zLineGen(row.items)
} else {
console.log(row.items)
return lineGen(row.items, scale);
}
})
.attr('stroke', stroke)
.attr('stroke-width', 2)
.attr('id', function() {
if (scale == 1) {
return row.name
} else {
return row.name + '_comparison'
}
})
.attr('fill', 'none')
.attr('class', 'chart-line scale_' + scale)
.attr('data-scale', scale)
.on('mousemove', function(d) {
var x = xScale.invert(d3.mouse(this)[0]);
var y = yScale.invert(d3.mouse(this)[1]);
});
i++;
});
}
function lineGen(s, scale) {
// console.log(scale)
if (scale == 1) {
var newlineGen = d3.line()
.x(function(d) {
return xScale(parseTime(d.from)) + 30;
})
.y(function(d, name) {
var names = Object.keys(d);
return yScale(d[names[1]]);
});
} else {
var newlineGen = d3.line()
.x(function(d, x) {
//console.log(d)
return x2Scale(parseTime(d.from)) + 30;
})
.y(function(d, name) {
var names = Object.keys(d);
return yScale(d[names[1]]);
});
}
return newlineGen(s)
}
function getTextWidth(text, fontSize, fontFace) {
var a = document.createElement('canvas');
var b = a.getContext('2d');
b.font = fontSize + 'px ' + fontFace;
return b.measureText(text).width;
}
function mousemove() {
var x0 = xScale.invert(d3.mouse(this)[0]);
var y0 = yScale.invert(d3.mouse(this)[1]);
};
}
</script>
</body>
</html>
Source: stackoverflow.com
Related Query
- D3.js wrong line chart direction
- D3 line chart giving wrong values at highest number
- D3.js line chart using the wrong keys when using general update pattern
- my d3 line chart looks weird, I can't figure out what's wrong
- D3.js: Wrong position of horizontal and vertical focus lines (crosshairs) in line chart
- NVD3 Cumulative line chart displays wrong y values
- d3js Multiple Stacked Bar Chart Line Cursor Appearing in Wrong Chart
- nvd3 line chart with string values on x-axis
- Draggable line chart in R/Shiny
- D3.JS time-series line chart with real-time data, panning and zooming
- d3 Line Chart Filling at Arbitrary Line
- Multiseries line chart with mouseover tooltip
- D3 line chart axis text labels in multi line
- NVD3 - line chart NaN on safari using latest versions
- NVD3 line chart with realtime data
- javascript charting - nvd3 line chart with two Y-axis
- D3.js: Line chart - tooltip and vertical line of hover
- NVD3 Line Chart Uncaught TypeError: Cannot read property 'x' of undefined
- Solid and dashed line in D3 line chart
- d3 Line Chart with enter-update-exit logic
- D3 multi-series line chart from pivoted JSON
- Draw a vertical line representing the current date in d3 gantt chart
- typescript line chart d3
- d3js line chart error - drawing weird area
- NVD3 line chart with vertical line
- dc.js Series Chart multi line
- nvd3.js-Line Chart with View Finder: rotate axis labels and show line values when mouse over
- NVD3 Line Chart X Axis Ticks Are Missing
- Adding a horizontal line to d3 graph displays at the wrong value
- D3.js combining bar and line chart
More Query from same tag
- Uncaught SyntaxError: Unexpected token with mouseover event in D3 Treemap
- d3.js, is it possible to append hyperlinks to GeoJSON file?
- Proper Convention for Injecting D3 into AngualrJS
- Creating a visualization with observations randomly generated over the entire area of a plot
- Setting x.domain with setInterval
- d3.js - Object doesn't support property or method 'map'
- Using XML as a datasource in d3js layout doesn't work in firefox
- bootstrap dropdown doesn't work inside svg?
- How to draw lines between 2 or more points ? (Points can be changed dynamically)
- D3.js graph shows up as text
- Issue with D3 zoomable treemap
- How to use D3 inside a ui-view state
- D3.js: Load flat 1-dimensional array via d3.csv results in "TypeError: groupData is undefined" / Load multiple CSV files with D3.js
- Sort Div Whit d3js html5
- State of SVG Performance on iOS and other Tablets?
- arcTween donut transition doesn't work in angular 4 when updating the chart
- Visualize data count in d3
- Filling two overlapping areas in d3.js
- Using large JSON files with d3.js causes massive performance hits/crashes
- d3.js pie-chart is truncated
- D3 linegraph using JSON data from API
- D3 Gradient starting point
- Not able to center D3 pie chart
- How to use highchart boost library with D3?
- D3 adding two donut charts on top of each other.
- D3 Selecting an element inside an SVG
- Displaying labels on horizontal chart with d3.js
- scale incoming metric data for representation in cubism
- Background image to SVG choropleth map using D3
- Why do the mouseenter/mouseleave events fire when entering/leaving child elements in an SVG?