gpt4 book ai didi

javascript - D3.js 负值折线图

转载 作者:行者123 更新时间:2023-11-30 20:11:13 26 4
gpt4 key购买 nike

制作 d3.js 折线图。工作示例:http://jsfiddle.net/13y8ea7n/

代码:

const width = 1140

var svgWidth = width-30, svgHeight = 300

var svg = d3.select('.svg')
.attr("width", svgWidth)
.attr("height", svgHeight)
.append('g')
.attr("width", svgWidth)
.attr("height", svgHeight)

var x = d3.scaleTime()
.range([0, svgWidth-57]);

var y = d3.scaleLinear()
.range([svgHeight-50, 0]);

var valueline = d3.line()
.x((d) => {return x(d.moment)})
.y((d) => {return y(d.val_prc)})

var x_axis = d3.axisBottom(x)
.ticks(0)

var y_axis = d3.axisRight(y)
.tickSize(-width, 0)
.tickFormat((d) => {
let label = d + '%'
if (d > 0) {
label = '+' + label
}
return label
})
.tickPadding(9)
.ticks(3)

var xAxisTranslate = svgHeight - 20;

var parseTime = d3.timeParse("%Y-%m-%d");


dataset.forEach((d) => {
d.moment = parseTime(d.moment);
d.val_prc = +d.val_prc;
});

x.domain(d3.extent(dataset, function(d) { return d.moment; }));
y.domain(d3.extent(dataset, function(d) { return d.val_prc; }));

svg.append("g")
.attr('class', 'y-axis')
.attr("transform", `translate(${svgWidth-57}, 10)`)
.call(y_axis)

svg.append("g")
.attr('class', 'x-axis')
.attr("transform", `translate(0, ${xAxisTranslate})`)
.call(x_axis)

svg.append("path")
.datum(dataset)
.attr("class", "line")
.attr("d", valueline);

面临两个问题。

  1. 虽然数据集中有负值,但图表呈现在 0% 刻度以上。我是 d3 的新手,所以找不到问题,我认为这是因为 y.domain。
  2. 是否可以根据 tickValues = [-50, 0, 50, 100] 的 y 轴渲染图表?试过了,但是 -50 tick 是从 svg-container 中渲染出来的。

没有在代码片段中包含数据集,因为它太长了。它包含在 fiddle 中。

最佳答案

1. 转换图形不同部分的魔数(Magic Number)太多。看看这篇关于 margin conventions 的文章。

上述约定的目标是在您以这种方式设置之后:

all subsequent code can ignore margins.


2. 您可以使用数组对 tickValues 进行硬编码,但是您还必须对 yDomain 进行硬编码,以便它像 y 一样在 View 中。 domain([-50, 100])(与使用 d3.extent 从数据值计算域相反)。


