我正在尝试使用d3.js V4构建简单的折线图。 我有多个bl.ocks样本的基本概念。
我的想法是创建char然后向其添加数据,最多9个数据点。
以下是我迄今为止构建的内容:
我可以使用此更新行:
addValue: function(val) {
chartData.push(val);
if (chartData.length > 9) {
chartData.shift();
}
y.domain([
-2,
d3.max(chartData, function(d) {
return d + 2;
})
]);
var svg = element.transition();
svg
.select(".d3-line")
.duration(750)
.attr("d", valueline(chartData));
}
但是当我添加新数据时我还想添加/移动点和线,没有这个我的错误图表看起来像这样:
我正在使用此代码添加初始点和行:
var lineGuides = svg
.append("g")
.selectAll(".d3-line-guides-group")
.data(chartData);
lineGuides
.enter()
.append("line")
.attr("class", "d3-line-guides")
.attr("x1", function(t, e) {
return x(e);
})
.attr("y1", function(t, a) {
return height;
})
.attr("x2", function(t, e) {
return x(e);
})
.attr("y2", function(t, a) {
return height;
})
.style("stroke", "rgba(255,255,255,0.3)")
.style("stroke-dasharray", "4,2")
.style("shape-rendering", "crispEdges")
.transition()
.duration(1000)
.delay(function(t, x) {
return 150 * x;
})
.attr("y2", function(t) {
return y(t);
})
.transition();
var points = svg
.insert("g")
.selectAll(".d3-line-circle")
.data(chartData)
.enter()
.append("circle")
.attr("class", "d3-line-circle d3-line-circle-medium")
.attr("cx", function(t, e) {
return x(e);
})
.attr("cy", function(t) {
return y(t);
})
.attr("r", 3)
.style("stroke", "#fff")
.style("fill", "#29B6F6")
.on("mouseover", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 5);
})
.on("mouseout", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 3);
});
points
.style("opacity", 0)
.transition()
.duration(250)
.ease(d3.easeLinear, 2)
.delay(1000)
.style("opacity", 1);
如何在数据更改时添加新点并更新旧点?
这是我到目前为止的代码:
/* global window, define, module */
(function(global, factory) {
var MicroChart = factory(global);
if (typeof define === "function" && define.amd) {
// AMD support
define(function() {
return MicroChart;
});
} else if (typeof module === "object" && module.exports) {
// CommonJS support
module.exports = MicroChart;
} else {
// We are probably running in the browser
global.MicroChart = MicroChart;
}
})(typeof window === "undefined" ? this : window, function(global, undefined) {
var document = global.document;
var slice = Array.prototype.slice;
var MicroChart = (function() {
var defaultOptions = {
height: 50
};
function shallowCopy(/* source, ...targets*/) {
var target = arguments[0],
sources = slice.call(arguments, 1);
sources.forEach(function(s) {
for (k in s) {
if (s.hasOwnProperty(k)) {
target[k] = s[k];
}
}
});
return target;
}
return function MicroChart(elem, opts) {
opts = shallowCopy({}, defaultOptions, opts);
var gaugeContainer = elem,
chartHeigh = opts.height,
instance;
var xScale, yScale, valueline, x, y;
var chartData = [5, 8, 2];
var element;
function initializeMicroChart(elem, height) {
element = d3.select(elem);
var margins = { top: 0, right: 0, bottom: 0, left: 0 };
var width =
element.node().getBoundingClientRect().width -
margins.left -
margins.right;
var height = chartHeigh - margins.top - margins.bottom;
var l = 10;
x = d3
.scaleLinear()
.domain([0, 8])
.range([l, width - l]);
y = d3.scaleLinear().range([height, 0]);
valueline = d3
.line()
.x(function(d, i) {
console.log(i);
return x(i);
})
.y(function(d) {
return y(d);
});
var svg = element
.append("svg")
.attr("width", width + margins.left + margins.right)
.attr("height", height + margins.top + margins.bottom);
y.domain([
-2,
d3.max(chartData, function(d) {
return d + 2;
})
]);
var s4 =function() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
var guid = s4()+s4();
console.log(guid);
var path = svg
.append("path")
.data([chartData])
.attr("class", "d3-line d3-line-medium")
.attr("clip-path", "url(#"+guid+")")
.attr("d", valueline)
.style("stroke", "#fff");
var clipPath = svg
.append("defs")
.append("clipPath")
.attr("id", guid);
var rect = clipPath
.append("rect")
.attr("class", "clip")
.attr("width", 0)
.attr("height", height)
.attr("transform", null)
.transition()
.duration(1000)
.ease(d3.easeLinear, 2)
.attr("width", width);
var lineGuides = svg
.append("g")
.selectAll(".d3-line-guides-group")
.data(chartData);
lineGuides
.enter()
.append("line")
.attr("class", "d3-line-guides")
.attr("x1", function(t, e) {
return x(e);
})
.attr("y1", function(t, a) {
return height;
})
.attr("x2", function(t, e) {
return x(e);
})
.attr("y2", function(t, a) {
return height;
})
.style("stroke", "rgba(255,255,255,0.3)")
.style("stroke-dasharray", "4,2")
.style("shape-rendering", "crispEdges")
.transition()
.duration(1000)
.delay(function(t, x) {
return 150 * x;
})
.attr("y2", function(t) {
return y(t);
})
.transition();
var points = svg
.insert("g")
.selectAll(".d3-line-circle")
.data(chartData)
.enter()
.append("circle")
.attr("class", "d3-line-circle d3-line-circle-medium")
.attr("cx", function(t, e) {
return x(e);
})
.attr("cy", function(t) {
return y(t);
})
.attr("r", 3)
.style("stroke", "#fff")
.style("fill", "#29B6F6")
.on("mouseover", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 5);
})
.on("mouseout", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 3);
});
points
.style("opacity", 0)
.transition()
.duration(250)
.ease(d3.easeLinear, 2)
.delay(1000)
.style("opacity", 1);
}
instance = {
addValue: function(val) {
chartData.push(val);
if (chartData.length > 9) {
chartData.shift();
}
y.domain([
-2,
d3.max(chartData, function(d) {
return d + 2;
})
]);
var svg = element.transition();
svg
.select(".d3-line")
.duration(750)
.attr("d", valueline(chartData));
}
};
initializeMicroChart(gaugeContainer, chartHeigh);
return instance;
};
})();
return MicroChart;
});
var gauge1 = MicroChart(document.getElementById("chart1"));
var gauge2 = MicroChart(document.getElementById("chart2"), {
height: 70
});
var randomInt = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
$("#update").on("click", function() {
gauge1.addValue(randomInt(5, 15));
gauge2.addValue(randomInt(5, 15));
});
以下是代码,以查看我的代码:https://codepen.io/Misiu/pen/dmGyZW?editors=0010
答案 0 :(得分:2)
使用.enter().append()
添加新节点.merge()
以合并现有节点和附加节点,然后更新所有节点并调用.exit().remove()
以删除不必要的节点。因此,您可以使用以下更新模式:
d3.select(window).on('load', function() {
// Join data
var joined = d3.select('div').selectAll('p').data([1, 2, 3, 4, 5]);
joined
// Add new elements
.enter().append('p')
// Merge both new and existing elements
.merge(joined)
// Update new and existing elements
.text(d => d);
// Remove excess elements
joined.exit().remove();
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<div>
<p>a</p>
<p>b</p>
<p>c</p>
</div>
结果,将创建两个<p>
元素,并且将更新所有<p>
元素。