Кодирование с тазобедренного сустава было бы примерно таким:
java.lang.reflect.Method method;
try {
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) { ... }
catch (NoSuchMethodException e) { ... }
Параметры идентифицируют очень специфический вам метод (если есть несколько перегруженных доступных, если метод не имеет аргументов, methodName
).
Затем вы вызываете этот метод, вызывая
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) { ... }
catch (IllegalAccessException e) { ... }
catch (InvocationTargetException e) { ... }
. Опять же, оставьте аргументы в .invoke
, если у вас их нет. Но да. Читайте о Java Reflection
Проблема с вашим вопросом не имеет ничего общего с программированием, JavaScript или D3 ... проблема является базовой концепцией dataviz (поэтому я добавил тэг data-visualization в ваш вопрос ):
То, что вы пытаетесь сделать, неверно! Вы не должны использовать бары с временной шкалой. Временные шкалы предназначены для временных рядов (в которых мы используем точки или точки, соединенные линиями).
Если вы используете бары со временем по оси x, вы столкнетесь с проблемами:
Однако, просто для объяснения, давайте создадим эту гистограмму с временным масштабом (несмотря на то, что это неправильный выбор) ... Вот как это сделать:
Во-первых, установите «ширину» полос во времени. Предположим, что каждый бар будет иметь 10-дневную ширину:
.attr("width", function(d){
return x(d3.timeDay.offset(d.date, 10)) - x(d.date)
})
Затем установите положение x
на панели до текущей даты, менее половины ее ширины (то есть менее 5 дней в нашем пример):
.attr('x', function(d, i) {
return x(d3.timeDay.offset(d.date, -5));
})
Наконец, не забудьте создать «отступы» в шкале времени:
var x = d3.scaleTime()
.domain([d3.min(data, function(d) {
return d3.timeDay.offset(d.date, -10);
}), d3.max(data, function(d) {
return d3.timeDay.offset(d.date, 10);
})])
.range([0, width]);
Вот ваш код с этими изменениями:
var keys = [];
var legendKeys = [];
var maxVal = [];
var w = 800;
var h = 450;
var margin = {
top: 30,
bottom: 40,
left: 50,
right: 20,
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var colors = ['#FF9A00', '#FFEBB6', '#FFC400', '#B4EDA0', '#FF4436'];
var data = [{
"one": 4306,
"two": 2465,
"three": 2299,
"four": 988,
"five": 554,
"six": 1841,
"date": "2015-05-31T00:00:00"
}, {
"one": 4378,
"two": 2457,
"three": 2348,
"four": 1021,
"five": 498,
"six": 1921,
"date": "2015-06-30T00:00:00"
}, {
"one": 3404,
"two": 2348,
"three": 1655,
"four": 809,
"five": 473,
"six": 1056,
"date": "2015-07-31T00:00:00"
},
];
data.forEach(function(d) {
d.date = new Date(d.date)
})
for (var i = 0; i < data.length; i++) {
for (var key in data[i]) {
if (!data.hasOwnProperty(key) && key !== "date")
maxVal.push(data[i][key]);
}
}
var x = d3.scaleTime()
.domain([d3.min(data, function(d) {
return d3.timeDay.offset(d.date, -10);
}), d3.max(data, function(d) {
return d3.timeDay.offset(d.date, 10);
})])
.range([0, width]);
var y = d3.scaleLinear()
.domain([0, d3.max(maxVal, function(d) {
return d;
})])
.range([height, 0]);
var svg = d3.select('body').append('svg')
.attr('class', 'chart')
.attr('width', w)
.attr('height', h);
var chart = svg.append('g')
.classed('graph', true)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var layersArea = chart.append('g')
.attr('class', 'layers');
var layers = layersArea.append('g')
.attr('class', 'layer');
layers.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('height', function(d, i) {
return height - y(d.one);
})
.attr('y', function(d, i) {
return y(d.one);
})
// .attr('width', function(d, i) {
// return 50;
// })
.attr("width", function(d) {
return x(d3.timeDay.offset(d.date, 10)) - x(d.date)
})
.attr('x', function(d, i) {
return x(d3.timeDay.offset(d.date, -5));
})
.style('fill', (d, i) => {
return colors[i];
});
chart.append('g')
.classed('x axis', true)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y-%m-%d")).tickValues(data.map(function(d) {
return new Date(d.date)
})));
chart.append('g')
.classed('y axis', true)
.call(d3.axisLeft(y)
.ticks(10));
<script src="https://d3js.org/d3.v4.min.js"></script>
scaleLinear
для дат на оси x, поскольку они всего лишь момент времени, они могут быть месяцами. Мне просто нужно преобразовать отметку времени в данных на читаемую дату – ttmt 16 January 2018 в 12:18