const dataset = [{
"moment": "2018-03-14",
"val_prc": 0,
"val_rub": 651573.83
},
{
"moment": "2018-03-15",
"val_prc": -0.18,
"val_rub": 650378.16
},
{
"moment": "2018-03-16",
"val_prc": 0.93,
"val_rub": 657633.22
},
{
"moment": "2018-03-19",
"val_prc": -0.24,
"val_rub": 650012.09
},
{
"moment": "2018-03-20",
"val_prc": -0.91,
"val_rub": 645619.39
},
{
"moment": "2018-03-21",
"val_prc": -0.59,
"val_rub": 647702.98
},
{
"moment": "2018-03-22",
"val_prc": -0.39,
"val_rub": 649028.2
},
{
"moment": "2018-03-23",
"val_prc": -0.66,
"val_rub": 647251.33
},
{
"moment": "2018-03-26",
"val_prc": -1,
"val_rub": 645037.53
},
{
"moment": "2018-03-27",
"val_prc": -1.74,
"val_rub": 640242.97
},
{
"moment": "2018-03-28",
"val_prc": -0.97,
"val_rub": 645237.98
},
{
"moment": "2018-03-29",
"val_prc": -0.7,
"val_rub": 647028.82
},
{
"moment": "2018-03-30",
"val_prc": -0.44,
"val_rub": 648697.05
},
{
"moment": "2018-04-02",
"val_prc": -0.96,
"val_rub": 645328.79
},
{
"moment": "2018-04-03",
"val_prc": -1.61,
"val_rub": 641075.02
},
{
"moment": "2018-04-04",
"val_prc": -2.65,
"val_rub": 634322.06
},
{
"moment": "2018-04-05",
"val_prc": -3.01,
"val_rub": 631949.94
},
{
"moment": "2018-04-06",
"val_prc": -1.71,
"val_rub": 640405.6
},
{
"moment": "2018-04-09",
"val_prc": 21.22,
"val_rub": 789860.31
},
{
"moment": "2018-04-10",
"val_prc": 37.84,
"val_rub": 898161.44
},
{
"moment": "2018-04-11",
"val_prc": 45.28,
"val_rub": 946624.12
},
{
"moment": "2018-04-12",
"val_prc": 35.01,
"val_rub": 879713.53
},
{
"moment": "2018-04-13",
"val_prc": 35.2,
"val_rub": 880939.55
},
{
"moment": "2018-04-16",
"val_prc": 35.39,
"val_rub": 882187.37
},
{
"moment": "2018-04-17",
"val_prc": 32.97,
"val_rub": 866413.03
},
{
"moment": "2018-04-18",
"val_prc": 32.68,
"val_rub": 864526.16
},
{
"moment": "2018-04-19",
"val_prc": 32.62,
"val_rub": 864112.82
},
{
"moment": "2018-04-20",
"val_prc": 32.13,
"val_rub": 862427.04
},
{
"moment": "2018-04-23",
"val_prc": 32.34,
"val_rub": 863806.29
},
{
"moment": "2018-04-24",
"val_prc": 30.87,
"val_rub": 854187
},
{
"moment": "2018-04-25",
"val_prc": 31.72,
"val_rub": 859709.46
},
{
"moment": "2018-04-26",
"val_prc": 32.54,
"val_rub": 865102.62
},
{
"moment": "2018-04-27",
"val_prc": 31.89,
"val_rub": 860868.98
},
{
"moment": "2018-04-28",
"val_prc": 31.78,
"val_rub": 860107.7
},
{
"moment": "2018-04-30",
"val_prc": 30.45,
"val_rub": 851444.35
},
{
"moment": "2018-05-02",
"val_prc": 37.21,
"val_rub": 895592.11
},
{
"moment": "2018-05-03",
"val_prc": 33.04,
"val_rub": 868336.14
},
{
"moment": "2018-05-04",
"val_prc": 33.58,
"val_rub": 871888.06
},
{
"moment": "2018-05-07",
"val_prc": 33.31,
"val_rub": 870101.52
},
{
"moment": "2018-05-08",
"val_prc": 33.43,
"val_rub": 870868.5
},
{
"moment": "2018-05-10",
"val_prc": 33.86,
"val_rub": 873673.59
},
{
"moment": "2018-05-11",
"val_prc": 33.96,
"val_rub": 874332.19
},
{
"moment": "2018-05-14",
"val_prc": 33.66,
"val_rub": 872423.33
},
{
"moment": "2018-05-15",
"val_prc": 35.21,
"val_rub": 882485
},
{
"moment": "2018-05-16",
"val_prc": 34.82,
"val_rub": 879932.88
},
{
"moment": "2018-05-17",
"val_prc": 34.67,
"val_rub": 878996.99
},
{
"moment": "2018-05-18",
"val_prc": 34.44,
"val_rub": 877477.19
},
{
"moment": "2018-05-21",
"val_prc": 34.37,
"val_rub": 877036.83
},
{
"moment": "2018-05-22",
"val_prc": 34.89,
"val_rub": 880399.25
},
{
"moment": "2018-05-23",
"val_prc": 34.23,
"val_rub": 876134.51
},
{
"moment": "2018-05-24",
"val_prc": 33.73,
"val_rub": 872870.04
},
{
"moment": "2018-05-25",
"val_prc": 34.89,
"val_rub": 880450.96
},
{
"moment": "2018-05-28",
"val_prc": 35.34,
"val_rub": 883328.84
},
{
"moment": "2018-05-29",
"val_prc": 34,
"val_rub": 874593.61
},
{
"moment": "2018-05-30",
"val_prc": 33.72,
"val_rub": 872813.35
},
{
"moment": "2018-05-31",
"val_prc": 33.51,
"val_rub": 876391.77
},
{
"moment": "2018-06-01",
"val_prc": 32.8,
"val_rub": 871773.21
},
{
"moment": "2018-06-04",
"val_prc": 32.36,
"val_rub": 868882.57
},
{
"moment": "2018-06-05",
"val_prc": 31.86,
"val_rub": 865603.14
},
{
"moment": "2018-06-06",
"val_prc": 31.38,
"val_rub": 862410.15
},
{
"moment": "2018-06-07",
"val_prc": 31.01,
"val_rub": 860001.79
},
{
"moment": "2018-06-08",
"val_prc": 32.1,
"val_rub": 867119.14
},
{
"moment": "2018-06-09",
"val_prc": 32.11,
"val_rub": 867210.65
},
{
"moment": "2018-06-11",
"val_prc": 29.44,
"val_rub": 849674.04
},
{
"moment": "2018-06-13",
"val_prc": 28.87,
"val_rub": 845932.98
},
{
"moment": "2018-06-14",
"val_prc": 29.74,
"val_rub": 851677.78
},
{
"moment": "2018-06-15",
"val_prc": 31.87,
"val_rub": 865629.03
},
{
"moment": "2018-06-18",
"val_prc": 33.21,
"val_rub": 874410.67
},
{
"moment": "2018-06-19",
"val_prc": 33.64,
"val_rub": 877287.69
},
{
"moment": "2018-06-20",
"val_prc": 32.91,
"val_rub": 872466.43
},
{
"moment": "2018-06-21",
"val_prc": 32.85,
"val_rub": 872068.35
},
{
"moment": "2018-06-22",
"val_prc": 33.4,
"val_rub": 875676.13
},
{
"moment": "2018-06-25",
"val_prc": 32.31,
"val_rub": 868547.41
},
{
"moment": "2018-06-26",
"val_prc": 32.22,
"val_rub": 867963.93
},
{
"moment": "2018-06-27",
"val_prc": 30.72,
"val_rub": 858061.68
},
{
"moment": "2018-06-28",
"val_prc": 30.57,
"val_rub": 857086.33
},
{
"moment": "2018-06-29",
"val_prc": 30.22,
"val_rub": 854793.98
},
{
"moment": "2018-07-02",
"val_prc": 31.58,
"val_rub": 863757.63
},
{
"moment": "2018-07-03",
"val_prc": 30.17,
"val_rub": 854498.09
},
{
"moment": "2018-07-04",
"val_prc": 29.8,
"val_rub": 852030.65
},
{
"moment": "2018-07-05",
"val_prc": 31.94,
"val_rub": 866084.21
},
{
"moment": "2018-07-06",
"val_prc": 30.15,
"val_rub": 854347.97
},
{
"moment": "2018-07-09",
"val_prc": 32.03,
"val_rub": 866658.09
},
{
"moment": "2018-07-10",
"val_prc": 35.24,
"val_rub": 887733.54
},
{
"moment": "2018-07-11",
"val_prc": 34.8,
"val_rub": 884858.56
},
{
"moment": "2018-07-12",
"val_prc": 32.98,
"val_rub": 906062.03
},
{
"moment": "2018-07-13",
"val_prc": 33.34,
"val_rub": 908492.48
},
{
"moment": "2018-07-16",
"val_prc": 29.89,
"val_rub": 885030.28
},
{
"moment": "2018-07-17",
"val_prc": 30.47,
"val_rub": 888979.1
},
{
"moment": "2018-07-18",
"val_prc": 33.17,
"val_rub": 907381.08
},
{
"moment": "2018-07-19",
"val_prc": 35.41,
"val_rub": 922629.27
},
{
"moment": "2018-07-20",
"val_prc": 32.8,
"val_rub": 904840.69
},
{
"moment": "2018-07-23",
"val_prc": 30.98,
"val_rub": 892420.38
},
{
"moment": "2018-07-24",
"val_prc": 32.05,
"val_rub": 899748.46
},
{
"moment": "2018-07-25",
"val_prc": 30.42,
"val_rub": 888651.05
},
{
"moment": "2018-07-26",
"val_prc": 28.85,
"val_rub": 877920.79
},
{
"moment": "2018-07-27",
"val_prc": 27.8,
"val_rub": 870776.46
},
{
"moment": "2018-07-30",
"val_prc": 28.52,
"val_rub": 875688.2
},
{
"moment": "2018-07-31",
"val_prc": 33.52,
"val_rub": 909739.19
},
{
"moment": "2018-08-01",
"val_prc": 30.4,
"val_rub": 888473.88
},
{
"moment": "2018-08-02",
"val_prc": 33.64,
"val_rub": 910571.7
},
{
"moment": "2018-08-03",
"val_prc": 31.85,
"val_rub": 898341.67
},
{
"moment": "2018-08-06",
"val_prc": 32.87,
"val_rub": 905304.31
},
{
"moment": "2018-08-07",
"val_prc": 33.05,
"val_rub": 906551.73
},
{
"moment": "2018-08-08",
"val_prc": 47.33,
"val_rub": 1003854.58
},
{
"moment": "2018-08-09",
"val_prc": 62.09,
"val_rub": 1104377.06
},
{
"moment": "2018-08-10",
"val_prc": 75.34,
"val_rub": 1194698.92
},
{
"moment": "2018-08-13",
"val_prc": 76,
"val_rub": 1349718.79
},
{
"moment": "2018-08-14",
"val_prc": 75.18,
"val_rub": 1492738.39
},
{
"moment": "2018-08-15",
"val_prc": 76.98,
"val_rub": 1659601.6
},
{
"moment": "2018-08-16",
"val_prc": 75.56,
"val_rub": 1749486.9
},
{
"moment": "2018-08-17",
"val_prc": 75.99,
"val_rub": 1753777.09
},
{
"moment": "2018-08-20",
"val_prc": 74.99,
"val_rub": 1743844.78
},
{
"moment": "2018-08-21",
"val_prc": 72.08,
"val_rub": 1714799.41
},
{
"moment": "2018-08-22",
"val_prc": 71.95,
"val_rub": 1713480.52
},
{
"moment": "2018-08-23",
"val_prc": 70.39,
"val_rub": 1697945.78
},
{
"moment": "2018-08-24",
"val_prc": 70.91,
"val_rub": 1703157.92
},
{
"moment": "2018-08-27",
"val_prc": 70.9,
"val_rub": 1703035.57
},
{
"moment": "2018-08-28",
"val_prc": 67.12,
"val_rub": 1665359
},
{
"moment": "2018-08-29",
"val_prc": 69.21,
"val_rub": 1686236.97
},
{
"moment": "2018-08-30",
"val_prc": 66.53,
"val_rub": 1659517.35
},
{
"moment": "2018-08-31",
"val_prc": 64.7,
"val_rub": 1641262.34
},
{
"moment": "2018-09-03",
"val_prc": 64.48,
"val_rub": 1639032.05
},
{
"moment": "2018-09-04",
"val_prc": 63.87,
"val_rub": 1633016.85
},
{
"moment": "2018-09-05",
"val_prc": 63.11,
"val_rub": 1625390.21
},
{
"moment": "2018-09-06",
"val_prc": 69.13,
"val_rub": 1685415.5
},
{
"moment": "2018-09-07",
"val_prc": 66.37,
"val_rub": 1657876.09
},
{
"moment": "2018-09-10",
"val_prc": 70.6,
"val_rub": 1700074.16
},
{
"moment": "2018-09-11",
"val_prc": 67.14,
"val_rub": 1665624.56
},
{
"moment": "2018-09-12",
"val_prc": 72.01,
"val_rub": 1714120.37
},
{
"moment": "2018-09-13",
"val_prc": 72.1,
"val_rub": 1715038.65
},
{
"moment": "2018-09-14",
"val_prc": 72.11,
"val_rub": 1715078.29
},
{
"moment": "2018-09-17",
"val_prc": 71.62,
"val_rub": 1710266.45
}
]

