Public
Edited
Jan 16, 2023
1 star
Insert cell
Insert cell
main = {
let dom = html`<div style="position: relative; height:100%">
<div class='dim-select'
style='position:absolute;
z-index:2;
right: 10% ;
background: #fff;
box-shadow: 4px 7px 8px #eee;
border: 1px solid #eee;' >
${selectInput}
${isShowSelect ? search : ""}
${isShowSelect ? dimList : []}
</div>
<div class='dims-chart' style="height: 100% ;min-height:400px; width:100%"></div>
</div>`;
setTimeout(() => {
const k = getUserStorageKey();
const val = sessionStorage.getItem(k);
if (val && chooseDims[0] !== val) {
mutable chooseDims = [val];
}
}, 100);
return dom;
}
Insert cell
mutable searchWord = ""
Insert cell
mutable chooseDims = _.take(legend, 1)
Insert cell
mutable isShowSelect = false
Insert cell
findParentBySelector = {
function collectionHas(a, b) {
//helper function (see below)
for (var i = 0, len = a.length; i < len; i++) {
if (a[i] == b) return true;
}
return false;
}
return function findParentBySelector(elm, selector) {
var all = document.querySelectorAll(selector);
var cur = elm.parentNode;
while (cur && !collectionHas(all, cur)) {
//keep going up until you find a match
cur = cur.parentNode; //go up
}
return cur; //will return null if not found
}
}
Insert cell
legend = _.keys(_.groupBy(finalDat, "mergedDim")).filter((l) =>
_.includes(l, searchWord)
)
Insert cell
getNoChooseDims = () => _.filter(legend, (d) => !_.includes(chooseDims, d))
Insert cell
Insert cell
selectInput = {
let input = html`<input style='height: 20px ;
line-height: 40px;
width:400px;
text-align: center;'
placeholder='维度选择:${
_.isEmpty(chooseDims) ? "未选择" : chooseDims
}' />`;
//筛选结果栏 输入框获取焦点事件
input.onclick = () => {
mutable isShowSelect = !isShowSelect;
};
return input;
}
Insert cell
// 维度栏
dimList = {
let ls = html`<ul class='dims-list' style='list-style: none; padding: 0; height: 200px;max-width:400px; overflow: auto; border-bottom: 1px solid #eee; margin: 0;'>
${_.map(legend, (len) => {
const color = !_.includes(chooseDims, len) ? "#fff" : "#e6f7ff";
return `<li style='cursor: pointer;background: ${color}; margin:5px 0; padding: 0 5px;'>${len} </li>`;
})}
</ul>`;
ls.onclick = (e) => {
const val = e.target.innerText;
mutable isShowSelect = false;
mutable chooseDims = [val];
sessionStorage.setItem(getUserStorageKey(), val);
};
return ls;
}
Insert cell
hashCode = function (str) {
var hash = 0,
i,
chr;
if (str.length === 0) return hash;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
Insert cell
function getUserStorageKey() {
const userId = _.get(window.sugo, "user.id", "unknown-user");
const hash = hashCode(
`${userId}:${slice.params.metrics}:${slice.params.tabKey}`
);
return `sliceTmpSetting:${hash}`;
}
Insert cell
groupedData = {
return _.groupBy(
_.filter(finalDat, (d) => _.includes(chooseDims, d.mergedDim)),
"mergedDim"
);
}
Insert cell
// 2021.12.10 二维折线图1(标注最大值最小值)
// 单指标;2个维度(时间维度 + 其他维度合并一维);源数据保留2位小数;
Insert cell
dimensions = ["time", "TLJ", "province", "city"]
Insert cell
finalDim = [_.first(dimensions), "mergedDim"]
Insert cell
metrics = ['count']
Insert cell
Insert cell
finalDat = {
let restDims = _.drop(dimensions, 1);
const data2 = await queryData(data);
return _.map(data2, (d) => {
return {
...d,
mergedDim: `${restDims.map((dim) => _.trim(d[dim])).join("-")}`
};
});
}
Insert cell
async function queryData(data0) {
// 时间:默认取值最近 n 天,至昨天; n 根据 timeRange 计算
const timeDim =
_.find(["YEAR", "MONTH", "DAY"], (dimName) => _.get(data0, [0, dimName])) ||
"MONTH";
let latestData = await modifyParamsAndQuery((slice) => {
const timeRange = _.get(slice, "params.extraData.timeRange") || [];
const dt = moment().add(-1, timeDim).diff(timeRange[1], timeDim);

return copyOnUpdate(slice, "params.extraData.timeRange", (arr) =>
_.map(arr, (t, ti) => {
// dt = 昨天 - until
// next = timeRange + dt
return moment(t, "YYYY-MM-DD").add(dt, timeDim).format("YYYY-MM-DD");
})
);
});
return _.get(latestData, "resultSet") || [];
}
Insert cell
slice = ({id: 0})
Insert cell
copyOnUpdate = _.identity
Insert cell
moment = window.moment || require("moment")
Insert cell
modifyParamsAndQuery = async (mapper) => {
return {
_tempMetric_xx: 0,
resultSet: data
};
}
Insert cell
translationDict = ({})
Insert cell
Insert cell
metricFormatterFn = metricsFormatDict[metrics[0]] || _.identity
Insert cell
Insert cell
option = {
let [timeDim, mergedDim] = finalDim;
let [metric] = metrics;
return {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
},
formatter: echartsLikeTooltipFormatter
},
// legend: {
// type: 'scroll'
// },
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: {
type: "category",
data: _.uniq((finalDat || []).map((d) => d[timeDim])),
//data: (data || []).map((d) => dimensions.map(dim => _.trim(d[dim])).join('-')),
//axisLabel: { rotate: 30 },
axisTick: { alignWithLabel: true },
axisLine: { onZero: false }
},
yAxis: {
type: "value",
boundaryGap: [0, 0.01],
scale: true //非0
},
color: [
"#5470c6",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc"
],
series: [
..._.map(groupedData, (arr, group) => {
return {
name: group,
type: "line",
symbol: "emptyCircle",
data: arr.map((d) => _.round(d[metric], 2)),
areaStyle: { normal: {} },
smooth: true,
markLine: {
silent: true,
lineStyle: {
color: "#FBDB10",
type: "solid"
},
label: {
position: "insideStartTop",
color: "#FBDB10",
formatter: "均值:{c}",
textShadowColor: "#fff",
textShadowBlur: 0.5,
textShadowOffsetX: 0.5,
textShadowOffsetY: 0.5,
fontSize: 14
},
data: [
{
yAxis: _.round(_.meanBy(arr, metric), 2)
}
]
},
markPoint: {
data: [
{ type: "max", name: "Max" },
{ type: "min", name: "Min" }
],
label: {
formatter: (params) => {
return metricFormatterFn(params.value);
}
}
}
};
})
]
};
}
Insert cell
chartInst = echarts.init(main.querySelector('.dims-chart'))
Insert cell
chartInst.setOption(option, { notMerge: true, lazyUpdate: true })
Insert cell
(width, chartInst.resize()) // 自适应宽度
Insert cell
echarts = window.echarts || require("https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js")
Insert cell
_ = window._ || require("lodash")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more