Socket
Socket
Sign inDemoInstall

mapd3

Package Overview
Dependencies
Maintainers
6
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mapd3 - npm Package Compare versions

Comparing version 0.13.2 to 0.14.0

.babelrc

4

.eslintrc.json

@@ -115,3 +115,3 @@ {

"no-loop-func": 2, // functions in loops are difficult to reason about.
"no-magic-numbers": [2, {"enforceConst": true, "ignore": [0,1,2]}], // what the number represents gets lost.
"no-magic-numbers": 0, // what the number represents gets lost.
"no-mixed-requires": 1, // group requires and seperate from other init for clearer code.

@@ -166,3 +166,3 @@ "no-mixed-spaces-and-tabs": 2, // just spaces for consistency.

"no-undefined": 2, // better to check typeof
"no-underscore-dangle": 2, // should not rely on variable name to reason about scoping, as it may change.
"no-underscore-dangle": 0, // should not rely on variable name to reason about scoping, as it may change.
"no-unexpected-multiline": 2, // prevents issues related to semicolons.

@@ -169,0 +169,0 @@ "no-unmodified-loop-condition": 2, // possible infinite loop; probably a mistake.

{
"name": "mapd3",
"version": "0.13.2",
"version": "0.14.0",
"description": "A fast chart library for the fastest DB",

@@ -20,3 +20,5 @@ "main": "dist/mapd3.js",

"dev": "webpack --env.dev --watch",
"clean": "yarn cache clean && rm -rf node_modules"
"clean": "yarn cache clean && rm -rf node_modules",
"test": "mocha-webpack test/**/*.spec.js --require test/setup.js --webpack-config webpack.config-spec.js --watch",
"format": "eslint \"src/**/*.js\" --fix"
},

@@ -50,23 +52,30 @@ "repository": {

"@babel/core": "^7.0.0-beta.36",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.41",
"@babel/preset-env": "^7.0.0-beta.36",
"babel-core": "^6.25.0",
"babel-eslint": "^7.2.3",
"babel-loader": "^8.0.0-beta.0",
"babel-plugin-add-module-exports": "^0.2.1",
"chai": "^4.1.2",
"css-loader": "^0.28.7",
"eslint": "^4.18.2",
"extract-text-webpack-plugin": "^3.0.2",
"ink-docstrap": "^1.3.0",
"jsdoc": "^3.5.4",
"jsdom": "^11.6.2",
"json-loader": "^0.5.7",
"mocha": "^5.0.5",
"mocha-webpack": "^1.1.0",
"node-sass": "^4.7.2",
"null-loader": "^0.1.1",
"requirejs-plugins": "^1.0.2",
"sanitize-html": "^1.13.0",
"sass-loader": "^6.0.6",
"sinon": "^4.5.0",
"text": "requirejs/text",
"webpack": "^3.10.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^1.16.2",
"webpack-livereload-plugin": "^0.9.0",
"webpack-node-externals": "^1.6.0",
"yargs": "^10.0.3"
}
}

@@ -0,1 +1,2 @@

import * as d3 from "./charts/helpers/d3-service"
import Chart from "./charts/chart.js"

@@ -29,3 +30,4 @@ import Tooltip from "./charts/tooltip.js"

Interactors,
colors
colors,
d3
}
import * as d3 from "./helpers/d3-service"
import {override, getSizes} from "./helpers/common"
import {override} from "./helpers/common"
import {autoFormat, multiFormat, getExtractFormatter} from "./helpers/formatters"

@@ -34,3 +34,8 @@

yDomain: "auto",
y2Domain: "auto"
y2Domain: "auto",
labelsAreRotated: false,
chartWidth: null,
chartHeight: null,
markPanelWidth: null
}

@@ -47,5 +52,7 @@

container: _container,
root: null,
xAxisRoot: null,
yAxisRoot: null,
y2AxisRoot: null,
background: null,
chartHeight: null,
chartWidth: null,
xAxis: null,

@@ -60,20 +67,26 @@ yAxis: null,

if (!cache.root) {
cache.root = cache.container.append("g")
.classed("axis-group", true)
.style("pointer-events", "none")
cache.root.append("g").attr("class", "grid-lines-group")
cache.root.append("g").attr("class", "axis x")
cache.root.append("g").attr("class", "axis y")
cache.root.append("g").attr("class", "axis y2")
cache.root = cache.container.select("svg.chart > g.chart-group")
cache.xAxisRoot = cache.root.append("g")
.classed("axis-group", true)
.style("pointer-events", "none")
cache.xAxisRoot.append("g").attr("class", "grid-lines-group")
cache.xAxisRoot.append("g").attr("class", "axis x")
cache.yAxisRoot = cache.container.select(".y-axis-container > svg")
cache.y2AxisRoot = cache.container.select(".y2-axis-container > svg")
cache.yAxisRoot.select(".axis-group").append("g").attr("class", "axis y")
cache.y2AxisRoot.select(".axis-group").append("g").attr("class", "axis y2")
}
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
const DOMAIN_LINE_WIDTH = 1
cache.yAxisRoot
.attr("width", config.margin.left)
.attr("height", config.chartHeight + config.margin.top + config.margin.bottom)
.select(".axis-group")
.attr("transform", `translate(${config.margin.left - DOMAIN_LINE_WIDTH}, ${config.margin.top})`)
cache.root.attr("transform", `translate(${config.margin.left}, ${config.margin.top})`)
cache.y2AxisRoot
.attr("width", config.margin.left)
.attr("height", config.chartHeight + config.margin.top + config.margin.bottom)
.select(".axis-group")
.attr("transform", `translate(0, ${config.margin.top})`)
}

@@ -90,3 +103,7 @@

} else if (config.keyType === "string") {
cache.xAxis.tickValues(scales.xScale.domain().filter((d, i) => !(i % config.xTickSkip)))
let xTickSkip = config.xTickSkip
if (config.xTickSkip === "auto") {
xTickSkip = getNumberOfLabelsToSkip()
}
cache.xAxis.tickValues(scales.xScale.domain().filter((d, i) => !(i % xTickSkip)))
} else if (config.keyType === "number") {

@@ -109,6 +126,8 @@ if (config.extractType) {

const yExtent = config.yDomain === "auto" ? scales.yScale.domain() : config.yDomain
let yFormat = autoFormat(yExtent, config.numberFormat)
const yFormat = autoFormat(yExtent, config.numberFormat)
axis.tickFormat(d3.format(yFormat))
} else if (typeof config.yAxisFormat === "string") {
axis.tickFormat(d3.format(config.yAxisFormat))
} else if (Array.isArray(config.yAxisFormat)) {
axis.tickFormat(d3.format(config.yAxisFormat[0]))
}

@@ -123,6 +142,8 @@ }

const y2Extent = config.y2Domain === "auto" ? scales.y2Scale.domain() : config.y2Domain
let y2Format = autoFormat(y2Extent, config.numberFormat)
const y2Format = autoFormat(y2Extent, config.numberFormat)
axis.tickFormat(d3.format(y2Format))
} else if (typeof config.y2AxisFormat === "string") {
axis.tickFormat(d3.format(config.y2AxisFormat))
} else if (Array.isArray(config.y2AxisFormat)) {
axis.tickFormat(d3.format(config.y2AxisFormat[0]))
}

@@ -133,5 +154,5 @@ }

cache.xAxis = d3.axisBottom(scales.xScale)
.tickSize(config.tickSizes, 0)
.tickPadding(config.tickPadding)
.tickSizeOuter(0)
.tickSize(config.tickSizes, 0)
.tickPadding(config.tickPadding)
.tickSizeOuter(0)

@@ -142,5 +163,5 @@ formatXAxis()

cache.yAxis = d3.axisLeft(scales.yScale)
.tickSize([config.tickSizes])
.tickPadding(config.tickPadding)
.tickSizeOuter(0)
.tickSize([config.tickSizes])
.tickPadding(config.tickPadding)
.tickSizeOuter(0)

@@ -152,3 +173,3 @@ formatYAxis(cache.yAxis)

} else {
cache.yAxis.ticks(Math.ceil(cache.chartHeight / config.tickSpacing))
cache.yAxis.ticks(Math.ceil(config.chartHeight / config.tickSpacing))
}

@@ -159,5 +180,5 @@ }

cache.y2Axis = d3.axisRight(scales.y2Scale)
.tickSize([config.tickSizes])
.tickPadding(config.tickPadding)
.tickSizeOuter(0)
.tickSize([config.tickSizes])
.tickPadding(config.tickPadding)
.tickSizeOuter(0)

@@ -172,26 +193,53 @@ formatY2Axis(cache.y2Axis)

