我正在使用d3.js来显示多个折线图。
我有两个数据阵列要比较,首先我使用x轴(底部),第二个 - x2轴(顶部)。 但我在这里遇到了一些错误。看起来像这样
线路方向完全错误。
有谁知道我应该在哪里找到这种行为的原因?
代码在这里
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 = parseInt($('.page .container').outerWidth())*0.75 - MARGINS.left - MARGINS.right -45,
HEIGHT = parseInt($('#visualisation').outerHeight()) - MARGINS.top - MARGINS.bottom;
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]);
xScale.domain(d3.extent(data.xAxis, function(d) { return parseTime(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) {
x2Scale.domain(d3.extent(dataArray.nodes2.xAxis, function(d) { return parseTime(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) {
return zLineGen(row.items)
} else {
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) {
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]);
};
}
数据在这里
{
"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-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)"
},
{
"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)"
}
],
"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-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)"
},
{
"from": "2017-01-30",
"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": "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)"
},
{
"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)"
}
],
"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"
}
]
}
}
答案 0 :(得分:1)
在您的数据中,nodes2.data
未正确排序。 d3
不会为您排序数据,而是根据情况对其进行绘制。
这是一个正在运行的样本,数据已正确排序:
<!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>
&#13;