const width = 1140
const height = 500
const margin = {
top: 30,
right: 50,
bottom: 20,
left: 10
}

const svgWidth = width - margin.left - margin.right
const svgHeight = height - margin.top - margin.bottom

const svg = d3.select('.svg')
.attr("width", width)
.attr("height", height)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)


const x = d3.scaleTime()
.range([0, svgWidth]);

const y = d3.scaleLinear()
.range([svgHeight, 0]);

const valueline = d3.line()
.x((d) => {
return x(d.moment)
})
.y((d) => {
return y(d.val_prc)
})

const x_axis = d3.axisBottom(x)
.ticks(0)

const y_axis = d3.axisRight(y)
.tickSize(-svgWidth, 0)
.tickFormat((d) => {
let label = d + '%'
if (d > 0) {
label = '+' + label
}
return label
})
.tickPadding(9)
.tickValues([-50, 0, 50, 100])

const xAxisTranslate = svgHeight - 20;

const parseTime = d3.timeParse("%Y-%m-%d");


dataset.forEach((d) => {
d.moment = parseTime(d.moment);
d.val_prc = +d.val_prc;
});

x.domain(d3.extent(dataset, function(d) {
return d.moment;
}));
y.domain([-50, 100]);

svg.append("g")
.attr('class', 'y-axis')
.attr("transform", `translate(${svgWidth}, 0)`)
.call(y_axis)

svg.append("g")
.attr('class', 'x-axis')
.attr("transform", `translate(0, ${xAxisTranslate})`)
.call(x_axis)

svg.append("path")
.datum(dataset)
.attr("class", "line")
.attr("d", valueline);
text {
fill: rgba(0, 0, 0, 0.47);
font-size: 14px;
line-height: 1;
text-anchor: start;
}

.line {
fill: none;
stroke: #c8102e;
stroke-width: 1px;
}

.y-axis path {
display: none;
}

.y-axis .tick line {
stroke: #c1c1c1;
stroke-width: 1px;
}


}
.x-axis .domain {
stroke: #c1c1c1;
stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Document</title>
</head>

<body>
<svg class="svg"></svg>
</body>

</html>

Fiddle

关于javascript - D3.js 负值折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52400579/

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