function rotateXLabels () {
cache.xAxisRoot.select(".axis.x").selectAll("text")
.attr("y", 0)
.attr("x", 9)
.attr("dy", ".35em")
.attr("transform", "rotate(90)")
.style("text-anchor", "start")
return this
}
function getNumberOfLabelsToSkip () {
const APPROX_FONT_WIDTH = 5
const labels = scales.xScale.domain()
let longestLabelApproxWidth = null
if (config.labelsAreRotated) {
longestLabelApproxWidth = APPROX_FONT_WIDTH
} else {
const longestLabel = labels.reduce((longest, d) => (d.length > longest.length ? d : longest), {length: 0})
longestLabelApproxWidth = longestLabel.length * APPROX_FONT_WIDTH
}
return Math.ceil(longestLabelApproxWidth / (config.markPanelWidth / labels.length))
}
function drawAxis () {
cache.root.select(".axis.x")
.attr("transform", `translate(0, ${cache.chartHeight})`)
.call(cache.xAxis)
cache.xAxisRoot.select(".axis.x")
.attr("transform", `translate(0, ${config.chartHeight})`)
.call(cache.xAxis)
if (config.labelsAreRotated) {
rotateXLabels()
}
if (scales.yScale) {
cache.root.select(".axis.y")
.transition()
.duration(config.axisTransitionDuration)
.ease(config.ease)
.call(cache.yAxis)
cache.yAxisRoot.select(".axis.y")
.transition()
.duration(config.axisTransitionDuration)
.ease(config.ease)
.call(cache.yAxis)
} else {
cache.root.select(".axis.y").selectAll("*").remove()
cache.yAxisRoot.select(".axis.y").selectAll("*").remove()
}
if (scales.y2Scale) {
cache.root.select(".axis.y2")
.attr("transform", `translate(${cache.chartWidth}, 0)`)
.transition()
.duration(config.axisTransitionDuration)
.ease(config.ease)
.call(cache.y2Axis)
cache.y2AxisRoot.select(".axis.y2")
.transition()
.duration(config.axisTransitionDuration)
.ease(config.ease)
.call(cache.y2Axis)
} else {
cache.root.select(".axis.y2").selectAll("*").remove()
cache.y2AxisRoot.select(".axis.y2").selectAll("*").remove()
}

@@ -208,9 +256,9 @@

} else {
ticks = Math.ceil(cache.chartHeight / config.tickSpacing)
ticks = Math.ceil(config.chartHeight / config.tickSpacing)
}
if (scales.yScale) {
cache.horizontalGridLines = cache.root.select(".grid-lines-group")
.selectAll("line.horizontal-grid-line")
.data(scales.yScale.ticks(ticks))
cache.horizontalGridLines = cache.xAxisRoot.select(".grid-lines-group")
.selectAll("line.horizontal-grid-line")
.data(scales.yScale.ticks(ticks))

@@ -223,3 +271,3 @@ cache.horizontalGridLines.enter()

.duration(config.axisTransitionDuration)
.attr("x2", cache.chartWidth)
.attr("x2", config.markPanelWidth)
.attr("y1", scales.yScale)

@@ -235,5 +283,5 @@ .attr("y2", scales.yScale)

if (config.grid === "vertical" || config.grid === "full") {
cache.verticalGridLines = cache.root.select(".grid-lines-group")
.selectAll("line.vertical-grid-line")
.data(cache.xAxis.tickValues())
cache.verticalGridLines = cache.xAxisRoot.select(".grid-lines-group")
.selectAll("line.vertical-grid-line")
.data(cache.xAxis.tickValues())

@@ -247,3 +295,3 @@ cache.verticalGridLines.enter()

.attr("y1", 0)
.attr("y2", cache.chartHeight)
.attr("y2", config.chartHeight)
.attr("x1", scales.xScale)

@@ -276,6 +324,14 @@ .attr("x2", scales.xScale)

function destroy () {
if (cache.root) {
cache.root.remove()
cache.root = null
if (cache.xAxisRoot) {
cache.xAxisRoot.remove()
cache.xAxisRoot = null
}
if (cache.yAxisRoot) {
cache.yAxisRoot.remove()
cache.yAxisRoot = null
}
if (cache.y2AxisRoot) {
cache.y2AxisRoot.remove()
cache.y2AxisRoot = null
}
}

@@ -282,0 +338,0 @@

@@ -1,3 +0,3 @@

import {keys, MAX_MARK_WIDTH} from "./helpers/constants"
import {override, getSizes} from "./helpers/common"
import {keys} from "./helpers/constants"
import {override} from "./helpers/common"

@@ -11,3 +11,3 @@ export default function Bar (_container) {

bottom: 40,
left: 70
left: 0
},

@@ -18,3 +18,9 @@ width: 800,

chartType: null,
barSpacingPercent: 10
barSpacingPercent: 10,
markWidth: null,
chartWidth: null,
chartHeight: null,
markPanelWidth: null,
selectedKeys: []
}

@@ -32,5 +38,3 @@

container: _container,
svg: null,
chartHeight: null,
chartWidth: null
svg: null
}

@@ -46,18 +50,27 @@

const MIN_BAR_HEIGHT = 1
const DIMMED_COLOR = "silver"
const getColor = (d) => scales.colorScale(d[keys.ID])
const getColor = (d) => {
const key = d.data && d.data.key
if (key && Array.isArray(config.selectedKeys) && config.selectedKeys.length) {
if (config.selectedKeys.indexOf(key) > -1) {
return scales.colorScale(d.id)
} else {
return DIMMED_COLOR
}
} else {
return scales.colorScale(d.id)
}
}
function build () {
if (!cache.root) {
cache.root = cache.container.append("g")
.classed("mark-group", true)
.classed("mark-group", true)
}
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
}
function drawBars () {
const stack = data.stack(data.stackData)
const markCount = data.dataByKey && data.dataByKey.length || 1

@@ -67,10 +80,8 @@ let barData = []

barData = data.dataBySeries.filter((d, i) => config.chartType[i] === "bar")
} else if(config.chartType === "bar" || config.chartType === "groupedBar") {
} else if (config.chartType === "bar" || config.chartType === "groupedBar") {
barData = data.dataBySeries
}
const groupCount = stack[0].length
const groupMemberCount = barData.length
const groupW = groupCount ? (cache.chartWidth / groupCount) : 0
const barW = Math.min(groupW, MAX_MARK_WIDTH)
const groupW = markCount ? (config.markPanelWidth / markCount) : 0
const gutterW = groupW / 100 * config.barSpacingPercent

@@ -80,3 +91,3 @@ const groupedBarW = groupMemberCount ? ((groupW - gutterW) / groupMemberCount) : 0

const barLayer = cache.root.selectAll(".bar-layer")
.data(barData)
.data(barData)

@@ -91,12 +102,12 @@ const barLayerUpdate = barLayer.enter()

const bars = barLayerUpdate.selectAll(".mark")
.data((d, i) => {
const datum = d.values.map(dB => {
const dBClone = Object.assign({}, dB)
dBClone.id = d[keys.ID]
dBClone.group = d[keys.GROUP]
dBClone.index = i
return dBClone
})
return datum
.data((d, i) => {
const datum = d.values.map(dB => {
const dBClone = Object.assign({}, dB)
dBClone.id = d[keys.ID]
dBClone.group = d[keys.GROUP]
dBClone.index = i
return dBClone
})
return datum
})

@@ -106,5 +117,5 @@ bars.enter()

.attr("class", "mark bar")
.attr('clip-path', `url(#mark-clip-${config.chartId})`)
.attr("clip-path", `url(#mark-clip-${config.chartId})`)
.merge(bars)
.attr("x", (d, i) => {
.attr("x", (d) => {
if (config.chartType === "groupedBar" || barData.length > 1) {

@@ -114,3 +125,3 @@ const x = scales.xScale(d[keys.KEY]) - groupW / 2 + groupedBarW * d.index + gutterW / 2

} else {
return Math.max(scales.xScale(d[keys.KEY]) - barW / 2, 0)
return Math.max(scales.xScale(d[keys.KEY]) - config.markWidth / 2, 0)
}

@@ -120,5 +131,5 @@ })

if (d[keys.GROUP] === 0) {
return Math.min(scales.yScale(d[keys.VALUE]), cache.chartHeight - MIN_BAR_HEIGHT)
return Math.min(scales.yScale(d[keys.VALUE]), config.chartHeight - MIN_BAR_HEIGHT)
} else {
return Math.min(scales.y2Scale(d[keys.VALUE]), cache.chartHeight - MIN_BAR_HEIGHT)
return Math.min(scales.y2Scale(d[keys.VALUE]), config.chartHeight - MIN_BAR_HEIGHT)
}

@@ -130,3 +141,3 @@ })

} else {
return barW
return config.markWidth
}

@@ -136,5 +147,5 @@ })

if (d[keys.GROUP] === 0) {
return Math.max(cache.chartHeight - scales.yScale(d[keys.VALUE]), MIN_BAR_HEIGHT)
return Math.max(config.chartHeight - scales.yScale(d[keys.VALUE]), MIN_BAR_HEIGHT)
} else {
return Math.max(cache.chartHeight - scales.y2Scale(d[keys.VALUE]), MIN_BAR_HEIGHT)
return Math.max(config.chartHeight - scales.y2Scale(d[keys.VALUE]), MIN_BAR_HEIGHT)
}

@@ -150,7 +161,6 @@ })

const stack = data.stack(data.stackData)
const barW = Math.min(cache.chartWidth / stack[0].length, MAX_MARK_WIDTH)
const gutterW = barW / 100 * config.barSpacingPercent
const gutterW = config.markWidth / 100 * config.barSpacingPercent
const stackedBarGroups = cache.root.selectAll(".bar-group")
.data(stack)
.data(stack)

@@ -161,3 +171,2 @@ const stackedUpdate = stackedBarGroups.enter()

.merge(stackedBarGroups)
.attr("fill", (d) => scales.colorScale(d.key))
.attr("stroke", "white")

@@ -168,3 +177,7 @@

const stackedBars = stackedUpdate.selectAll(".mark")
.data((d) => d)
.data((d, i, p) => {
// add the id to individual datum to use for choosing color
const datum = d.map(dB => ({...dB, id: p[i].__data__.key}))
return datum
})

@@ -174,8 +187,9 @@ stackedBars.enter()

.attr("class", "mark bar")
.attr('clip-path', `url(#mark-clip-${config.chartId})`)
.attr("clip-path", `url(#mark-clip-${config.chartId})`)
.merge(stackedBars)
.attr("x", (d) => scales.xScale(d.data[keys.KEY])- barW / 2 + gutterW / 2)
.attr("y", (d) => scales.yScale(d[1]) )
.attr("x", (d) => scales.xScale(d.data[keys.KEY]) - config.markWidth / 2 + gutterW / 2)
.attr("y", (d) => scales.yScale(d[1]))
.attr("height", (d) => Math.max(scales.yScale(d[0]) - scales.yScale(d[1]), MIN_BAR_HEIGHT))
.attr("width", barW - gutterW)
.attr("width", config.markWidth - gutterW)
.attr("fill", getColor)

@@ -182,0 +196,0 @@ stackedBars.exit().remove()

@@ -37,19 +37,19 @@ import * as d3 from "./helpers/d3-service"

cache.root = cache.container.append("div")
.attr("class", "binning-group")
.style("float", "left")
.style("padding-top", "12px")
.style("padding-left", "12px")
.attr("class", "binning-group")
.style("float", "left")
.style("padding-top", "12px")
.style("padding-left", "12px")
cache.label = cache.root.append("div")
.attr("class", "bin-label")
.text(config.label)
.attr("class", "bin-label")
.text(config.label)
cache.autoItem = cache.root.append("div")
.attr("class", "item item-auto toggleOnOff")
.on("click.select", function click () {
const isSelected = this.classList.contains("selected")
const toggled = !isSelected
dispatcher.call("change", this, {name: config.autoLabel, isSelected: toggled})
})
.text(config.autoLabel)
.attr("class", "item item-auto toggleOnOff")
.on("click.select", function click () {
const isSelected = this.classList.contains("selected")
const toggled = !isSelected
dispatcher.call("change", this, {name: config.autoLabel, isSelected: toggled})
})
.text(config.autoLabel)
}

@@ -70,12 +70,12 @@

cache.binningItems = cache.root.selectAll(".toggleExclusive")
.data(_binningToggles)
.data(_binningToggles)
cache.binningItems.enter().append("div")
.attr("class", (d) => `item item-${d} toggleExclusive`)
.on("click.select", function click (d) {
const isSelected = this.classList.contains("selected")
dispatcher.call("change", this, {name: d, isSelected})
})
.merge(cache.binningItems)
.text((d) => d)
.on("click.select", function click (d) {
const isSelected = this.classList.contains("selected")
dispatcher.call("change", this, {name: d, isSelected})
})
.merge(cache.binningItems)
.attr("class", (d) => `item item-${d} toggleExclusive`)
.text((d) => d)

@@ -82,0 +82,0 @@ cache.binningItems.exit().remove()

import * as d3 from "./helpers/d3-service"
import {override, stringToType, getSizes, extendIsValid} from "./helpers/common"
import {override, stringToType, extendIsValid} from "./helpers/common"
import {blurOnEnter} from "./interactors"

@@ -9,10 +9,2 @@

let config = {
margin: {
top: 60,
right: 30,
bottom: 40,
left: 70
},
width: 800,
height: 500,
keyType: "time",

@@ -30,5 +22,3 @@ dateFormat: "%b %d, %Y",

inputMin: null,
inputMax: null,
chartWidth: null,
chartHeight: null
inputMax: null
}

@@ -44,3 +34,3 @@

function handleFocus (selection) {
return function() {
return () => {
let text = selection.text()

@@ -58,6 +48,6 @@ const parsed = d3.timeParse(config.dateFormat)(text)

cache.root = cache.container
.append("div")
.attr("class", "brush-range-input-group")
.style("top", 0)
.style("padding-top", "12px")
.append("div")
.attr("class", "brush-range-input-group")
.style("top", 0)
.style("padding-top", "12px")

@@ -84,3 +74,3 @@ cache.inputMax = cache.root.append("div")

this,
{ extent: [rangeMin, cache.rangeMax] }
{extent: [rangeMin, cache.rangeMax]}
)

@@ -123,3 +113,3 @@ } else {

this,
{ extent: [cache.rangeMin, rangeMax] }
{extent: [cache.rangeMin, rangeMax]}
)

@@ -138,6 +128,2 @@ } else {

const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
const domain = scales.xScale.domain()

@@ -144,0 +130,0 @@

import * as d3 from "./helpers/d3-service"
import {invertScale, override, getSizes, extendIsValid} from "./helpers/common"
import {clamp, invertScale, override, extendIsValid} from "./helpers/common"

@@ -18,3 +18,6 @@ export default function Brush (_container) {

brushRangeMax: null,
brushIsEnabled: true
brushIsEnabled: true,
markPanelWidth: null,
chartHeight: null
}

@@ -31,5 +34,3 @@

chartBrush: null,
handle: null,
chartWidth: null,
chartHeight: null
handle: null
}

@@ -47,3 +48,3 @@

cache.root = cache.container.append("g")
.classed("brush-group", true)
.classed("brush-group", true)

@@ -55,10 +56,6 @@ cache.brush = d3.brushX()

}
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
}
function buildBrush () {
cache.brush.extent([[0, 0], [cache.chartWidth, cache.chartHeight]])
cache.brush.extent([[0, 0], [config.markPanelWidth, config.chartHeight]])

@@ -68,3 +65,3 @@ cache.chartBrush = cache.root.call(cache.brush)

cache.chartBrush.selectAll(".brush-rect")
.attr("height", cache.chartHeight)
.attr("height", config.chartHeight)

@@ -80,6 +77,2 @@ moveBrush()

function clamp (value, _dataExtent) {
return Math.min(Math.max(_dataExtent[0], value), _dataExtent[1])
}
function clampBrush (_dataExtent) {

@@ -86,0 +79,0 @@ if (config.keyType === "time") {

@@ -10,5 +10,5 @@ import * as d3 from "./helpers/d3-service"

rebind,
getSizes,
uniqueId
} from "./helpers/common"
import {autoConfigure} from "./helpers/auto-config"

@@ -30,5 +30,6 @@ import Scale from "./scale"

export default function Chart (_container) {
let config = {
let inputConfig = {
// common

@@ -48,2 +49,3 @@ margin: {

ease: d3.easeLinear,
useScrolling: false,

@@ -66,2 +68,3 @@ // intro animation

y2AxisFormat: ".2f",
tooltipFormat: ".2f",
tickSizes: 8,

@@ -73,3 +76,7 @@ yTicks: "auto",

axisTransitionDuration: 0,
labelsAreRotated: false,
// data
sortBy: null,
xTitle: "",

@@ -128,3 +135,4 @@ yTitle: "",

// bar
barSpacingPercent: 10
barSpacingPercent: 10,
selectedKeys: []
}

@@ -159,3 +167,4 @@

stack: null,
flatDataSorted: null
flatDataSorted: null,
allKeyTotals: null
}

@@ -165,29 +174,66 @@

let eventCollector = {}
let config = null
setConfig(inputConfig) // init with config = inputConfig
// events
const dispatcher = d3.dispatch("mouseOverPanel", "mouseOutPanel", "mouseMovePanel")
const dispatcher = d3.dispatch("mouseOverPanel", "mouseOutPanel", "mouseMovePanel", "mouseClickPanel")
const dataManager = DataManager()
function build () {
if (!cache.svg) {
const template = `<div class="mapd3 mapd3-container">
const createTemplate = (chartType) => {
const chartClassName = _chartType => {
switch (chartType) {
case "bar":
case "stackedBar":
return "bar"
case "line":
case "stackedArea":
return "line"
// TO DO: handle bar line combo chartType...
case Array.isArray(_chartType):
return "combo"
default:
return ""
}
}
const className = chartClassName(chartType)
return `<div class="mapd3 mapd3-container ${className}">
<div class="header-group"></div>
<svg class="chart">
<g class="chart-group"></g>
<g class="panel-group">
<rect class="panel-background"></rect>
</g>
<rect class="masking-rectangle"></rect>
</svg>
<div class="y-axis-container">
<svg>
<g class="axis-group"></g>
</svg>
</div>
<div class="svg-wrapper">
<svg class="chart ${className}">
<g class="chart-group"></g>
<g class="panel-group">
<rect class="panel-background"></rect>
</g>
<rect class="masking-rectangle"></rect>
</svg>
</div>
<div class="y2-axis-container">
<svg>
<g class="axis-group"></g>
</svg>
</div>
</div>`
}
function build () {
if (!cache.root) {
const base = d3.select(cache.container)
.html(template)
.html(createTemplate(config.chartType))
cache.container = base.select(".mapd3-container")
.style("position", "relative")
cache.root = base.select(".mapd3-container")
.style("position", "relative")
cache.svg = base.select("svg")
cache.svgWrapper = base.select(".svg-wrapper")
cache.svg = base.select("svg.chart")
cache.headerGroup = base.select(".header-group")
.style("position", "absolute")
.style("position", "absolute")
cache.panel = cache.svg.select(".panel-group")

@@ -200,13 +246,13 @@ cache.chart = cache.svg.select(".chart-group")

scale: Scale(),
axis: Axis(cache.chart),
axis: Axis(cache.root),
line: Line(cache.panel),
bar: Bar(cache.panel),
tooltip: Tooltip(cache.container),
legend: Legend(cache.container),
tooltip: Tooltip(cache.root),
legend: Legend(cache.root),
brush: Brush(cache.panel),
hover: Hover(cache.panel),
binning: Binning(cache.headerGroup),
domainEditor: DomainEditor(cache.container),
domainEditor: DomainEditor(cache.root),
brushRangeEditor: BrushRangeEditor(cache.headerGroup),
label: Label(cache.container),
label: Label(cache.root),
clipPath: ClipPath(cache.svg)

@@ -226,24 +272,21 @@ }

const {width, height, chartWidth, chartHeight} = getSizes(config, cache)
cache.width = width
cache.height = height
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
cache.svgWrapper
.style("flex", `0 0 ${config.chartWidth}px`)
.style("height", `${config.height}px`)
cache.svg
.attr("width", cache.width)
.attr("height", cache.height)
.style("flex", `0 0 ${config.markPanelWidth}px`)
.style("height", `${config.chartHeight + config.margin.bottom}`)
.attr("transform", `translate(0,${config.margin.top})`)
cache.headerGroup
.style("width", `${cache.chartWidth}px`)
.style("width", `${config.chartWidth}px`)
.style("left", `${config.margin.left}px`)
cache.panel
.attr("transform", `translate(${config.margin.left},${config.margin.top})`)
.select(".panel-background")
.attr("width", cache.chartWidth)
.attr("height", cache.chartHeight)
.style("width", `${config.markPanelWidth}px`)
.style("height", `${config.chartHeight}px`)
.attr("fill", "transparent")
return this

@@ -258,2 +301,6 @@ }

components.clipPath
.setConfig(config)
.render()
components.axis

@@ -316,6 +363,2 @@ .setConfig(config)

components.clipPath
.setConfig(config)
.render()
triggerIntroAnimation()

@@ -327,5 +370,8 @@ return this

dataObject.data = cloneData(_data[keys.SERIES])
const cleanedData = dataManager.cleanData(_data, config.keyType)
const cleanedData = dataManager.cleanData(_data, config.keyType, config.sortBy)
Object.assign(dataObject, cleanedData)
const autoConfig = autoConfigure(inputConfig, cache, dataObject)
config = Object.assign({}, inputConfig, autoConfig)
render()

@@ -347,3 +393,3 @@ return this

.attr("width", 0)
.attr("x", cache.width - config.margin.right)
.attr("x", config.width - config.margin.right)
.on("end", () => cache.maskingRectangle.remove())

@@ -368,2 +414,3 @@ }

const [mouseX, mouseY] = d3.mouse(cache.panel.node())
const [panelMouseX] = d3.mouse(cache.svgWrapper.node())
if (!dataObject.data) { return }

@@ -375,9 +422,19 @@ const xPosition = mouseX

const dataPointXPosition = scales.xScale(dataPoint[keys.KEY])
throttledDispatch("mouseMovePanel", null, dataPoint, dataPointXPosition, mouseY)
throttledDispatch("mouseMovePanel", null, dataPoint, dataPointXPosition, mouseY, panelMouseX)
}
})
.on("click.dispatch", () => {
const [mouseX] = d3.mouse(cache.panel.node())
if (!dataObject.data) { return }
const xPosition = mouseX
const dataPoint = dataManager.getNearestDataPoint(xPosition, dataObject, scales, config.keyType)
if (dataPoint) {
throttledDispatch("mouseClickPanel", null, dataPoint)
}
})
}
function getEvents () {
if (!cache.svg) {
if (!cache.root) {
render()

@@ -394,3 +451,6 @@ }

function setConfig (_config) {
config = override(config, _config)
inputConfig = override(inputConfig, _config)
const autoConfig = autoConfigure(inputConfig, cache, dataObject)
config = Object.assign({}, inputConfig, autoConfig)
return this

@@ -409,3 +469,3 @@ }

function destroy () {
cache.svg.on(".", null).remove()
cache.root.on(".", null).remove()
}

@@ -412,0 +472,0 @@

@@ -1,3 +0,2 @@

import * as d3 from "./helpers/d3-service"
import {override, getSizes} from "./helpers/common"
import {override} from "./helpers/common"

@@ -19,3 +18,6 @@ /**

height: 500,
chartId : null,
chartId: null,
markPanelWidth: null,
chartHeight: null
}

@@ -25,5 +27,3 @@

container: _container,
clipPath: null,
chartWidth: null,
chartHeight: null,
clipPath: null
}

@@ -33,15 +33,11 @@

if (!cache.clipPath) {
cache.clipPath = cache.container.append('defs')
.append('clipPath')
.attr('id', `mark-clip-${config.chartId}`)
.append('rect')
cache.clipPath = cache.container.append("defs")
.append("clipPath")
.attr("id", `mark-clip-${config.chartId}`)
.append("rect")
}
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
cache.clipPath
.attr('width', cache.chartWidth)
.attr('height', cache.chartHeight)
.attr("width", config.markPanelWidth)
.attr("height", config.chartHeight)
}

@@ -54,3 +50,3 @@

function render() {
function render () {
build()

@@ -57,0 +53,0 @@ }

import * as d3 from "./helpers/d3-service"
import {keys} from "./helpers/constants"
import {invertScale, sortData, cloneData, getUnique} from "./helpers/common"
import {comparators, keys} from "./helpers/constants"
import {ascendingComparator, descendingComparator, clamp, invertScale, sortData, cloneData, getUnique} from "./helpers/common"

@@ -14,3 +14,4 @@

groupCount: 2,
lineCount: 4
lineCount: 4,
stringMinMaxLength: [4, 8]
}

@@ -29,15 +30,17 @@ const cache = {

function generateRandomString (_length) {
return Math.random().toString(36).replace(/[^a-z0-9]+/g, "").substr(0, _length || 5)
let stringLength = _length
if (!_length) {
const range = config.stringMinMaxLength
stringLength = Math.round(Math.random() * (range[1] - range[0])) + range[0]
}
return [...Array(stringLength)].map(() => String.fromCharCode(Math.round(Math.random() * 25) + 97)).join("")
}
function generateSeries (_dataKeys, _range, _allowNegative) {
function generateSeries (_dataKeys, _range) {
let value = d3.randomUniform(..._range)()
const variabilityRatio = 50
const randomWalkStepSize = (_range[1] - _range[0]) / variabilityRatio
const variabilityDivider = 10
const randomWalkStepSize = (_range[1] - _range[0]) / variabilityDivider
const rnd = d3.randomNormal(0, 1)
return _dataKeys.map((d) => {
value = value + rnd() * randomWalkStepSize
if (!_allowNegative && value < randomWalkStepSize) {
value = value + randomWalkStepSize
}
value = clamp(value + rnd() * randomWalkStepSize, _range)
return {

@@ -82,3 +85,3 @@ value,

function cleanData (_data, _keyType) {
function cleanData (_data, _keyType, _sortBy) {
const dataBySeries = cloneData(_data[keys.SERIES])

@@ -153,19 +156,43 @@ dataBySeries.forEach((serie) => {

const stackData = dataByKey
.map((d) => {
const points = {
key: d[keys.KEY]
}
d.series.forEach((dB) => {
points[dB[keys.ID]] = dB[keys.VALUE]
})
return points
.map((d) => {
const points = {
key: d[keys.KEY]
}
d.series.forEach((dB) => {
points[dB[keys.ID]] = dB[keys.VALUE]
})
return points
})
// d3 stack
const stack = d3.stack()
.keys(dataBySeries.map(getID))
.order(d3.stackOrderNone)
.offset(d3.stackOffsetNone)
.keys(dataBySeries.map(getID))
.order(d3.stackOrderNone)
.offset(d3.stackOffsetNone)
return {dataBySeries, dataByKey, stack, stackData, flatDataSorted, groupKeys}
// get stack totals
const allKeyTotals = dataByKey.map(d => ({
key: d[keys.KEY],
total: d3.sum(d[keys.SERIES].map(dB => dB[keys.VALUE]))
}))
// sort
switch (_sortBy) {
case comparators.TOTAL_ASCENDING:
allKeyTotals.sort(ascendingComparator("total"))
break
case comparators.TOTAL_DESCENDING:
allKeyTotals.sort(descendingComparator("total"))
break
case comparators.ALPHA_ASCENDING:
allKeyTotals.sort(ascendingComparator("key"))
break
case comparators.ALPHA_DESCENDING:
allKeyTotals.sort(descendingComparator("key"))
break
default:
break
}
return {dataBySeries, dataByKey, stack, stackData, flatDataSorted, groupKeys, allKeyTotals}
}

@@ -172,0 +199,0 @@

import * as d3 from "./helpers/d3-service"
import {override, stringToType, getSizes} from "./helpers/common"
import {override, stringToType} from "./helpers/common"
import {blurOnEnter} from "./interactors"

@@ -28,3 +28,6 @@

yDomainEditorIsEnabled: true,
y2DomainEditorIsEnabled: true
y2DomainEditorIsEnabled: true,
chartWidth: null,
chartHeight: null
}

@@ -46,5 +49,3 @@

xMaxInput: null,
xLockIcon: null,
chartWidth: null,
chartHeight: null
xLockIcon: null
}

@@ -91,28 +92,28 @@

cache.root = cache.container
.append("div")
.attr("class", "domain-input-group")
.style("position", "absolute")
.style("top", 0)
.append("div")
.attr("class", "domain-input-group")
.style("position", "absolute")
.style("top", 0)
// hit zones
cache.xHitZone = cache.root.append("div")
.attr("class", "hit-zone x")
.style("pointer-events", "all")
.style("position", "absolute")
.on("mouseover.dispatch", showXEditor)
.on("mouseout.dispatch", hideXEditor)
.attr("class", "hit-zone x")
.style("pointer-events", "all")
.style("position", "absolute")
.on("mouseover.dispatch", showXEditor)
.on("mouseout.dispatch", hideXEditor)
cache.yHitZone = cache.root.append("div")
.attr("class", "hit-zone y")
.style("pointer-events", "all")
.style("position", "absolute")
.on("mouseover.dispatch", showYEditor)
.on("mouseout.dispatch", hideYEditor)
.attr("class", "hit-zone y")
.style("pointer-events", "all")
.style("position", "absolute")
.on("mouseover.dispatch", showYEditor)
.on("mouseout.dispatch", hideYEditor)
cache.y2HitZone = cache.root.append("div")
.attr("class", "hit-zone y2")
.style("pointer-events", "all")
.style("position", "absolute")
.on("mouseover.dispatch", showY2Editor)
.on("mouseout.dispatch", hideY2Editor)
.attr("class", "hit-zone y2")
.style("pointer-events", "all")
.style("position", "absolute")
.on("mouseover.dispatch", showY2Editor)
.on("mouseout.dispatch", hideY2Editor)

@@ -273,12 +274,8 @@ // y input group

const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
if (config.xDomainEditorIsEnabled) {
cache.xHitZone.style("display", "block")
cache.xHitZone
.style("width", `${cache.chartWidth + LOCK_SIZE}px`)
.style("width", `${config.chartWidth + LOCK_SIZE}px`)
.style("height", `${HOVER_ZONE_SIZE}px`)
.style("top", `${config.margin.top + cache.chartHeight}px`)
.style("top", `${config.margin.top + config.chartHeight}px`)
.style("left", `${config.margin.left}px`)

@@ -288,5 +285,5 @@ .style("display", "block")

cache.xMinInput
.style("top", `${PADDING}px`)
.style("left", "0px")
.text(xFormatter(xDomain[0]))
.style("top", `${PADDING}px`)
.style("left", "0px")
.text(xFormatter(xDomain[0]))

@@ -311,3 +308,3 @@ cache.xMaxInput

.style("width", `${HOVER_ZONE_SIZE}px`)
.style("height", `${cache.chartHeight + LOCK_SIZE}px`)
.style("height", `${config.chartHeight + LOCK_SIZE}px`)
.style("top", `${config.margin.top - LOCK_SIZE}px`)

@@ -323,3 +320,3 @@ .style("left", `${config.margin.left - HOVER_ZONE_SIZE}px`)

cache.yMinInput
.style("top", `${cache.chartHeight + LOCK_SIZE - INPUT_HEIGHT}px`)
.style("top", `${config.chartHeight + LOCK_SIZE - INPUT_HEIGHT}px`)
.style("right", "0px")

@@ -342,5 +339,5 @@ .text(yFormatter(yDomain[0]))

.style("width", `${HOVER_ZONE_SIZE}px`)
.style("height", `${cache.chartHeight + LOCK_SIZE}px`)
.style("height", `${config.chartHeight + LOCK_SIZE}px`)
.style("top", `${config.margin.top - LOCK_SIZE}px`)
.style("left", `${config.margin.left + cache.chartWidth}px`)
.style("left", `${config.margin.left + config.chartWidth}px`)

@@ -353,3 +350,3 @@ cache.y2MaxInput

cache.y2MinInput
.style("top", `${cache.chartHeight + LOCK_SIZE - INPUT_HEIGHT}px`)
.style("top", `${config.chartHeight + LOCK_SIZE - INPUT_HEIGHT}px`)
.style("left", `${PADDING}px`)

@@ -356,0 +353,0 @@ .text(y2Formatter(y2Domain[0]))

@@ -30,10 +30,10 @@ import {keys} from "./constants"

const obj = {}
arr.forEach(d =>{
arr.forEach(d => {
obj[d] = null
})
const keys = Object.keys(obj)
const allKeys = Object.keys(obj)
if (_keyType === "time") {
return keys.map(d => new Date(d))
return allKeys.map(d => new Date(d))
} else {
return keys
return allKeys
}

@@ -90,26 +90,7 @@ }

}
console.log("stringToType", str, type, converted)
return converted
}
export function getSizes (config, cache) {
const width = config.width === "auto"
? (cache.container && cache.container.clientWidth || 0)
: config.width
const height = config.height === "auto"
? (cache.container && cache.container.clientHeight || 0)
: config.height
const chartWidth = Math.max(width - config.margin.left - config.margin.right, 0)
const chartHeight = Math.max(height - config.margin.top - config.margin.bottom, 0)
return {
width,
height,
chartWidth,
chartHeight
}
}
export function isNumeric (val) {
return Number(parseFloat(val)) === val;
return Number(parseFloat(val)) === val
}

@@ -123,3 +104,3 @@

&& d !== null
).length == 2
).length === 2
}

@@ -130,1 +111,36 @@

}
export function ascendingComparator (key) {
return (a, b) => {
if (a[key] < b[key]) {
return -1
}
if (a[key] > b[key]) {
return 1
}
return 0
}
}
export function descendingComparator (key) {
return (a, b) => {
if (b[key] < a[key]) {
return -1
}
if (b[key] > a[key]) {
return 1
}
return 0
}
}
export function clamp (value, clampMinMax) {
return Math.min(Math.max(clampMinMax[0], value), clampMinMax[1])
}
export function hasBars (_chartType) {
return _chartType === "bar"
|| _chartType === "stackedBar"
|| _chartType === "groupedBar"
|| (Array.isArray(_chartType) && _chartType.filter(d => d === "bar").length > 0)
}

@@ -20,2 +20,10 @@ export const keys = {

export const MIN_MARK_WIDTH = 20
export const MAX_MARK_WIDTH = 200
export const comparators = {
TOTAL_ASCENDING: "totalAscending",
TOTAL_DESCENDING: "totalDescending",
ALPHA_ASCENDING: "alphaAscending",
ALPHA_DESCENDING: "alphaDescending"
}
export {
axisBottom,
axisLeft,
axisRight,
timeParse,
timeFormat,
utcFormat,
format,
bisector,
extent,
sum,
range,
merge,
nest,
dispatch,
easeLinear,
easeQuadInOut,
select,
mouse,
event,
transition,
randomUniform,
randomNormal,
timeDay,
timeMonth,
timeSecond,
timeMinute,
timeHour,
timeWeek,
timeYear,
utcYear,
utcDay,
area,
curveCatmullRom,
line,
stack,
stackOffsetNone,
stackOrderNone,
scaleTime,
scalePoint,
scaleBand,
scaleLinear,
scaleOrdinal,
symbol,
symbolTriangle,
brushX
axisBottom,
axisLeft,
axisRight,
timeParse,
timeFormat,
utcFormat,
format,
formatPrefix,
bisector,
extent,
sum,
range,
merge,
nest,
dispatch,
easeLinear,
easeQuadInOut,
select,
mouse,
event,
transition,
randomUniform,
randomNormal,
timeDay,
timeMonth,
timeSecond,
timeMinute,
timeHour,
timeWeek,
timeYear,
utcYear,
utcDay,
area,
curveCatmullRom,
line,
stack,
stackOffsetNone,
stackOrderNone,
scaleTime,
scalePoint,
scaleBand,
scaleLinear,
scaleOrdinal,
symbol,
symbolTriangle,
brushX
} from "d3/build/d3"

@@ -76,10 +76,10 @@ import * as d3 from "./d3-service"

// slightly modified version of d3's default time-formatting to always use abbrev month names
const formatMillisecond = d3.timeFormat(".%L");
const formatSecond = d3.timeFormat(":%S");
const formatMinute = d3.timeFormat("%I:%M");
const formatHour = d3.timeFormat("%I %p");
const formatDay = d3.timeFormat("%a %d");
const formatWeek = d3.timeFormat("%b %d");
const formatMonth = d3.timeFormat("%b");
const formatYear = d3.timeFormat("%Y");
const formatMillisecond = d3.timeFormat(".%L")
const formatSecond = d3.timeFormat(":%S")
const formatMinute = d3.timeFormat("%I:%M")
const formatHour = d3.timeFormat("%I %p")
const formatDay = d3.timeFormat("%a %d")
const formatWeek = d3.timeFormat("%b %d")
const formatMonth = d3.timeFormat("%b")
const formatYear = d3.timeFormat("%Y")

@@ -91,10 +91,12 @@ /**

*/
export function multiFormat(date) {
export function multiFormat (date) {
/* eslint-disable no-nested-ternary */
return (d3.timeSecond(date) < date ? formatMillisecond
: d3.timeMinute(date) < date ? formatSecond
: d3.timeMinute(date) < date ? formatSecond
: d3.timeHour(date) < date ? formatMinute
: d3.timeDay(date) < date ? formatHour
: d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
: d3.timeYear(date) < date ? formatMonth
: formatYear)(date);
: d3.timeDay(date) < date ? formatHour
: d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
: d3.timeYear(date) < date ? formatMonth
: formatYear)(date)
/* eslint-enable no-nested-ternary */
}

@@ -105,16 +107,16 @@

*/
export function formatOddDateBin(specifier, value) {
export function formatOddDateBin (specifier, value) {
switch (specifier) {
// reproducing the old line chart behavior, even if it's wrong
case "1w":
return `${d3.utcFormat("%b %d")(value)} - ${d3.utcFormat("%b %d,")(d3.utcDay.offset(value, 6))}`
case "1c":
return `${d3.utcFormat("%Y")(value)} - ${d3.utcFormat("%Y")(d3.utcYear.offset(value, 99))}`
case "10y":
return `${d3.utcFormat("%Y")(value)} - ${d3.utcFormat("%Y")(d3.utcYear.offset(value, 9))}`
case "1q":
const monthNumber = d3.utcFormat('%m')(value) // convert to integer month (01 - 12)
return `Q${Math.floor((parseInt(monthNumber, 10) + 3) / 3)} ${d3.utcFormat('%Y')(value)}`;
default:
return
// reproducing the old line chart behavior, even if it's wrong
case "1w":
return `${d3.utcFormat("%b %d")(value)} - ${d3.utcFormat("%b %d,")(d3.utcDay.offset(value, 6))}`
case "1c":
return `${d3.utcFormat("%Y")(value)} - ${d3.utcFormat("%Y")(d3.utcYear.offset(value, 99))}`
case "10y":
return `${d3.utcFormat("%Y")(value)} - ${d3.utcFormat("%Y")(d3.utcYear.offset(value, 9))}`
case "1q":
const monthNumber = d3.utcFormat("%m")(value) // convert to integer month (01 - 12)
return `Q${Math.floor((parseInt(monthNumber, 10) + 3) / 3)} ${d3.utcFormat("%Y")(value)}`
default:
return value
}

@@ -133,5 +135,5 @@ }

export function formatTooltipNumber(d) {
export function formatTooltipNumber (d) {
// comma separator, max 2 decimals
return d3.format(",")(Math.round(d * 100) / 100)
}
import * as d3 from "./helpers/d3-service"
import {keys, LEFT_AXIS_GROUP_INDEX, RIGHT_AXIS_GROUP_INDEX} from "./helpers/constants"
import {override, getSizes} from "./helpers/common"
import {keys, LEFT_AXIS_GROUP_INDEX} from "./helpers/constants"
import {override} from "./helpers/common"

@@ -18,3 +18,6 @@ export default function Hover (_container) {

dotRadius: null,
chartType: null
chartType: null,
chartWidth: null,
chartHeight: null
}

@@ -32,4 +35,2 @@

svg: null,
chartWidth: null,
chartHeight: null,
dateRange: [null, null],

@@ -56,9 +57,5 @@ brush: null,

cache.root = cache.container.append("g")
.classed("hover-group", true)
.style("pointer-events", "none")
.classed("hover-group", true)
.style("pointer-events", "none")
}
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
}

@@ -103,3 +100,3 @@

const dots = cache.root.selectAll(".dot")
.data(_dotsData)
.data(_dotsData)

@@ -115,3 +112,3 @@ dots.enter()

} else {
return scales.y2Scale(d[keys.VALUE])
return scales.y2Scale ? scales.y2Scale(d[keys.VALUE]) : scales.yScale(d[keys.VALUE])
}

@@ -145,3 +142,3 @@ })

const verticalMarkerLine = cache.root.selectAll("line")
.data([0])
.data([0])

@@ -153,3 +150,3 @@ verticalMarkerLine.enter()

.attr("y1", 0)
.attr("y2", cache.chartHeight)
.attr("y2", config.chartHeight)

@@ -156,0 +153,0 @@ verticalMarkerLine.exit().remove()

import * as d3 from "./helpers/d3-service"
import {override, getSizes} from "./helpers/common"
import {override} from "./helpers/common"

@@ -18,3 +18,6 @@ export default function Label (_container) {

yLabel: "",
y2Label: ""
y2Label: "",
chartWidth: null,
chartHeight: null
}

@@ -27,5 +30,3 @@

yAxisLabel: null,
y2AxisLabel: null,
chartWidth: null,
chartHeight: null
y2AxisLabel: null
}

@@ -39,7 +40,7 @@

cache.root = cache.container
.append("div")
.attr("class", "label-group")
.style("position", "absolute")
.style("top", 0)
.style("white-space", "nowrap")
.append("div")
.attr("class", "label-group")
.style("position", "absolute")
.style("top", 0)
.style("white-space", "nowrap")

@@ -90,9 +91,5 @@ cache.xAxisLabel = cache.root.append("div")

const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
cache.xAxisLabel
.text(config.xLabel)
.style("max-width", `${cache.chartWidth}px`)
.style("max-width", `${config.chartWidth}px`)
.style("top", function top () {

@@ -103,8 +100,8 @@ const LABEL_PADDING = 18

})
.style("left", `${config.margin.left + cache.chartWidth / 2}px`)
.style("left", `${config.margin.left + config.chartWidth / 2}px`)
cache.yAxisLabel
.text(config.yLabel)
.style("max-width", `${cache.chartHeight}px`)
.style("top", `${config.margin.top + cache.chartHeight / 2}px`)
.style("max-width", `${config.chartHeight}px`)
.style("top", `${config.margin.top + config.chartHeight / 2}px`)
.style("left", function top () {

@@ -118,4 +115,4 @@ const LABEL_PADDING = 4

.text(config.y2Label)
.style("max-width", `${cache.chartHeight}px`)
.style("top", `${config.margin.top + cache.chartHeight / 2}px`)
.style("max-width", `${config.chartHeight}px`)
.style("top", `${config.margin.top + config.chartHeight / 2}px`)
.style("left", function top () {

@@ -122,0 +119,0 @@ const LABEL_PADDING = 4

import * as d3 from "./helpers/d3-service"
import {keys, dashStylesTranslation} from "./helpers/constants"
import {override, getSizes} from "./helpers/common"
import {override} from "./helpers/common"

@@ -9,14 +9,8 @@ export default function Line (_container) {

let config = {
margin: {
top: 60,
right: 30,
bottom: 40,
left: 70
},
width: 800,
height: 500,
chartId: null,
chartType: null,
colorSchema: ["skyblue"],
xDomain: "auto"
xDomain: "auto",
chartHeight: null
}

@@ -35,4 +29,3 @@

container: _container,
svg: null,
chartHeight: null,
svg: null
}

@@ -52,8 +45,4 @@

cache.root = cache.container.append("g")
.classed("mark-group", true)
.classed("mark-group", true)
}
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
}

@@ -63,8 +52,8 @@

const seriesLine = d3.line()
.x((d) => scales.xScale(d[keys.KEY]))
.y((d) => scales.yScale(d[keys.VALUE]))
.x((d) => scales.xScale(d[keys.KEY]))
.y((d) => scales.yScale(d[keys.VALUE]))
const seriesLine2 = d3.line()
.x((d) => scales.xScale(d[keys.KEY]))
.y((d) => scales.y2Scale(d[keys.VALUE]))
.x((d) => scales.xScale(d[keys.KEY]))
.y((d) => scales.y2Scale(d[keys.VALUE]))

@@ -81,3 +70,3 @@ if (Array.isArray(config.xDomain)) {

const lines = cache.root.selectAll(".mark")
.data(lineData)
.data(lineData)

@@ -88,3 +77,3 @@ lines.enter()

.attr("class", "mark line")
.attr('clip-path', `url(#mark-clip-${config.chartId})`)
.attr("clip-path", `url(#mark-clip-${config.chartId})`)
.classed("y2-line", (d) => d[keys.GROUP] > 0)

@@ -110,14 +99,14 @@ .attr("d", (d) => {

const seriesArea = d3.area()
.x((d) => scales.xScale(d[keys.KEY]))
.y0((d) => scales.yScale(d[keys.VALUE]))
.y1(() => cache.chartHeight)
.x((d) => scales.xScale(d[keys.KEY]))
.y0((d) => scales.yScale(d[keys.VALUE]))
.y1(() => config.chartHeight)
const seriesArea2 = d3.area()
.x((d) => scales.xScale(d[keys.KEY]))
.y0((d) => scales.y2Scale(d[keys.VALUE]))
.y1(() => cache.chartHeight)
.curve(d3.curveCatmullRom)
.x((d) => scales.xScale(d[keys.KEY]))
.y0((d) => scales.y2Scale(d[keys.VALUE]))
.y1(() => config.chartHeight)
.curve(d3.curveCatmullRom)
const areas = cache.root.selectAll(".mark")
.data(data.dataBySeries)
.data(data.dataBySeries)

@@ -128,3 +117,3 @@ areas.enter()

.attr("class", "mark area")
.attr('clip-path', `url(#mark-clip-${config.chartId})`)
.attr("clip-path", `url(#mark-clip-${config.chartId})`)
.classed("y2-area", (d) => d[keys.GROUP] > 0)

@@ -146,8 +135,8 @@ .attr("d", (d) => {

const seriesLine = d3.area()
.x((d) => scales.xScale(d.data[keys.KEY]))
.y0((d) => scales.yScale(d[0]))
.y1((d) => scales.yScale(d[1]))
.x((d) => scales.xScale(d.data[keys.KEY]))
.y0((d) => scales.yScale(d[0]))
.y1((d) => scales.yScale(d[1]))
const areas = cache.root.selectAll(".mark")
.data(data.stack(data.stackData))
.data(data.stack(data.stackData))

@@ -158,3 +147,3 @@ areas.enter()

.attr("class", "mark stacked-area")
.attr('clip-path', `url(#mark-clip-${config.chartId})`)
.attr("clip-path", `url(#mark-clip-${config.chartId})`)
.attr("d", seriesLine)

@@ -161,0 +150,0 @@ .style("stroke", "none")

import * as d3 from "./helpers/d3-service"
import {keys, LEFT_AXIS_GROUP_INDEX, RIGHT_AXIS_GROUP_INDEX, MAX_MARK_WIDTH} from "./helpers/constants"
import {getUnique, override, getSizes} from "./helpers/common"
import {
keys,
LEFT_AXIS_GROUP_INDEX,
RIGHT_AXIS_GROUP_INDEX
} from "./helpers/constants"
import {override} from "./helpers/common"

@@ -9,10 +13,2 @@ export default function Scale () {

let config = {
margin: {
top: 60,
right: 30,
bottom: 40,
left: 70
},
height: null,
width: null,
keyType: null,

@@ -24,8 +20,8 @@ chartType: null,

yDomain: "auto",
y2Domain: "auto"
}
y2Domain: "auto",
const cache = {
chartWidth: null,
chartHeight: null
chartHeight: null,
markPanelWidth: null,
markWidth: null
}

@@ -37,3 +33,4 @@

flatDataSorted: null,
groupKeys: null
groupKeys: null,
allKeyTotals: null
}

@@ -45,19 +42,5 @@

function hasBars (_chartType) {
return _chartType === "bar"
|| _chartType === "stackedBar"
|| _chartType === "groupedBar"
|| (Array.isArray(_chartType) && _chartType.filter(d => d === "bar").length > 0)
}
function getScaleSizes () {
const {chartWidth, chartHeight} = getSizes(config, cache)
cache.chartWidth = chartWidth
cache.chartHeight = chartHeight
}
function buildXScale (_allKeys) {
let xScale = null
let domain = null
const markW = Math.min(hasBars(config.chartType) ? cache.chartWidth / _allKeys.length : 0, MAX_MARK_WIDTH)

@@ -85,4 +68,5 @@ if (config.keyType === "time") {

const markWidthOffset = config.markWidth ? config.markWidth / 2 : 0
xScale.domain(domain)
.range([markW / 2, cache.chartWidth - markW / 2])
.range([markWidthOffset, config.markPanelWidth - markWidthOffset])

@@ -94,4 +78,4 @@ return xScale

const yScale = d3.scaleLinear()
.domain(_extent)
.rangeRound([cache.chartHeight, 0])
.domain(_extent)
.rangeRound([config.chartHeight, 0])

@@ -104,5 +88,5 @@ return yScale

const colorScale = d3.scaleOrdinal()
.range(config.colorSchema.map((d) => d.value))
.domain(config.colorSchema.map((d, i) => (typeof d.id === "undefined") ? ids[i] : d.id))
.unknown(config.defaultColor)
.range(config.colorSchema.map((d) => d.value))
.domain(config.colorSchema.map((d, i) => ((typeof d.id === "undefined") ? ids[i] : d.id)))
.unknown(config.defaultColor)

@@ -115,5 +99,5 @@ return colorScale

const styleScale = d3.scaleOrdinal()
.range(config.colorSchema.map((d) => d.style))
.domain(config.colorSchema.map((d, i) => d.id || ids[i]))
.unknown("solid")
.range(config.colorSchema.map((d) => d.style))
.domain(config.colorSchema.map((d, i) => d.id || ids[i]))
.unknown("solid")

@@ -126,5 +110,5 @@ return styleScale

const chartTypeScale = d3.scaleOrdinal()
.range(config.colorSchema.map((d) => d.type))
.domain(config.colorSchema.map((d, i) => d.id || ids[i]))
.unknown("line")
.range(config.colorSchema.map((d) => d.type))
.domain(config.colorSchema.map((d, i) => d.id || ids[i]))
.unknown("line")

@@ -153,7 +137,5 @@ return chartTypeScale

const allStackHeights = data.dataByKey.map((d) => d3.sum(d.series.map((dB) => dB.value)))
const allKeys = data.allKeyTotals.map(getKey)
const allKeys = data.flatDataSorted.map(getKey)
const allUniqueKeys = getUnique(allKeys, config.keyType)
const xScale = buildXScale(allUniqueKeys)
const xScale = buildXScale(allKeys)
const colorScale = buildColorScale()

@@ -192,2 +174,3 @@ const styleScale = buildStyleScale()

const groupKeys = Object.keys(groups) || []
const allKeys = data.allKeyTotals.map(getKey)

@@ -197,4 +180,3 @@ const hasLeftAxis = groupKeys.indexOf(LEFT_AXIS_GROUP_INDEX) > -1

const allUniqueKeys = data.dataByKey.map(d => d.key)
const xScale = buildXScale(allUniqueKeys)
const xScale = buildXScale(allKeys)

@@ -242,3 +224,2 @@ const colorScale = buildColorScale()

function getScales () {
getScaleSizes()
if (config.chartType === "stackedBar"

@@ -245,0 +226,0 @@ || config.chartType === "stackedArea") {

import * as d3 from "./helpers/d3-service"
import {keys, dashStylesTranslation} from "./helpers/constants"
import {cloneData, isNumeric, override} from "./helpers/common"
import {binTranslation, formatOddDateBin, multiFormat, formatTooltipNumber} from "./helpers/formatters"
import {isNumeric, override} from "./helpers/common"
import {binTranslation, formatOddDateBin, formatTooltipNumber} from "./helpers/formatters"
export default function Tooltip (_container, isLegend = false) {
export default function Tooltip (_container, _isLegend = false) {

@@ -20,3 +20,2 @@ let config = {

dateFormat: "%b %d, %Y",
numberFormat: null,
tooltipIsEnabled: true,

@@ -28,3 +27,8 @@ tooltipTitle: null,

colorSchema: ["skyblue"],
keyType: "time"
keyType: "time",
tooltipFormat: null,
markPanelWidth: null,
chartWidth: null,
chartHeight: null
}

@@ -40,4 +44,2 @@

root: null,
chartWidth: null,
chartHeight: null,
tooltipDivider: null,

@@ -54,9 +56,6 @@ tooltipBody: null,

function build () {
cache.chartWidth = config.width - config.margin.left - config.margin.right
cache.chartHeight = config.height - config.margin.top - config.margin.bottom
if (!cache.root) {
cache.root = cache.container.append("div")
.attr("class", isLegend ? "legend-group" : "tooltip-group")
.style("position", "absolute")
.attr("class", _isLegend ? "legend-group" : "tooltip-group")
.style("position", "absolute")

@@ -67,11 +66,11 @@ const panel = cache.root.append("div")

cache.tooltipTitleSection = panel.append("div")
.attr("class", "tooltip-title-section")
.attr("class", "tooltip-title-section")
cache.tooltipTitle = cache.tooltipTitleSection.append("div")
.attr("class", "tooltip-title")
.attr("class", "tooltip-title")
cache.tooltipBody = panel.append("div")
.attr("class", "tooltip-body")
.attr("class", "tooltip-body")
if (isLegend) {
if (_isLegend) {
cache.tooltipTitleSection.append("div")

@@ -81,3 +80,3 @@ .attr("class", "tooltip-collapse")

cache.tooltipTitleSection.on("click", function () {
cache.tooltipTitleSection.on("click", function click () {
const isCollapsed = this.classList.toggle("collapsed")

@@ -95,4 +94,4 @@ toggleCollapse(isCollapsed)

if (isLegend) {
cache.root.style("max-height", cache.chartHeight)
if (_isLegend) {
cache.root.style("max-height", config.chartHeight)
if (config.tooltipIsEnabled) {

@@ -113,5 +112,6 @@ show()

if (_mouseX > (cache.chartWidth / 2)) {
if (_mouseX > (config.chartWidth / 2)) {
avoidanceOffset = -tooltipSize.width - OFFSET
}
return [tooltipX + avoidanceOffset, tooltipY]

@@ -122,8 +122,8 @@ }

const xPosition = cache.xPosition === "auto"
? cache.chartWidth
: cache.xPosition
? config.chartWidth
: cache.xPosition
const yPosition = cache.yPosition === "auto"
? config.margin.top
: cache.yPosition
? config.margin.top
: cache.yPosition

@@ -137,5 +137,5 @@ cache.root

if (isLegend) {
if (_isLegend) {
// set max-height in case there are too many legend items
cache.root.style("max-height", `${cache.chartHeight}px`)
cache.root.style("max-height", `${config.chartHeight}px`)
}

@@ -146,5 +146,15 @@

function formatValue (_value, _format, _index) {
if (typeof _format === "string" && _format !== "auto") {
return d3.format(_format)(_value)
} else if (Array.isArray(_format)) {
return _format[_index] ? d3.format(_format[_index])(_value) : formatTooltipNumber(_value)
} else {
return formatTooltipNumber(_value)
}
}
function drawContent () {
const tooltipItems = cache.tooltipBody.selectAll(".tooltip-item")
.data(cache.content)
.data(cache.content)
const tooltipItemsUpdate = tooltipItems.enter().append("div")

@@ -156,3 +166,3 @@ .attr("class", "tooltip-item")

const tooltipItem = tooltipItemsUpdate.selectAll(".section")
.data((d) => {
.data((d, i) => {
const legendData = [

@@ -163,6 +173,6 @@ {

style: scales.styleScale(d[keys.ID])
},
}
]
if (isLegend) {
if (typeof d[keys.LABEL] !== "undefined") {
legendData.push({key: "tooltip-label", value: d[keys.LABEL]})

@@ -172,3 +182,4 @@ }

if (typeof d[keys.VALUE] !== "undefined") {
legendData.push({key: "value", value: d[keys.VALUE]})
const formattedValue = formatValue(d[keys.VALUE], config.tooltipFormat, i)
legendData.push({key: "value", value: formattedValue})
}

@@ -200,5 +211,3 @@ return legendData

.attr("stroke-width", 2.5)
.attr("stroke-dasharray", d => {
return dashStylesTranslation[d.style]
})
.attr("stroke-dasharray", dB => dashStylesTranslation[dB.style])
} else {

@@ -213,4 +222,2 @@ svg

}
} else if (d.key === "value") {
selection.html(formatTooltipNumber(d.value))
} else {

@@ -225,4 +232,4 @@ selection.html(d.value)

function toggleCollapse (isCollapsed) {
if (isCollapsed) {
function toggleCollapse (_isCollapsed) {
if (_isCollapsed) {
cache.tooltipTitle.html("Legend")

@@ -244,4 +251,4 @@ cache.tooltipBody.style("display", "none")

if (title instanceof Date) {
const { binningResolution } = config;
let specifier = binTranslation[binningResolution]
const {binningResolution} = config
const specifier = binTranslation[binningResolution]

@@ -265,5 +272,3 @@ if (specifier) {

function setupContent (_series) {
let series = _series
cache.content = sortSeries(series)
cache.content = sortSeries(_series)
return this

@@ -288,5 +293,5 @@ }

function setupTooltip (_dataPoint, _xPosition, _yPosition) {
function setupTooltip (_dataPoint, _xPosition, _yPosition, _panelXPosition) {
build()
const [tooltipX, tooltipY] = calculateTooltipPosition(_xPosition, _yPosition)
const [tooltipX, tooltipY] = calculateTooltipPosition(_panelXPosition, _yPosition)
setXPosition(tooltipX)

@@ -293,0 +298,0 @@ setYPosition(tooltipY)

@@ -1,27 +0,27 @@

var requireConfig = {
const requireConfig = {
baseUrl: '',
baseUrl: "",
paths: {
'es6': './node_modules/js-common/src/utils/es6',
'd3': 'node_modules/d3/d3'
},
shim: {
'd3': { exports: 'd3'},
},
map: {},
packages: []
};
paths: {
es6: "./node_modules/js-common/src/utils/es6",
d3: "node_modules/d3/d3"
},
shim: {
d3: {exports: "d3"}
},
map: {},
packages: []
}
if (typeof require === 'undefined') {
// any values set on require before it loads will be used as config
// ignore the "redefinition error" due to the line below
window.require = window.requireConfig;
} else if (typeof module === 'undefined') {
window.require.config(window.requireConfig);
if (typeof require === "undefined") {
// any values set on require before it loads will be used as config
// ignore the "redefinition error" due to the line below
window.require = window.requireConfig
} else if (typeof module === "undefined") {
window.require.config(window.requireConfig)
}
// allow for loading in nodejs
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = requireConfig;
if (typeof module !== "undefined" && module.exports) {
exports = module.exports = requireConfig
}
const webpack = require("webpack")
const path = require("path")
const LiveReloadPlugin = require("webpack-livereload-plugin")
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const chartModulesPath = path.resolve("./src/charts")
const fixturesPath = path.resolve("./test/fixtures")
const vendorsPath = path.resolve("./node_modules")
const bundleIndexPath = path.resolve("./src/bundle.js")
const scssIndexPath = path.resolve("./src/styles/mapd3.scss")
const defaultJSLoader = {
test: /\.js$/,
include: /src/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env"],
cacheDirectory: false
}
}
}
const config = function (env) {
const config = (env) => {
if (env.prod) {
return {
entry: {
mapd3: bundleIndexPath,
mapd3: bundleIndexPath
},

@@ -35,5 +18,5 @@

path: path.resolve(__dirname, "dist"),
filename: '[name].min.js',
filename: "[name].min.js",
library: "[name]",
libraryTarget: "umd",
libraryTarget: "umd"
},

@@ -51,3 +34,3 @@

use: {
loader: 'babel-loader',
loader: "babel-loader",
options: {

@@ -73,8 +56,6 @@ presets: ["@babel/preset-env"],

}
}
if (env.dev) {
} else if (env.dev) {
return {
entry: {
mapd3: bundleIndexPath,
mapd3: bundleIndexPath
},

@@ -86,5 +67,5 @@

path: path.resolve(__dirname, "dist"),
filename: '[name].js',
filename: "[name].js",
library: "[name]",
libraryTarget: "umd",
libraryTarget: "umd"
},

@@ -102,3 +83,3 @@

use: {
loader: 'babel-loader',
loader: "babel-loader",
options: {

@@ -120,6 +101,7 @@ presets: ["@babel/preset-env"],

allChunks: true
}),
// new BundleAnalyzerPlugin()
})
]
}
} else {
return
}

@@ -126,0 +108,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc